mirror of
https://github.com/apache/cordova-android.git
synced 2026-01-30 00:05:28 +08:00
Compare commits
1451 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d654de809a | ||
|
|
86f9b618ef | ||
|
|
ec1cc70c8b | ||
|
|
a64203f817 | ||
|
|
f4b315961b | ||
|
|
3bc755de7c | ||
|
|
c5ffdff49b | ||
|
|
2829ed77cc | ||
|
|
f3885692d9 | ||
|
|
d7fc37d365 | ||
|
|
c3bdebdb83 | ||
|
|
9514a3ed94 | ||
|
|
050dd088cf | ||
|
|
26f0401fda | ||
|
|
e4e04927b6 | ||
|
|
6b3ef11715 | ||
|
|
cf0fdf5ac0 | ||
|
|
33614d1273 | ||
|
|
1f735935b9 | ||
|
|
8c14e33bb6 | ||
|
|
7375154228 | ||
|
|
1427c13504 | ||
|
|
5538a231a8 | ||
|
|
9be110683b | ||
|
|
cfc36140bc | ||
|
|
72e947e5c7 | ||
|
|
7320ce8ea7 | ||
|
|
3e07f26bc4 | ||
|
|
5415440829 | ||
|
|
15e19489e3 | ||
|
|
c3610aa43c | ||
|
|
c1ac3aa483 | ||
|
|
291f111913 | ||
|
|
c2a6dcb6bd | ||
|
|
3439746645 | ||
|
|
b10fe465ab | ||
|
|
480af2644c | ||
|
|
ecd2e06883 | ||
|
|
7cfb33d0ef | ||
|
|
9224ab1592 | ||
|
|
931a996dab | ||
|
|
98fe46757f | ||
|
|
6b6e887c2f | ||
|
|
b92303b1c9 | ||
|
|
731a36d3a0 | ||
|
|
342bbaa3ae | ||
|
|
56a3ee5fe6 | ||
|
|
d80d532a2a | ||
|
|
3aca14d530 | ||
|
|
aa2d3962bf | ||
|
|
f7c717e393 | ||
|
|
268fea58ee | ||
|
|
ba140a8a84 | ||
|
|
27f1181d53 | ||
|
|
f953e6adb8 | ||
|
|
ffd14fe7d9 | ||
|
|
66fa12a091 | ||
|
|
132650df28 | ||
|
|
81a77949fc | ||
|
|
7fbb2b195f | ||
|
|
1feaa7fed7 | ||
|
|
ac284fd39c | ||
|
|
e78db000c6 | ||
|
|
032ea8a8d3 | ||
|
|
fc63f66e89 | ||
|
|
832e626573 | ||
|
|
ce5d9a2ee8 | ||
|
|
77c51d3ae7 | ||
|
|
53dae45430 | ||
|
|
16343ffe70 | ||
|
|
b37498d5f6 | ||
|
|
9f41906895 | ||
|
|
fbeb379f1b | ||
|
|
2dcd50c11b | ||
|
|
30681eb772 | ||
|
|
52e575e1e7 | ||
|
|
890e12c306 | ||
|
|
6cbf6b7875 | ||
|
|
c255a84941 | ||
|
|
ce7d6d69d9 | ||
|
|
d5538b7076 | ||
|
|
cdfa13b265 | ||
|
|
e31c911c30 | ||
|
|
a658ea1573 | ||
|
|
a986e72338 | ||
|
|
162d9b6c2e | ||
|
|
9e3ccf4b3e | ||
|
|
6b71c2f392 | ||
|
|
0d313a3964 | ||
|
|
ddac192c4a | ||
|
|
69a03c2e16 | ||
|
|
2b128b85f7 | ||
|
|
879da03438 | ||
|
|
3f83fdbfc1 | ||
|
|
949152532c | ||
|
|
7ce46ed60c | ||
|
|
cb442364ca | ||
|
|
ac34bf1e54 | ||
|
|
a5d300c6ff | ||
|
|
533677df8b | ||
|
|
25be42d385 | ||
|
|
00f6d30e08 | ||
|
|
090822eb41 | ||
|
|
d9900a725d | ||
|
|
5cb01f2ae9 | ||
|
|
4be92f285a | ||
|
|
f9b89e98c2 | ||
|
|
f221441877 | ||
|
|
f2e8c00f49 | ||
|
|
525ce0e0ad | ||
|
|
2f7ffa3636 | ||
|
|
9ae3d2c074 | ||
|
|
bf13fd48ce | ||
|
|
3b99760a42 | ||
|
|
0e78dc35d8 | ||
|
|
c8bbdb23de | ||
|
|
7ee8117186 | ||
|
|
8237c41143 | ||
|
|
d52ca93ba6 | ||
|
|
8354651059 | ||
|
|
81cc3c260f | ||
|
|
4dc32e194b | ||
|
|
5a82dd5110 | ||
|
|
f20708a5e7 | ||
|
|
91cf78f183 | ||
|
|
0cde8819cf | ||
|
|
07632b0eeb | ||
|
|
4a7f825cfe | ||
|
|
4bc2051f44 | ||
|
|
34dde53506 | ||
|
|
7a09182446 | ||
|
|
eb8cf56e8e | ||
|
|
12a27643db | ||
|
|
c6ccde0558 | ||
|
|
16e3ebd87b | ||
|
|
94c096dd5b | ||
|
|
2e3e4ec3b2 | ||
|
|
6e222c3938 | ||
|
|
3b3bd9b6c9 | ||
|
|
4e3331ba66 | ||
|
|
b6c5a5fc9a | ||
|
|
94943a9a84 | ||
|
|
71e72f215d | ||
|
|
58cdfd86d0 | ||
|
|
dfa66b9dd4 | ||
|
|
d56ea25816 | ||
|
|
c91b272648 | ||
|
|
ca8bb75b40 | ||
|
|
36eab713a1 | ||
|
|
7133576fe9 | ||
|
|
effffcba1d | ||
|
|
404ce8bc3e | ||
|
|
a91bd095b0 | ||
|
|
fd6a1e5ed0 | ||
|
|
7d6ac87033 | ||
|
|
8aa813b862 | ||
|
|
95aa5c9f1c | ||
|
|
4319447cb5 | ||
|
|
50ea162251 | ||
|
|
9c239804d3 | ||
|
|
320e31bb10 | ||
|
|
8b55a16986 | ||
|
|
41125ea1e2 | ||
|
|
73219bf2d2 | ||
|
|
d6eb723b7f | ||
|
|
993d73762c | ||
|
|
48b51c451a | ||
|
|
3d191d5884 | ||
|
|
955133f173 | ||
|
|
c2cafb4b45 | ||
|
|
67f474ef42 | ||
|
|
cd6c0e1de9 | ||
|
|
92be0033a8 | ||
|
|
b934c1be6a | ||
|
|
145b50a320 | ||
|
|
a33cdc9c7b | ||
|
|
62101e85ff | ||
|
|
0a3714e5e0 | ||
|
|
86a2830d75 | ||
|
|
9300e97d2b | ||
|
|
3792f75281 | ||
|
|
a14c794255 | ||
|
|
aef96e95e8 | ||
|
|
cc860804f6 | ||
|
|
d8a19b5565 | ||
|
|
1c5b5e2ce6 | ||
|
|
2f24e42dc1 | ||
|
|
0c12aa163e | ||
|
|
ec47274fbd | ||
|
|
04ccb06e3f | ||
|
|
d31ee20ba5 | ||
|
|
9b25d45b93 | ||
|
|
d51abdd73e | ||
|
|
9ea8b2237a | ||
|
|
e86c2e5970 | ||
|
|
caeb86843d | ||
|
|
0f15608175 | ||
|
|
705991e5b0 | ||
|
|
b636874bd9 | ||
|
|
965e4e9b19 | ||
|
|
af77977fda | ||
|
|
e74baf188f | ||
|
|
663a71255f | ||
|
|
79aa3e159d | ||
|
|
95118398dd | ||
|
|
4d18a8e55f | ||
|
|
3bab41f138 | ||
|
|
f577af0886 | ||
|
|
aab47bd453 | ||
|
|
445ddd89fb | ||
|
|
6f21a96238 | ||
|
|
c47bcb2f54 | ||
|
|
b0b628ffc2 | ||
|
|
4b4a2e9f9e | ||
|
|
58afd0b604 | ||
|
|
4352456129 | ||
|
|
bb141a70e8 | ||
|
|
ff260c03ca | ||
|
|
297f862ccc | ||
|
|
141bbfb051 | ||
|
|
663a919ed1 | ||
|
|
483babe3bc | ||
|
|
b407641049 | ||
|
|
32e07c22d0 | ||
|
|
d427c52aac | ||
|
|
eb623a84d5 | ||
|
|
07290277ba | ||
|
|
743541218f | ||
|
|
94de0a7ce2 | ||
|
|
36e9fb292b | ||
|
|
2661e010d9 | ||
|
|
7687becfee | ||
|
|
1641f09dc9 | ||
|
|
1505673393 | ||
|
|
629e05b7b1 | ||
|
|
e98f6ae570 | ||
|
|
0b5bf0c098 | ||
|
|
1deefa48ee | ||
|
|
50c4aef873 | ||
|
|
cf42d31214 | ||
|
|
00caa1c0a0 | ||
|
|
93c8ba920a | ||
|
|
8702c04d39 | ||
|
|
c349892c5b | ||
|
|
3d4b8ce99b | ||
|
|
64fd87134f | ||
|
|
82bba44538 | ||
|
|
e6adbb0e42 | ||
|
|
11fc6be328 | ||
|
|
0ec8f5d283 | ||
|
|
b872df0f31 | ||
|
|
0add4af208 | ||
|
|
298cd9e065 | ||
|
|
b715d20385 | ||
|
|
9a00ccdacc | ||
|
|
e8d48e1f43 | ||
|
|
a2f8c9c75b | ||
|
|
5fb83e7f52 | ||
|
|
dd6bf568d1 | ||
|
|
00ee164cef | ||
|
|
448071b02d | ||
|
|
4dad9d0e37 | ||
|
|
3a2117c5d3 | ||
|
|
26a3f6ddc3 | ||
|
|
7741312673 | ||
|
|
954a1723f1 | ||
|
|
87285d94f7 | ||
|
|
d260d0c182 | ||
|
|
137eb40fab | ||
|
|
af440460e1 | ||
|
|
a5c8472a37 | ||
|
|
dfae37421d | ||
|
|
438a8d8b75 | ||
|
|
ac2034561d | ||
|
|
c42cd4233d | ||
|
|
5b2a73e3eb | ||
|
|
6f163a6ba5 | ||
|
|
cc94cc7d01 | ||
|
|
94934ae2cf | ||
|
|
e361f88501 | ||
|
|
708c042b61 | ||
|
|
600599f49e | ||
|
|
1fe7bbbbc4 | ||
|
|
f83d7a7cd1 | ||
|
|
7094047b3d | ||
|
|
11d3607688 | ||
|
|
fcae58d355 | ||
|
|
ef9ace9e65 | ||
|
|
22e4039133 | ||
|
|
4971670e56 | ||
|
|
e16cab6b9c | ||
|
|
a643c3dba6 | ||
|
|
51abf5b0a6 | ||
|
|
1cee6e309b | ||
|
|
0777a660bf | ||
|
|
5e0479e414 | ||
|
|
942c77816d | ||
|
|
8e260d5c40 | ||
|
|
7951eee8a3 | ||
|
|
be2f7d7a8a | ||
|
|
59c8e8b46e | ||
|
|
98c8b28bf3 | ||
|
|
7bb5bc01b7 | ||
|
|
1482c07ae4 | ||
|
|
adba84ae6a | ||
|
|
146e296826 | ||
|
|
28c10dba09 | ||
|
|
e646a0840d | ||
|
|
74ea6bf00a | ||
|
|
d7ad784809 | ||
|
|
642bd10dcc | ||
|
|
7c566c36f4 | ||
|
|
dbbe038939 | ||
|
|
e3430a916c | ||
|
|
ea1f041e11 | ||
|
|
0fe6d9f367 | ||
|
|
46e7359372 | ||
|
|
41cace9a96 | ||
|
|
4638331cb4 | ||
|
|
e339a7583c | ||
|
|
0b7570c9ee | ||
|
|
a85acfcfc5 | ||
|
|
3d4ccbec23 | ||
|
|
2f66ec60db | ||
|
|
f1cfe2b07b | ||
|
|
6160ca6e30 | ||
|
|
b621c3e4c4 | ||
|
|
64d2ae9ad4 | ||
|
|
39fc45b8d8 | ||
|
|
fd954adc81 | ||
|
|
8b379cbf56 | ||
|
|
59c0b04602 | ||
|
|
11b3cf3bfd | ||
|
|
9254f5a8a5 | ||
|
|
e5b68f4a3c | ||
|
|
95babc01e3 | ||
|
|
4dd792a49f | ||
|
|
207c50e500 | ||
|
|
763e34e861 | ||
|
|
b895a0c335 | ||
|
|
c5767eb545 | ||
|
|
94fb79c17f | ||
|
|
6856b02aa7 | ||
|
|
04f812c136 | ||
|
|
8783cf03b2 | ||
|
|
4e1156e083 | ||
|
|
1d6e1d416b | ||
|
|
fd02e5a07e | ||
|
|
937056fcaf | ||
|
|
41ed18684d | ||
|
|
96d4a22215 | ||
|
|
6e4ef508e8 | ||
|
|
4437d7f3c4 | ||
|
|
001570e941 | ||
|
|
28c41294bb | ||
|
|
82898da507 | ||
|
|
eabcdbf129 | ||
|
|
5ab11edad2 | ||
|
|
b57317bdc2 | ||
|
|
1f49f29183 | ||
|
|
638fbfabdc | ||
|
|
16de12a3ba | ||
|
|
1316578ba3 | ||
|
|
1926c50f09 | ||
|
|
b858a4a5d7 | ||
|
|
ec9741443b | ||
|
|
fe7b2a36ec | ||
|
|
2d88a726b7 | ||
|
|
a51edd3579 | ||
|
|
b7ede8f9ba | ||
|
|
15f36cc19d | ||
|
|
95edd970bc | ||
|
|
2c6285d4b3 | ||
|
|
1d1cdb5ea4 | ||
|
|
34bdef9c45 | ||
|
|
cad673f8cd | ||
|
|
7c446b222d | ||
|
|
1bd0f8fcf4 | ||
|
|
dd3c261ba2 | ||
|
|
70cc711ec1 | ||
|
|
485f2ee923 | ||
|
|
129be6e476 | ||
|
|
c08b64efb3 | ||
|
|
f4a0f55b13 | ||
|
|
39d32bcb5b | ||
|
|
3351fdbc74 | ||
|
|
7be1f018aa | ||
|
|
437daa368a | ||
|
|
3df09eacf2 | ||
|
|
483dd3435a | ||
|
|
2b0aa03380 | ||
|
|
fc7261b199 | ||
|
|
3200c50b9f | ||
|
|
862a8eab8d | ||
|
|
1bfcc92677 | ||
|
|
80a09b8f36 | ||
|
|
5f7ce4b868 | ||
|
|
412d97fa0c | ||
|
|
57bed98cf1 | ||
|
|
b1d8788506 | ||
|
|
1bd4900981 | ||
|
|
e6812f18a0 | ||
|
|
f604988181 | ||
|
|
150cdfd3ac | ||
|
|
f42b34d6b4 | ||
|
|
166b35bc6c | ||
|
|
121b74fa0c | ||
|
|
5451320350 | ||
|
|
fe45b29ef6 | ||
|
|
4e1aa8aa59 | ||
|
|
fa366eb7a8 | ||
|
|
e086a706ba | ||
|
|
53b8da8198 | ||
|
|
c2c5f71018 | ||
|
|
2bdc849c2b | ||
|
|
7cbe8f5843 | ||
|
|
810df61049 | ||
|
|
5c38101a9e | ||
|
|
b4236b9783 | ||
|
|
980c4699b0 | ||
|
|
463c7b5027 | ||
|
|
7c7230dd35 | ||
|
|
b915aafb5b | ||
|
|
8202ab83fa | ||
|
|
2fe6d14e56 | ||
|
|
7ee285342f | ||
|
|
6fe18ae0ab | ||
|
|
5c4fa213d1 | ||
|
|
1895d8ac9e | ||
|
|
7f5f87ac72 | ||
|
|
0244341ac5 | ||
|
|
ae96d5678b | ||
|
|
a9ebf50b86 | ||
|
|
8d8cbf6e28 | ||
|
|
77e9092108 | ||
|
|
210d7c76e6 | ||
|
|
01ad3f447a | ||
|
|
546948cb8c | ||
|
|
37c20c3f67 | ||
|
|
22daea11e1 | ||
|
|
792aa78aec | ||
|
|
5cf95cfa01 | ||
|
|
fff956304f | ||
|
|
3ae28b3085 | ||
|
|
b5df9dd88e | ||
|
|
b6a01a203a | ||
|
|
990d91360d | ||
|
|
b5c3ac605a | ||
|
|
55865a4f1d | ||
|
|
ff27ad332b | ||
|
|
85bad87c1c | ||
|
|
f7014f14df | ||
|
|
99341bce29 | ||
|
|
bf6291020a | ||
|
|
79829f6209 | ||
|
|
a97487bcec | ||
|
|
892ffc8ce4 | ||
|
|
fbf7f1c3f9 | ||
|
|
3b7e0504e8 | ||
|
|
68bc57ae85 | ||
|
|
f42e5f66fd | ||
|
|
10d31ea0a3 | ||
|
|
e64ebdfaee | ||
|
|
7e15ff930d | ||
|
|
b83610a653 | ||
|
|
16e08384c0 | ||
|
|
9cb14838e8 | ||
|
|
6fe66ad79c | ||
|
|
f78b444ed1 | ||
|
|
9946d15f23 | ||
|
|
b032dcca16 | ||
|
|
01d6ae55a4 | ||
|
|
f1b377bf07 | ||
|
|
03c5208d47 | ||
|
|
3ace9348f6 | ||
|
|
3a14017729 | ||
|
|
e726c0d60b | ||
|
|
98b971b4de | ||
|
|
4ec3d6d064 | ||
|
|
c531d97ed2 | ||
|
|
8c9e416175 | ||
|
|
431f3337d9 | ||
|
|
63ab701685 | ||
|
|
c9b164b983 | ||
|
|
54d32ad910 | ||
|
|
c8140bad19 | ||
|
|
2e5b6bce55 | ||
|
|
5ee178789f | ||
|
|
0efd9fcac0 | ||
|
|
c0a39570c9 | ||
|
|
9ac4b570e6 | ||
|
|
6689827278 | ||
|
|
86a24ebd0f | ||
|
|
d2a7d18067 | ||
|
|
b679672c0e | ||
|
|
90f83db9c9 | ||
|
|
32d74f8623 | ||
|
|
53cc381c76 | ||
|
|
d845736948 | ||
|
|
add107583f | ||
|
|
dd837f7130 | ||
|
|
12ebadbb0f | ||
|
|
e30bc6b6e4 | ||
|
|
9288158226 | ||
|
|
3a55991480 | ||
|
|
9e44596db7 | ||
|
|
e86d811fc0 | ||
|
|
5cff144a22 | ||
|
|
a021adb7fd | ||
|
|
e2a090bbba | ||
|
|
a70c8536f9 | ||
|
|
9aaa152b9a | ||
|
|
a2b8ebf57e | ||
|
|
b3fe47985a | ||
|
|
e52d4fc003 | ||
|
|
3753e3f353 | ||
|
|
979d8e66f2 | ||
|
|
c5b37cc7e7 | ||
|
|
e3989bcc2b | ||
|
|
2f9c512b59 | ||
|
|
43172cf530 | ||
|
|
e518eacbde | ||
|
|
c3b8b279b0 | ||
|
|
0dd4951be7 | ||
|
|
12d06bd727 | ||
|
|
bc52345f05 | ||
|
|
c28a313374 | ||
|
|
c509c8e7e5 | ||
|
|
fb89cef256 | ||
|
|
9ac9fd4fe9 | ||
|
|
dfb89df4f1 | ||
|
|
0e572aea36 | ||
|
|
420cee4ee6 | ||
|
|
403297d967 | ||
|
|
abba254a38 | ||
|
|
048107e378 | ||
|
|
78efe2a960 | ||
|
|
8077091b34 | ||
|
|
683e32cffb | ||
|
|
1c9d76e637 | ||
|
|
98d9901693 | ||
|
|
ee58107caa | ||
|
|
75f358d01e | ||
|
|
01946dd4d6 | ||
|
|
c9e16b2c39 | ||
|
|
77eada7dbd | ||
|
|
f7c97cb1d0 | ||
|
|
f38a2ae14a | ||
|
|
7c22bc74bc | ||
|
|
dfd668d145 | ||
|
|
dbc6dd73f3 | ||
|
|
4765c6fcc5 | ||
|
|
78dd084303 | ||
|
|
cd9fb9b709 | ||
|
|
adcbd879c8 | ||
|
|
227733d195 | ||
|
|
13148728b3 | ||
|
|
8f91ebf194 | ||
|
|
230c635a54 | ||
|
|
e1f930282c | ||
|
|
cb07fe395c | ||
|
|
3917284f71 | ||
|
|
8bfd45c095 | ||
|
|
a001d8cfb7 | ||
|
|
867358ea81 | ||
|
|
62c3e46529 | ||
|
|
8a95ed8ee6 | ||
|
|
20caac1b6e | ||
|
|
48b8c69ba0 | ||
|
|
35d53a0684 | ||
|
|
dbeb252fee | ||
|
|
21614ea891 | ||
|
|
4b38ccef80 | ||
|
|
2d4d18fd75 | ||
|
|
27cd9dde38 | ||
|
|
373da39ac2 | ||
|
|
b7990b7df8 | ||
|
|
4b9047b7d8 | ||
|
|
d226818be3 | ||
|
|
1ee9da79f8 | ||
|
|
070eb6b947 | ||
|
|
cbb0bd5ee7 | ||
|
|
553a25cea7 | ||
|
|
53982272d6 | ||
|
|
a32cf2344f | ||
|
|
934cf32163 | ||
|
|
a17c7b9bbf | ||
|
|
a03df3fad0 | ||
|
|
86cd20dcc3 | ||
|
|
71402b658e | ||
|
|
5d8d8e77f8 | ||
|
|
4dee30ed84 | ||
|
|
025676d6e7 | ||
|
|
aad396ae38 | ||
|
|
c798d131bb | ||
|
|
bf3e024648 | ||
|
|
191f31baa7 | ||
|
|
d3b7903af8 | ||
|
|
99e7d1e161 | ||
|
|
b13166f5d9 | ||
|
|
80fe4458c6 | ||
|
|
791574c26e | ||
|
|
ac61ebf2d5 | ||
|
|
4599e9897d | ||
|
|
cb99ed0a01 | ||
|
|
4864d52966 | ||
|
|
b2d61679fb | ||
|
|
383b3dadd5 | ||
|
|
c65c259123 | ||
|
|
e7e2730929 | ||
|
|
bb9615eed0 | ||
|
|
18877bf80e | ||
|
|
778b784eb6 | ||
|
|
5ff900f7ec | ||
|
|
ba31424604 | ||
|
|
1782111d45 | ||
|
|
1fa63300aa | ||
|
|
b42c918973 | ||
|
|
f12262ea96 | ||
|
|
334cf45d6d | ||
|
|
b7bb72294a | ||
|
|
64ff204371 | ||
|
|
282367c6d5 | ||
|
|
36c33a5889 | ||
|
|
5ee7e81ff9 | ||
|
|
f4859444dd | ||
|
|
73c7994cd1 | ||
|
|
0c74090953 | ||
|
|
f60d54eae4 | ||
|
|
31bc015cdd | ||
|
|
b028ad3604 | ||
|
|
d2e4e35c37 | ||
|
|
1f37200bb6 | ||
|
|
77178daad3 | ||
|
|
1648f161d9 | ||
|
|
9fa6cea69b | ||
|
|
66b827e502 | ||
|
|
7755a902dd | ||
|
|
d25b73f47d | ||
|
|
ac2969c3f8 | ||
|
|
ee38b2ef03 | ||
|
|
0f70e04e6e | ||
|
|
9fc1e7272e | ||
|
|
0d4d0b8a37 | ||
|
|
fcd2c989a2 | ||
|
|
e0d0d6c455 | ||
|
|
ce1a961b99 | ||
|
|
c71a08a9d9 | ||
|
|
17bfcea65a | ||
|
|
5e8959bab1 | ||
|
|
9924dc0f92 | ||
|
|
7388c036d7 | ||
|
|
ad4512801f | ||
|
|
409b9af398 | ||
|
|
7cc8fd7e87 | ||
|
|
42c8105f13 | ||
|
|
9a71cc5b4e | ||
|
|
c543b7469d | ||
|
|
7caac3265a | ||
|
|
5d68d5a246 | ||
|
|
7187f87eae | ||
|
|
fb81f3e77e | ||
|
|
0ae49ed098 | ||
|
|
b8e5aaf754 | ||
|
|
aa4820c3b7 | ||
|
|
5d79d6e134 | ||
|
|
fb1455a17b | ||
|
|
c668eeba0f | ||
|
|
62421ee49d | ||
|
|
e791f29ce1 | ||
|
|
06947cc453 | ||
|
|
8c97474524 | ||
|
|
77a8568b28 | ||
|
|
e2dadbd7fe | ||
|
|
17b668a115 | ||
|
|
a30c2b6a75 | ||
|
|
2660eebec2 | ||
|
|
f415664b6d | ||
|
|
5092b29312 | ||
|
|
d5be901bc2 | ||
|
|
5462eddfdb | ||
|
|
fef51f12c6 | ||
|
|
fdb3679cf5 | ||
|
|
11beb37c50 | ||
|
|
5cd17730b1 | ||
|
|
cb192056f8 | ||
|
|
892f96e305 | ||
|
|
13ef58a5bb | ||
|
|
2bf6509e1d | ||
|
|
a45d5a98dd | ||
|
|
a31714f8a4 | ||
|
|
23d2a806f0 | ||
|
|
c20b2330ab | ||
|
|
8613551aec | ||
|
|
2ab01dadc0 | ||
|
|
790636c8cd | ||
|
|
23938830f7 | ||
|
|
674b87057a | ||
|
|
83d9248ec8 | ||
|
|
f9d27e4a67 | ||
|
|
2683803ef3 | ||
|
|
dd86d7a5ed | ||
|
|
1246a81d39 | ||
|
|
8ab7278db2 | ||
|
|
db099e7722 | ||
|
|
fcc01bc37e | ||
|
|
a18dacf5f2 | ||
|
|
77f9cae50b | ||
|
|
3610bbf21b | ||
|
|
d5e3be9a55 | ||
|
|
80b369d6d5 | ||
|
|
d29eb84010 | ||
|
|
381ce535bf | ||
|
|
2e20bb0639 | ||
|
|
56cd24797e | ||
|
|
431ca99c23 | ||
|
|
6ced2ff293 | ||
|
|
31055bb303 | ||
|
|
24a53e39dd | ||
|
|
2ab113b695 | ||
|
|
9a0481a750 | ||
|
|
09035eb4c4 | ||
|
|
1adf268e71 | ||
|
|
23f57ad5a7 | ||
|
|
d9b15cf69e | ||
|
|
dbfe12a993 | ||
|
|
2b32dfd99d | ||
|
|
679de40780 | ||
|
|
66f15fdd37 | ||
|
|
038f0e45b1 | ||
|
|
033bfcc804 | ||
|
|
fa87c08a29 | ||
|
|
dfb799739a | ||
|
|
1193f7ed22 | ||
|
|
7530c21a9f | ||
|
|
a120614617 | ||
|
|
0311f0db38 | ||
|
|
547b683e61 | ||
|
|
ff1d943a69 | ||
|
|
15a5c89e86 | ||
|
|
03b974ee3f | ||
|
|
f145605c63 | ||
|
|
29230d0316 | ||
|
|
57fc49ddc2 | ||
|
|
5ac6853fed | ||
|
|
b870214cca | ||
|
|
55074b925f | ||
|
|
958424ce59 | ||
|
|
d04fc289ac | ||
|
|
e14edf134d | ||
|
|
dbb127447f | ||
|
|
dc94fc39ec | ||
|
|
6db9a7cb12 | ||
|
|
1f39386616 | ||
|
|
25aef945d1 | ||
|
|
c9aa43afe0 | ||
|
|
913e177f6f | ||
|
|
ae431aec12 | ||
|
|
8ac15048cd | ||
|
|
a1cfe87f1e | ||
|
|
c130396d4e | ||
|
|
bc2e7cf317 | ||
|
|
7ace1d652d | ||
|
|
26effd1def | ||
|
|
5f6824e5dd | ||
|
|
4589bdd31f | ||
|
|
72e0b49e0b | ||
|
|
3caa45d860 | ||
|
|
7c069f14f8 | ||
|
|
552885dbd3 | ||
|
|
6efeb1471c | ||
|
|
01f062d2ba | ||
|
|
2a42c463d2 | ||
|
|
182843edf6 | ||
|
|
9a9d36e9d9 | ||
|
|
7d5249eea6 | ||
|
|
f7910c41c3 | ||
|
|
3973f4f952 | ||
|
|
8a19769a47 | ||
|
|
c0ee593c10 | ||
|
|
c806451b8a | ||
|
|
00e5ff1964 | ||
|
|
432aec62a9 | ||
|
|
c8ec7e5191 | ||
|
|
a0d2b96de6 | ||
|
|
2c202b82d7 | ||
|
|
a42dc08756 | ||
|
|
48f58110fe | ||
|
|
7b3724972b | ||
|
|
9ca2a16218 | ||
|
|
f1e8400abf | ||
|
|
11e0ffa90a | ||
|
|
2ee4326a4d | ||
|
|
226e72ac18 | ||
|
|
65c78b8f3f | ||
|
|
6137c7ca06 | ||
|
|
5bebf11b37 | ||
|
|
68161d2714 | ||
|
|
a6473cb826 | ||
|
|
0084c6f96a | ||
|
|
a87825dbee | ||
|
|
3566154cd0 | ||
|
|
92d69e320f | ||
|
|
08a190ef5b | ||
|
|
98339ee5d8 | ||
|
|
fa387fd758 | ||
|
|
54979f2fc4 | ||
|
|
538e90f23a | ||
|
|
d9107bcac6 | ||
|
|
3f3a0b9140 | ||
|
|
e1347e434e | ||
|
|
7657faa9c3 | ||
|
|
28ef765913 | ||
|
|
d2f59391a2 | ||
|
|
df90bdb350 | ||
|
|
c416c77d7a | ||
|
|
ce05a720d1 | ||
|
|
6c19a440f5 | ||
|
|
f4612fdb5d | ||
|
|
04b9a0b09e | ||
|
|
f93c438067 | ||
|
|
e1d608443a | ||
|
|
9233c3a898 | ||
|
|
dfa514334b | ||
|
|
5810a96e62 | ||
|
|
70473a80af | ||
|
|
525fd30cb2 | ||
|
|
5212cd4dcd | ||
|
|
e95bde62a2 | ||
|
|
4fe73cf6ad | ||
|
|
78b2835da4 | ||
|
|
f9a49efae9 | ||
|
|
b9ddc9e678 | ||
|
|
dc459c84a3 | ||
|
|
1d26239809 | ||
|
|
5ca233779d | ||
|
|
e51b4897a3 | ||
|
|
81f283e56f | ||
|
|
ccdd2fd2ca | ||
|
|
69f11a29e1 | ||
|
|
cf494f3238 | ||
|
|
d5895c635a | ||
|
|
2ac9873613 | ||
|
|
eb59e76cde | ||
|
|
d9db845b43 | ||
|
|
e55327b064 | ||
|
|
bdd5a4e053 | ||
|
|
ac2e2c9a42 | ||
|
|
76f9d49e24 | ||
|
|
6ec8ab95fc | ||
|
|
9c98625610 | ||
|
|
f270cde47d | ||
|
|
9de7efd072 | ||
|
|
7b81d317a0 | ||
|
|
876f975aa2 | ||
|
|
3c5815ac0f | ||
|
|
678ae2d684 | ||
|
|
e4f8f44fb0 | ||
|
|
49566d29f8 | ||
|
|
7f4ee7b20a | ||
|
|
32526a8c16 | ||
|
|
71a7f72ab9 | ||
|
|
4d0824f4a4 | ||
|
|
d56dd40d06 | ||
|
|
6aafd6dc3a | ||
|
|
011b512f28 | ||
|
|
aa2d17e489 | ||
|
|
0eee2293dc | ||
|
|
a2f35d2bda | ||
|
|
58f58d9ee8 | ||
|
|
412bb349ac | ||
|
|
652f15f893 | ||
|
|
8512ebb923 | ||
|
|
f0ac173ec8 | ||
|
|
bef0d47924 | ||
|
|
cba0d59021 | ||
|
|
7d3afcab94 | ||
|
|
5f1cda07e7 | ||
|
|
e11beade4b | ||
|
|
6a1e089b73 | ||
|
|
0aa98ac2da | ||
|
|
f9ef38cc7a | ||
|
|
a3a215a1ba | ||
|
|
d3ee322d7c | ||
|
|
7ec20e7752 | ||
|
|
08dfb13dbf | ||
|
|
6a5cddd907 | ||
|
|
dc5078306d | ||
|
|
1bc032853c | ||
|
|
e562e4e7b9 | ||
|
|
0ffffa9029 | ||
|
|
0f2303e8d5 | ||
|
|
31f7f8149e | ||
|
|
fe1f57c23f | ||
|
|
29a0b010da | ||
|
|
621e1163f8 | ||
|
|
17d64cfcbe | ||
|
|
7379d2135d | ||
|
|
c55fd06b99 | ||
|
|
d81727a08c | ||
|
|
b582e1592a | ||
|
|
dd8533a320 | ||
|
|
d72a8cbf89 | ||
|
|
fe0876ded6 | ||
|
|
fa15763c5d | ||
|
|
205215d409 | ||
|
|
076bfcde87 | ||
|
|
10510484b5 | ||
|
|
e1dea5b4d3 | ||
|
|
891f8d00cf | ||
|
|
0d409f0fe3 | ||
|
|
4e0c8982c9 | ||
|
|
a741c66c97 | ||
|
|
3e6a7cbdf5 | ||
|
|
5d34aa0afe | ||
|
|
979ae94698 | ||
|
|
8d7b85b26a | ||
|
|
686977a986 | ||
|
|
9c6c782146 | ||
|
|
ca9539b5b6 | ||
|
|
ff25be8839 | ||
|
|
d1ab1b59be | ||
|
|
05bc1865a6 | ||
|
|
6e6e0275ad | ||
|
|
ec3c5b2ca2 | ||
|
|
5289d569b0 | ||
|
|
6f873ff6b5 | ||
|
|
467cbe972c | ||
|
|
bfd1bfe9f0 | ||
|
|
3404a6c699 | ||
|
|
17a4b5155e | ||
|
|
d406e2ed22 | ||
|
|
0bfc9935b2 | ||
|
|
64c6cbe303 | ||
|
|
2245db3e80 | ||
|
|
6f19a50c98 | ||
|
|
c7ce9598a8 | ||
|
|
afcdccf783 | ||
|
|
1bf12842ca | ||
|
|
da8fbee256 | ||
|
|
4021f26e76 | ||
|
|
8eab8438cf | ||
|
|
1b4096b01d | ||
|
|
54caa6e438 | ||
|
|
486eb149f2 | ||
|
|
faa034a205 | ||
|
|
2cd3ebc7a8 | ||
|
|
7e3af6c235 | ||
|
|
dd4de16d1d | ||
|
|
ba8577fa5f | ||
|
|
6192319f8c | ||
|
|
fed368d553 | ||
|
|
20c885418e | ||
|
|
9318ee30bd | ||
|
|
8b6c9574df | ||
|
|
313148136a | ||
|
|
6e1fdc77ae | ||
|
|
2a9582ebb1 | ||
|
|
dd1cd46719 | ||
|
|
9961d9e54d | ||
|
|
7eb12110d1 | ||
|
|
3d62744601 | ||
|
|
17af417235 | ||
|
|
df9d314361 | ||
|
|
610e0c984a | ||
|
|
3688fca126 | ||
|
|
9bc89c784f | ||
|
|
79682f5d52 | ||
|
|
c206ac0335 | ||
|
|
34840175f3 | ||
|
|
6312457425 | ||
|
|
f71e664952 | ||
|
|
80d559f17e | ||
|
|
772aedc263 | ||
|
|
45d7c124c8 | ||
|
|
73abb20b3d | ||
|
|
0baf104a75 | ||
|
|
302d51cdfd | ||
|
|
d3cbfd5467 | ||
|
|
9e3e7e1820 | ||
|
|
18893bf6cd | ||
|
|
f53161d6f5 | ||
|
|
4c9a571106 | ||
|
|
365edcad16 | ||
|
|
ae9047a708 | ||
|
|
9c0e58df8d | ||
|
|
ee34f11c29 | ||
|
|
6ca6d88bff | ||
|
|
65a397fb63 | ||
|
|
0a669077fb | ||
|
|
451688a12e | ||
|
|
d181d89dd2 | ||
|
|
ac14b0d73b | ||
|
|
0f42c65792 | ||
|
|
37b3e980dc | ||
|
|
eb49e011e2 | ||
|
|
e0a73f72ee | ||
|
|
e217ab28c5 | ||
|
|
ca583865ea | ||
|
|
5e7efde311 | ||
|
|
2c7c13420b | ||
|
|
ac4fc3e54e | ||
|
|
46db36a05e | ||
|
|
3d073be990 | ||
|
|
1bc49fe450 | ||
|
|
1f7fe9abcc | ||
|
|
5217abf57a | ||
|
|
2ecbde891a | ||
|
|
bf7fc66646 | ||
|
|
5a94b38e2f | ||
|
|
1bc55f5937 | ||
|
|
04c9542f94 | ||
|
|
17e739f68a | ||
|
|
4f5515fde3 | ||
|
|
ae3ba129ea | ||
|
|
6b92a0fff7 | ||
|
|
d859bb8e67 | ||
|
|
f12bbf71ed | ||
|
|
b723beb545 | ||
|
|
47daaaf14f | ||
|
|
9ba5bae34d | ||
|
|
dbfa2d7994 | ||
|
|
8134f86d1f | ||
|
|
5c60b09bf4 | ||
|
|
20a19d67d0 | ||
|
|
311a2f6023 | ||
|
|
59a3cf93e6 | ||
|
|
a42f095cef | ||
|
|
a29340523f | ||
|
|
5ad7a7c014 | ||
|
|
c6fa7e4aad | ||
|
|
d4b248fbe3 | ||
|
|
48881d081a | ||
|
|
331024414e | ||
|
|
9d0c5349bb | ||
|
|
dc40d8afac | ||
|
|
005877b4b8 | ||
|
|
774d21747a | ||
|
|
12e5b39c05 | ||
|
|
4d5e452ece | ||
|
|
1ba3ecbef3 | ||
|
|
db6695cb02 | ||
|
|
b3f5e039f2 | ||
|
|
c3e17fb185 | ||
|
|
f7ae7fe43a | ||
|
|
e07822350e | ||
|
|
07439ff99c | ||
|
|
f111c245c1 | ||
|
|
c3502da4a0 | ||
|
|
4012108d48 | ||
|
|
4a0605e09b | ||
|
|
250380d73e | ||
|
|
b30f5d782d | ||
|
|
b00cd9b557 | ||
|
|
e11f8f646b | ||
|
|
92b1de8cf8 | ||
|
|
bbafe53a2b | ||
|
|
e239fd970f | ||
|
|
7fa4515c28 | ||
|
|
b40eb0a454 | ||
|
|
5e3e9ddb8e | ||
|
|
a9a5284a67 | ||
|
|
afe504dbbf | ||
|
|
0c484ddcf7 | ||
|
|
8d0e80620a | ||
|
|
1d28506b09 | ||
|
|
1b33dbe2ae | ||
|
|
80654c059d | ||
|
|
999c548e6e | ||
|
|
e42913ae8a | ||
|
|
ee07cbecba | ||
|
|
fffaa9bced | ||
|
|
6195b2c99d | ||
|
|
06aafc96c9 | ||
|
|
2dc0727e36 | ||
|
|
a219feaa60 | ||
|
|
f3a09da340 | ||
|
|
946e345a3f | ||
|
|
6cb8d11b22 | ||
|
|
fdcf9c5327 | ||
|
|
45c714cbb5 | ||
|
|
7352a309a0 | ||
|
|
b297fe6f59 | ||
|
|
e575212c49 | ||
|
|
c52dc10c9e | ||
|
|
d35c913249 | ||
|
|
9bac59b952 | ||
|
|
5016253922 | ||
|
|
03893071fc | ||
|
|
d3dc94c04b | ||
|
|
af0feabb6a | ||
|
|
81ab0a414f | ||
|
|
ecd6ca0172 | ||
|
|
db7ee192f7 | ||
|
|
2ec0b601fa | ||
|
|
79feb6d5d2 | ||
|
|
8013b760e3 | ||
|
|
a29b8e5b36 | ||
|
|
9ef487a7a5 | ||
|
|
563fa46ba4 | ||
|
|
7865c06863 | ||
|
|
3d53b9244d | ||
|
|
f2afa4dd50 | ||
|
|
893ecec55e | ||
|
|
401584dbd8 | ||
|
|
b234b0bded | ||
|
|
b9b2c6a013 | ||
|
|
1d2efa0d25 | ||
|
|
93ec092eaf | ||
|
|
29ae492983 | ||
|
|
b9f6a59a20 | ||
|
|
d74551216f | ||
|
|
d4302ae51b | ||
|
|
9d5fb0b201 | ||
|
|
e0a5fe4002 | ||
|
|
f9d9a0a4bd | ||
|
|
78f0c7b119 | ||
|
|
c6d8343de2 | ||
|
|
0ccd11e587 | ||
|
|
b486711d68 | ||
|
|
2eb4c5e960 | ||
|
|
85aa740c98 | ||
|
|
6415848383 | ||
|
|
beb9460538 | ||
|
|
c030770be7 | ||
|
|
0180342dff | ||
|
|
b97748d3dc | ||
|
|
9d4977db00 | ||
|
|
f095284faa | ||
|
|
401c2f42f9 | ||
|
|
eb0348d47c | ||
|
|
1f46240ba9 | ||
|
|
14870726e0 | ||
|
|
c7d6a2eecb | ||
|
|
ce61eb2174 | ||
|
|
f3df21ef0a | ||
|
|
5eb554e008 | ||
|
|
e5e7c3fad3 | ||
|
|
2a8b9ab75e | ||
|
|
c8f0ffb42f | ||
|
|
b3e68b96cf | ||
|
|
ae7a550a09 | ||
|
|
e069bbb800 | ||
|
|
17ff6be6a9 | ||
|
|
d42489c67a | ||
|
|
3ea72e5d21 | ||
|
|
762854ad7a | ||
|
|
10465066ee | ||
|
|
0cf9f51816 | ||
|
|
3d5e2340ca | ||
|
|
e2047afa42 | ||
|
|
231b39d2dc | ||
|
|
dddce30368 | ||
|
|
e0e4ba2bd7 | ||
|
|
e0eadb6b76 | ||
|
|
483e5dfbea | ||
|
|
8aa9d8213d | ||
|
|
a74f71c935 | ||
|
|
87b81e53f0 | ||
|
|
a2816e31c3 | ||
|
|
f78af9f27b | ||
|
|
98138a0a60 | ||
|
|
e639b6303e | ||
|
|
99fb3ebe00 | ||
|
|
5829840409 | ||
|
|
4699ab5500 | ||
|
|
69fc7f39b7 | ||
|
|
510a962a52 | ||
|
|
570fc3cfb2 | ||
|
|
5d211f2fa6 | ||
|
|
dcb127c14d | ||
|
|
fba87de064 | ||
|
|
576f8cba44 | ||
|
|
b9f9429542 | ||
|
|
bf0df9f3c3 | ||
|
|
1d458f2782 | ||
|
|
5ca4b4a884 | ||
|
|
5935052ead | ||
|
|
f3f2ad9144 | ||
|
|
9d1edc4554 | ||
|
|
5143b8a492 | ||
|
|
7c67f40fc4 | ||
|
|
167b600135 | ||
|
|
6c465e25d3 | ||
|
|
c183d06ed1 | ||
|
|
574731b853 | ||
|
|
94568a4ec8 | ||
|
|
b22c0e5b6d | ||
|
|
ab3347d25d | ||
|
|
66872de8e5 | ||
|
|
f6d4402fdc | ||
|
|
9f66ccb5f3 | ||
|
|
b339330592 | ||
|
|
56acd2953b | ||
|
|
6f8e13297e | ||
|
|
e9a9144098 | ||
|
|
d1905dbee8 | ||
|
|
adc88f01b7 | ||
|
|
ccf0c5db67 | ||
|
|
507554b8e8 | ||
|
|
4795133daf | ||
|
|
c1c9075962 | ||
|
|
a691e9f744 | ||
|
|
8969eed506 | ||
|
|
be83095edf | ||
|
|
5c7783305a | ||
|
|
f394f7457b | ||
|
|
d60806bfa6 | ||
|
|
32febcb892 | ||
|
|
6c594b6f5f | ||
|
|
67d46432ed | ||
|
|
adf4166caa | ||
|
|
40b9810a63 | ||
|
|
d9e7984279 | ||
|
|
e5b9900d3b | ||
|
|
fc3f1431b2 | ||
|
|
c8bf2f4cb1 | ||
|
|
d16555ec4b | ||
|
|
3c9415b1c2 | ||
|
|
aa45670d87 | ||
|
|
e6d801a594 | ||
|
|
0aec2be4dd | ||
|
|
c86b618aaa | ||
|
|
451afabfbb | ||
|
|
f60049f713 | ||
|
|
ee0cd679d3 | ||
|
|
07ed6daeda | ||
|
|
b5800ced61 | ||
|
|
6d879f19f8 | ||
|
|
dde79c14f5 | ||
|
|
b08f245504 | ||
|
|
cbd0b7a94b | ||
|
|
f060d09272 | ||
|
|
6edad7e7de | ||
|
|
f0f596c892 | ||
|
|
dbe65f1d35 | ||
|
|
cdaf620f92 | ||
|
|
09b753d09e | ||
|
|
838fa5635f | ||
|
|
0a4d218010 | ||
|
|
24944cff22 | ||
|
|
34820f4344 | ||
|
|
56047e5fc8 | ||
|
|
80ee6c1a91 | ||
|
|
5649fbac20 | ||
|
|
586d3ecd60 | ||
|
|
9ebdca66d9 | ||
|
|
41ddcf2218 | ||
|
|
cbe1216bc2 | ||
|
|
234ee63859 | ||
|
|
2402541974 | ||
|
|
8b1fb30f59 | ||
|
|
bf6864bce0 | ||
|
|
34ebdaddc1 | ||
|
|
9f42772b7e | ||
|
|
47211f6cb3 | ||
|
|
95b48705fe | ||
|
|
6c1a2e1230 | ||
|
|
55b1e40885 | ||
|
|
d87f404d6e | ||
|
|
48c6ec87cf | ||
|
|
71972dcaab | ||
|
|
3fd158ad6e | ||
|
|
447af8da6a | ||
|
|
e8b80e8752 | ||
|
|
30a1164f6a | ||
|
|
80a5ea137b | ||
|
|
db8a8f3556 | ||
|
|
81195db87d | ||
|
|
23ec117f57 | ||
|
|
d3e24b0c48 | ||
|
|
58c3f9a187 | ||
|
|
03aaab6f8b | ||
|
|
a489ae0fb6 | ||
|
|
c8af154205 | ||
|
|
6d1e0356ac | ||
|
|
adfdb16dc5 | ||
|
|
825b9eafc2 | ||
|
|
0ad9ff0d87 | ||
|
|
24e5c24dd4 | ||
|
|
8451133d00 | ||
|
|
be165c677f | ||
|
|
55ee289ed6 | ||
|
|
22e5ccfed4 | ||
|
|
508cafad1d | ||
|
|
ca979a99e8 | ||
|
|
4ecbaa79cf | ||
|
|
c12f01261a | ||
|
|
d6d2749411 | ||
|
|
509588b130 | ||
|
|
c21e8c9c87 | ||
|
|
e7411e8260 | ||
|
|
59f9b6f359 | ||
|
|
5f93a26eea | ||
|
|
d79403e352 | ||
|
|
ed94d0dd30 | ||
|
|
43df9f6b9c | ||
|
|
fd12f57f10 | ||
|
|
ca1a322c76 | ||
|
|
7d0cc5837d | ||
|
|
5edb3acad5 | ||
|
|
e35a8de4bb | ||
|
|
b77f1cbff8 | ||
|
|
8b93e87e3e | ||
|
|
cb61e90148 | ||
|
|
ccd4365922 | ||
|
|
d7b79f5042 | ||
|
|
95fa0f4461 | ||
|
|
c37b2d236b | ||
|
|
2d77bcf1a4 | ||
|
|
0c9295f8bc | ||
|
|
3b27d89c4a | ||
|
|
8356ac67e8 | ||
|
|
fae0c3dcfd | ||
|
|
6b24f2d547 | ||
|
|
2d5dcf24da | ||
|
|
15ddef26f4 | ||
|
|
531efe1e30 | ||
|
|
df89d33fab | ||
|
|
cb98bbce1f | ||
|
|
24adc6d00c | ||
|
|
71e47aa772 | ||
|
|
dffd2deb53 | ||
|
|
8ff48b371e | ||
|
|
6de66b87cb | ||
|
|
5dacb8d2d5 | ||
|
|
0850229c9f | ||
|
|
1f45503e2f | ||
|
|
c8a521c182 | ||
|
|
5c48ccd92a | ||
|
|
f74d8aaf2b | ||
|
|
7eb3e5d139 | ||
|
|
ffa1eb1ee9 | ||
|
|
24dfbfd84f | ||
|
|
ad6d71fef3 | ||
|
|
c178031f06 | ||
|
|
20db698475 | ||
|
|
dd624ccd9c | ||
|
|
ac504768b2 | ||
|
|
2d7b7160c3 | ||
|
|
2fbb9c285d | ||
|
|
47d99e5193 | ||
|
|
0437d6cc1a | ||
|
|
c6851cf7c5 | ||
|
|
45680a562e | ||
|
|
3b9d46fadc | ||
|
|
f840f3aceb | ||
|
|
afa1ecf3c5 | ||
|
|
295b9f4f5b | ||
|
|
79048a5a84 | ||
|
|
d683bd3744 | ||
|
|
9f5f4973ae | ||
|
|
441785b51d | ||
|
|
0d32115c3f | ||
|
|
e660768e4b | ||
|
|
01abb32025 | ||
|
|
d44d9ddca6 | ||
|
|
13f92b2b76 | ||
|
|
e6aa64760e | ||
|
|
3829df665f | ||
|
|
c8fafa6bbd | ||
|
|
aede2235d0 | ||
|
|
c56c73f250 | ||
|
|
fc50a0d954 | ||
|
|
c6349668dd | ||
|
|
dd0b6b1e30 | ||
|
|
eb66eb02cb | ||
|
|
5b324c85b0 | ||
|
|
fc9cff7d26 | ||
|
|
6a628f7f2d | ||
|
|
f3e70c79eb | ||
|
|
08a32272d3 | ||
|
|
a705b72740 | ||
|
|
de6652dd9d | ||
|
|
b2f49b15ba | ||
|
|
c0dcbecbea | ||
|
|
b323f329cc | ||
|
|
2625a57fdd | ||
|
|
2142d00bb9 | ||
|
|
4ce585be02 | ||
|
|
c2631ee0f7 | ||
|
|
8ab1733374 | ||
|
|
bafa438ce3 | ||
|
|
18cc90b3d8 | ||
|
|
0fd1e3c57b | ||
|
|
1ee484f70d | ||
|
|
724ea49f0b | ||
|
|
6fc2a3b84e | ||
|
|
b84d64912b | ||
|
|
e28f09e95b | ||
|
|
21f6d9c527 | ||
|
|
8e0c3c1fa1 | ||
|
|
9e10160366 | ||
|
|
d38dd4c131 | ||
|
|
84aaf02b0f | ||
|
|
269b90ad6f | ||
|
|
c11c4bea94 | ||
|
|
7de660808c | ||
|
|
1fcaf2435f | ||
|
|
87fbb5c92f | ||
|
|
3636a18bba | ||
|
|
ea8d6b17ec | ||
|
|
27e511b785 | ||
|
|
9dfa503bad | ||
|
|
a087116915 | ||
|
|
216f6a9b32 | ||
|
|
e32503fad7 | ||
|
|
c33f768570 | ||
|
|
20c7b512f3 | ||
|
|
5abe8dd506 | ||
|
|
e4119f3fd2 | ||
|
|
480e5ca4d1 | ||
|
|
f4cf2cecb5 | ||
|
|
5ab5cf03b5 | ||
|
|
13ba1e4900 | ||
|
|
17c919edd9 | ||
|
|
99b3693f40 | ||
|
|
483bb53d9c | ||
|
|
80ec23887e | ||
|
|
ea81b97bfc | ||
|
|
be39bf8d91 | ||
|
|
ca66c4bf59 | ||
|
|
4192489836 | ||
|
|
2e4667da88 | ||
|
|
9718aa5d4a | ||
|
|
d5dd43289b | ||
|
|
1bd7a662df | ||
|
|
327589a1d7 | ||
|
|
531b8f641f | ||
|
|
8ac274cdca | ||
|
|
fea79bc971 | ||
|
|
f2526bbc78 | ||
|
|
1794f2e047 | ||
|
|
b99e9abb5f | ||
|
|
e77f9bb8fc | ||
|
|
628f88cf79 | ||
|
|
87238f26f6 | ||
|
|
95013e87dd | ||
|
|
d604e8b9b4 | ||
|
|
9a2eb04054 | ||
|
|
f34da8a96f | ||
|
|
527f17d19e | ||
|
|
2818e05e71 | ||
|
|
49b50ce66c | ||
|
|
b793fbfc28 | ||
|
|
59ff94fefb | ||
|
|
f3c29840a7 | ||
|
|
6dabe4c010 | ||
|
|
8ecfcb12c7 | ||
|
|
ae8bc77ee7 | ||
|
|
e25490751c |
34
.gitignore
vendored
34
.gitignore
vendored
@@ -2,17 +2,41 @@
|
||||
default.properties
|
||||
gen
|
||||
assets/www/cordova.js
|
||||
framework/assets/www/.tmp*
|
||||
local.properties
|
||||
framework/proguard.cfg
|
||||
framework/cordova.jar
|
||||
framework/cordova-*.jar
|
||||
framework/phonegap-*.jar
|
||||
framework/lib
|
||||
proguard.cfg
|
||||
proguard.cfg
|
||||
proguard-project.txt
|
||||
framework/bin
|
||||
framework/test/org/apache/cordova/*.class
|
||||
framework/assets/www/.DS_Store
|
||||
framework/assets/www/cordova-*.js
|
||||
framework/assets/www/phonegap-*.js
|
||||
framework/libs
|
||||
framework/javadoc-public
|
||||
framework/javadoc-private
|
||||
test/libs
|
||||
example
|
||||
./test
|
||||
tmp
|
||||
test/bin
|
||||
test/assets/www/.tmp*
|
||||
test/assets/www/cordova.js
|
||||
test/cordova/plugins/org.apache.cordova.device/www/device.js
|
||||
test/cordova/plugins/org.apache.cordova.device/src/android/Device.java
|
||||
tmp/**
|
||||
.metadata
|
||||
tmp/**/*
|
||||
Thumbs.db
|
||||
Desktop.ini
|
||||
*.tmp
|
||||
*.bak
|
||||
*.swp
|
||||
*.class
|
||||
*.jar
|
||||
# IntelliJ IDEA files
|
||||
*.iml
|
||||
.idea
|
||||
npm-debug.log
|
||||
/node_modules
|
||||
/framework/build
|
||||
|
||||
8
.reviewboardrc
Normal file
8
.reviewboardrc
Normal file
@@ -0,0 +1,8 @@
|
||||
#
|
||||
# Settings for post-review (used for uploading diffs to reviews.apache.org).
|
||||
#
|
||||
GUESS_FIELDS = True
|
||||
OPEN_BROWSER = True
|
||||
TARGET_GROUPS = 'cordova'
|
||||
REVIEWBOARD_URL = 'http://reviews.apache.org'
|
||||
|
||||
5
.travis.yml
Normal file
5
.travis.yml
Normal file
@@ -0,0 +1,5 @@
|
||||
language: android
|
||||
install: npm install
|
||||
script:
|
||||
- npm test
|
||||
- npm run test-build
|
||||
38
CONTRIBUTING.md
Normal file
38
CONTRIBUTING.md
Normal file
@@ -0,0 +1,38 @@
|
||||
<!--
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
-->
|
||||
|
||||
# Contributing to Apache Cordova
|
||||
|
||||
Anyone can contribute to Cordova. And we need your contributions.
|
||||
|
||||
There are multiple ways to contribute: report bugs, improve the docs, and
|
||||
contribute code.
|
||||
|
||||
For instructions on this, start with the
|
||||
[contribution overview](http://cordova.apache.org/#contribute).
|
||||
|
||||
The details are explained there, but the important items are:
|
||||
- Sign and submit an Apache ICLA (Contributor License Agreement).
|
||||
- Have a Jira issue open that corresponds to your contribution.
|
||||
- Run the tests so your patch doesn't break existing functionality.
|
||||
|
||||
We look forward to your contributions!
|
||||
|
||||
87
LICENSE
87
LICENSE
@@ -199,4 +199,89 @@
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
limitations under the License.
|
||||
|
||||
ADDITIONAL LICENSES:
|
||||
|
||||
================================================================================
|
||||
bin/node_modules/q
|
||||
================================================================================
|
||||
|
||||
Copyright 2009–2012 Kristopher Michael Kowal. All rights reserved.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to
|
||||
deal in the Software without restriction, including without limitation the
|
||||
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
IN THE SOFTWARE.
|
||||
|
||||
|
||||
================================================================================
|
||||
bin/node_modules/shelljs
|
||||
================================================================================
|
||||
|
||||
Copyright (c) 2012, Artur Adib <aadib@mozilla.com>
|
||||
All rights reserved.
|
||||
|
||||
You may use this project under the terms of the New BSD license as follows:
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Artur Adib nor the
|
||||
names of the contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL ARTUR ADIB BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
================================================================================
|
||||
bin/node_modules/shelljs
|
||||
================================================================================
|
||||
Copyright 2009, 2010, 2011 Isaac Z. Schlueter.
|
||||
All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
18
NOTICE
18
NOTICE
@@ -1,5 +1,17 @@
|
||||
Apache Callback
|
||||
Copyright 2011 The Apache Software Foundation
|
||||
Apache Cordova
|
||||
Copyright 2014 The Apache Software Foundation
|
||||
|
||||
This product includes software developed by
|
||||
This product includes software developed at
|
||||
The Apache Software Foundation (http://www.apache.org)
|
||||
|
||||
=========================================================================
|
||||
== NOTICE file corresponding to the section 4 d of ==
|
||||
== the Apache License, Version 2.0, ==
|
||||
== in this case for the Android-specific code. ==
|
||||
=========================================================================
|
||||
|
||||
This product includes software developed as part of
|
||||
The Android Open Source Project (http://source.android.com).
|
||||
|
||||
This software includes software developed at Square, Inc.
|
||||
Copyright (C) 2013 Square, Inc.
|
||||
|
||||
114
README.md
Executable file → Normal file
114
README.md
Executable file → Normal file
@@ -1,80 +1,61 @@
|
||||
<!--
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
-->
|
||||
Cordova Android
|
||||
===
|
||||
|
||||
Cordova Android is an Android application library that allows for Cordova based projects to be built for the Android Platform. Cordova based applications are, at the core, an application written with web technology: HTML, CSS and JavaScript.
|
||||
Cordova Android is an Android application library that allows for Cordova-based
|
||||
projects to be built for the Android Platform. Cordova based applications are,
|
||||
at the core, applications written with web technology: HTML, CSS and JavaScript.
|
||||
|
||||
[Apache Cordova](http://cordova.io) is a project of The Apache Software Foundation (ASF).
|
||||
|
||||
Apache Cordova is an effort undergoing incubation at The Apache
|
||||
Software Foundation (ASF), sponsored by the Apache Incubator project.
|
||||
Incubation is required of all newly accepted projects until a further
|
||||
review indicates that the infrastructure, communications, and decision
|
||||
making process have stabilized in a manner consistent with other
|
||||
successful ASF projects. While incubation status is not necessarily
|
||||
a reflection of the completeness or stability of the code, it does
|
||||
indicate that the project has yet to be fully endorsed by the ASF.
|
||||
|
||||
Requires
|
||||
---
|
||||
|
||||
- Java JDK 1.5
|
||||
- Apache ANT
|
||||
- Java JDK 1.5 or greater
|
||||
- Apache Ant 1.8.0 or greater
|
||||
- Android SDK [http://developer.android.com](http://developer.android.com)
|
||||
|
||||
|
||||
Building
|
||||
---
|
||||
|
||||
To create your cordova.jar, run in the framework directory:
|
||||
|
||||
android update project -p . -t android-15
|
||||
ant jar
|
||||
|
||||
|
||||
Cordova Android Developer Tools
|
||||
---
|
||||
|
||||
The Cordova developer tooling is split between general tooling and project level tooling.
|
||||
The Cordova developer tooling is split between general tooling and project level tooling.
|
||||
|
||||
General Commands
|
||||
|
||||
./bin/create [path package activity] ... create the ./example app or a cordova android project
|
||||
./bin/bench ............................ generate a bench proj
|
||||
./bin/autotest ......................... test the cli tools
|
||||
./bin/test ............................. run mobile-spec
|
||||
./bin/create [path package activity] ... creates the ./example app or a cordova android project
|
||||
./bin/check_reqs ....................... checks that your environment is set up for cordova-android development
|
||||
./bin/update [path] .................... updates an existing cordova-android project to the version of the framework
|
||||
|
||||
Project Commands
|
||||
|
||||
These commands live in a generated Cordova Android project.
|
||||
These commands live in a generated Cordova Android project. Any interactions with the emulator require you to have an AVD defined.
|
||||
|
||||
./cordovap/debug [path] ..................... install to first device
|
||||
./cordova/emulate .......................... start avd (emulator) named default
|
||||
./cordova/log .............................. starts logcat
|
||||
|
||||
Running the Example Project
|
||||
---
|
||||
|
||||
Start avd (emulator) named `default`:
|
||||
|
||||
./bin/emulate
|
||||
|
||||
Create the example project and build it to the first device:
|
||||
|
||||
./bin/create
|
||||
cd example
|
||||
./cordova/debug
|
||||
|
||||
Start adb logcat (console.log calls output here):
|
||||
|
||||
./cordova/log
|
||||
|
||||
Running the [callback/callback-test](http://github.com/callback/callback-test) tests:
|
||||
---
|
||||
|
||||
./bin/test
|
||||
|
||||
Creating a new Cordova Android Project
|
||||
---
|
||||
|
||||
./bin/create ~/Desktop/myapp com.phonegap.special MyApp
|
||||
./cordova/clean ........................ cleans the project
|
||||
./cordova/build ........................ calls `clean` then compiles the project
|
||||
./cordova/log ........................ streams device or emulator logs to STDOUT
|
||||
./cordova/run ........................ calls `build` then deploys to a connected Android device. If no Android device is detected, will launch an emulator and deploy to it.
|
||||
./cordova/version ...................... returns the cordova-android version of the current project
|
||||
|
||||
Importing a Cordova Android Project into Eclipse
|
||||
----
|
||||
@@ -86,10 +67,25 @@ Importing a Cordova Android Project into Eclipse
|
||||
5. Right click on the project root: Run as > Run Configurations
|
||||
6. Click on the Target tab and select Manual (this way you can choose the emulator or device to build to)
|
||||
|
||||
Building without the Tooling
|
||||
---
|
||||
Note: The Developer Tools handle this. This is only to be done if the tooling fails, or if
|
||||
you are developing directly against the framework.
|
||||
|
||||
|
||||
To create your `cordova.jar` file, run in the framework directory:
|
||||
|
||||
android update project -p . -t android-19
|
||||
ant jar
|
||||
|
||||
|
||||
Running Tests
|
||||
----
|
||||
Please see details under test/README.md.
|
||||
|
||||
Further Reading
|
||||
---
|
||||
----
|
||||
|
||||
- [http://developer.android.com](http://developer.android.com)
|
||||
- [http://docs.phonegap.com](http://docs.phonegap.com)
|
||||
- [http://wiki.phonegap.com](http://wiki.phonegap.com)
|
||||
- [http://cordova.apache.org/](http://cordova.apache.org)
|
||||
- [http://wiki.apache.org/cordova/](http://wiki.apache.org/cordova/)
|
||||
|
||||
309
RELEASENOTES.md
Normal file
309
RELEASENOTES.md
Normal file
@@ -0,0 +1,309 @@
|
||||
<!--
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
-->
|
||||
## Release Notes for Cordova (Android) ##
|
||||
|
||||
### Release 3.7.2 (May 2015) ###
|
||||
|
||||
* Removed Intent Functionality from Preferences - Preferences can no longer be set by intents
|
||||
|
||||
### Release 3.7.1 (January 2015) ###
|
||||
* CB-8411 Initialize plugins only after `createViews()` is called (regression in 3.7.0)
|
||||
|
||||
### Release 3.7.0 (January 2015) ###
|
||||
|
||||
* CB-8328 Allow plugins to handle certificate challenges (close #150)
|
||||
* CB-8201 Add support for auth dialogs into Cordova Android
|
||||
* CB-8017 Add support for `<input type=file>` for Lollipop
|
||||
* CB-8143 Loads of gradle improvements (try it with cordova/build --gradle)
|
||||
* CB-8329 Cancel outstanding ActivityResult requests when a new startActivityForResult occurs
|
||||
* CB-8026 Bumping up Android Version and setting it up to allow third-party cookies. This might change later.
|
||||
* CB-8210 Use PluginResult for various events from native so that content-security-policy <meta> can be used
|
||||
* CB-8168 Add support for `cordova/run --list` (closes #139)
|
||||
* CB-8176 Vastly better auto-detection of SDK & JDK locations
|
||||
* CB-8079 Use activity class package name, but fallback to application package name when looking for splash screen drawable
|
||||
* CB-8147 Have corodva/build warn about unrecognized flags rather than fail
|
||||
* CB-7881 Android tooling shouldn't lock application directory
|
||||
* CB-8112 Turn off mediaPlaybackRequiresUserGesture
|
||||
* CB-6153 Add a preference for controlling hardware button audio stream (DefaultVolumeStream)
|
||||
* CB-8031 Fix race condition that shows as ConcurrentModificationException
|
||||
* CB-7974 Cancel timeout timer if view is destroyed
|
||||
* CB-7940 Disable exec bridge if bridgeSecret is wrong
|
||||
* CB-7758 Allow content-url-hosted pages to access the bridge
|
||||
* CB-6511 Fixes build for android when app name contains unicode characters.
|
||||
* CB-7707 Added multipart PluginResult
|
||||
* CB-6837 Fix leaked window when hitting back button while alert being rendered
|
||||
* CB-7674 Move preference activation back into onCreate()
|
||||
* CB-7499 Support RTL text direction
|
||||
* CB-7330 Don't run check_reqs for bin/create.
|
||||
|
||||
### 3.6.4 (Sept 30, 2014) ###
|
||||
|
||||
* Set VERSION to 3.6.4 (via coho)
|
||||
* Update JS snapshot to version 3.6.4 (via coho)
|
||||
* CB-7634 Detect JAVA_HOME properly on Ubuntu
|
||||
* CB-7579 Fix run script's ability to use non-arch-specific APKs
|
||||
* CB-6511 Fixes build for android when app name contains unicode characters.
|
||||
* CB-7463: Adding licences. I don't know what the gradle syntax is for comments, that still needs to be done.
|
||||
* CB-7463: Looked at the Apache BigTop git, gradle uses C-style comments
|
||||
* CB-7460: Fixing bug with KitKat where the background colour would override the CSS colours on the application
|
||||
|
||||
### 3.6.0 (Sept 2014) ###
|
||||
|
||||
* Set VERSION to 3.6.0 (via coho)
|
||||
* CB-7410 fix the menu test
|
||||
* CB-7410 Fix the errorUrl test
|
||||
* CB-7410 Fix Basic Authentication test
|
||||
* CB-3445: Allow build and run scripts to select APK by architecture
|
||||
* CB-3445: Add environment variable 'BUILD_MULTIPLE_APKS' for splitting APKs based on architecture
|
||||
* CB-3445: Ensure that JAR files in libs directory are included
|
||||
* CB-7267 update RELEASENOTES for 3.5.1
|
||||
* CB-7410 clarify the title
|
||||
* CB-7385 update cordova.js for testing prior to branch/tag
|
||||
* CB-7410 add whitelist entries to get iframe/GoogleMaps working
|
||||
* CB-7291 propogate change in method signature to the native tests
|
||||
* CB-7291: Restrict meaning of "\*" in internal whitelist to just http and https
|
||||
* CB-7291: Only add file, content and data URLs to internal whitelist
|
||||
* CB-7291: Add defaults to external whitelist
|
||||
* CB-7291: Add external-launch-whitelist and use it for filtering intent launches
|
||||
* CB-3445: Read project.properties to configure gradle libraries
|
||||
* CB-7325 Fix error message in android_sdk_version.js when missing SDK on windows
|
||||
* CB-7335 Add a .gitignore to android project template
|
||||
* CB-7330 Fix dangling function call in last commit (broke gradle builds)
|
||||
* CB-7330 Don't run "android update" during creation
|
||||
* CB-3445 Add gradle support clean command (plus some code cleanup)
|
||||
* CB-7044 Fix typo in prev commit causing check_reqs to always fail.
|
||||
* CB-3445 Copy gradle wrapper in build instead of create
|
||||
* CB-3445 Add .gradle template files for "update" as well as "create"
|
||||
* CB-7044 Add JAVA_HOME when not set. Be stricter about ANDROID_HOME
|
||||
* CB-3445 Speed up gradle building (incremental builds go from 10s -> 1.5s for me)
|
||||
* CB-3445: android: Copy Gradle wrapper from Android SDK rather than bundling a JAR
|
||||
* CB-3445: Add which to checked-in node_modules
|
||||
* CB-3445: Add option to build and install with gradle
|
||||
* CB-3445: Add an initial set of Gradle build scripts
|
||||
* CB-7321 Don't require ant for create script
|
||||
* CB-7044, CB-7299 Fix up PATH problems when possible.
|
||||
* Change in test's AndroidManifest.xml needed for the test to run properly. Forgot the manifest.
|
||||
* Change in test's AndroidManifest.xml needed for the test to run properly
|
||||
* Adding tests related to 3.5.1
|
||||
* CB-7261 Fix setNativeToJsBridgeMode sometimes crashing when switching to ONLINE_EVENT
|
||||
* CB-7265 Fix crash when navigating to custom protocol (introduced in 3.5.1)
|
||||
* Filter out non-launchable intents
|
||||
* Handle unsupported protocol errors in webview better
|
||||
* CB-7238: I should have collapsed this, but Config.init() must go before the creation of CordovaWebView
|
||||
* CB-7238: Minor band-aid to get tests running again, this has to go away before 3.6.0 is released, since this is an API change.
|
||||
* Extend whitelist to handle URLs without // chars
|
||||
* CB-7172 Force window to have focus after resume
|
||||
* CB-7159 Set background color of webView as well as its parent
|
||||
* CB-7018 Fix setButtonPlumbedToJs never un-listening
|
||||
* Undeprecate some just-deprecated symbols in PluginManager.
|
||||
* @Deprecate methods of PluginManager that were never meant to be public
|
||||
* Move plugin instantiation and instance storing logic PluginEntry->PluginManager
|
||||
* Fix broken unit test due to missing Config.init() call
|
||||
* Update to check for Google Glass APIs
|
||||
* Fix for `android` not being in PATH check on Windows
|
||||
* Displaying error when regex does not match.
|
||||
* Fix broken compile due to previous commit :(
|
||||
* Tweak CordovaPlugin.initialize method to be less deprecated.
|
||||
* Un-deprecate CordovaActivity.init() - it's needed to tweak prefs in onCreate
|
||||
* Tweak log messages in CordovaBridge with bridgeSecret is wrong
|
||||
* Backport CordovaBridge from 4.0.x -> master
|
||||
* Update unit tests to not use most deprecated things (e.g. DroidGap)
|
||||
* Add non-String overloades for CordovaPreferences.set()
|
||||
* Make CordovaWebview resilient to init() not being called (for backwards-compatibility)
|
||||
* Add node_module licenses to LICENSE
|
||||
* Update cordova.js snapshot to work with bridge changes
|
||||
* Provide CordovaPlugin with CordovaPreferences. Add new Plugin.initialize()
|
||||
* Convert usages of Config.\* to use the non-static versions
|
||||
* Change getProperty -> prefs.get\* within CordovaActivity
|
||||
* Make CordovaUriHelper class package-private
|
||||
* Fix PluginManager.setPluginEntries not removing old entries
|
||||
* Move registration of App plugin from config.xml -> code
|
||||
* Make setWebViewClient an override instead of an overload. Delete Location-change JS->Native bridge mode (missed some of it).
|
||||
* CB-4404 Revert setting android:windowSoftInputMode to "adjustPan"
|
||||
* Refactor: Use ConfigXmlParser in activity. Adds CordovaWebView.init()
|
||||
* Deprecate some convenience methods on CordovaActivity
|
||||
* Fix CordovaPreferences not correctly parsing hex values (valueOf->decode)
|
||||
* Refactor: Move url-filter information into PluginEntry.
|
||||
* Don't re-parse config.xml in onResume.
|
||||
* Move handling of Fullscreen preference to CordovaActivity
|
||||
* Delete dead code from CordovaActivity
|
||||
* Update .classpath to make Eclipse happy (just re-orders one line)
|
||||
* Delete "CB-3064: The errorUrl is..." Log message left over from debugging presumably
|
||||
* Refactor Config into ConfigXmlParser, CordovaPreferences
|
||||
* Delete Location-change JS->Native bridge mode
|
||||
* CB-5988 Allow exec() only from file: or start-up URL's domain
|
||||
* CB-6761 Fix native->JS bridge ceasing to fire when page changes and online is set to false and the JS loads quickly
|
||||
* Update the errorurl to no longer use intents
|
||||
* This breaks running the JUnit tests, we'll bring it back soon
|
||||
* Refactoring the URI handling on Cordova, removing dead code
|
||||
* CB-7018 Clean up and deprecation of some button-related functions
|
||||
* CB-7017 Fix onload=true being set on all subsequent plugins
|
||||
* CB-5971: Fix package / project validation
|
||||
* CB-5971: Add unit tests to cordova-android
|
||||
* CB-5971: Factor out package/project name validation logic
|
||||
* Delete explicit activity.finish() in back button handling. No change in behaviour.
|
||||
* CB-5971: This would have been a good first bug, too bad
|
||||
* CB-4404: Changing where android:windowSoftInputMode is in the manifest so it works
|
||||
* Add documentation referencing other implementation.
|
||||
* CB-6851 Deprecate WebView.sendJavascript()
|
||||
* CB-6876 Show the correct executable name
|
||||
* CB-6876 Fix the "print usage"
|
||||
* Trivial spelling fix in comments when reading CordovaResourceApi
|
||||
* CB-6818: I want to remove this code, because Square didn't do their headers properly
|
||||
* CB-6860 Add activity_name and launcher_name to AndroidManifest.xml & strings.xml
|
||||
* Add a comment to custom_rules.xml saying why we move AndroidManifest.xml
|
||||
* Remove +x from README.md
|
||||
* CB-6784 Add missing licenses
|
||||
* CB-6784 Add license to CONTRIBUTING.md
|
||||
* Revert "defaults.xml: Add AndroidLaunchMode preference"
|
||||
* updated RELEASENOTES
|
||||
* CB-6315: Wrapping this so it runs on the UI thread
|
||||
* CB-6723 Update package name for Robotium
|
||||
* CB-6707 Update minSdkVersion to 10 consistently
|
||||
* CB-5652 make visible cordova version
|
||||
* Update JS snapshot to version 3.6.0-dev (via coho)
|
||||
* Update JS snapshot to version 3.6.0-dev (via coho)
|
||||
* Set VERSION to 3.6.0-dev (via coho)
|
||||
|
||||
### 3.5.1 (August 2014) ###
|
||||
|
||||
This was a security update to address CVE-2014-3500, CVE-2014-3501,
|
||||
and CVE-2014-3502. For more information, see
|
||||
http://cordova.apache.org/announcements/2014/08/04/android-351.html
|
||||
|
||||
* Filter out non-launchable intents
|
||||
* Handle unsupported protocol errors in webview better
|
||||
* Update the errorurl to no longer use intents
|
||||
* Refactoring the URI handling on Cordova, removing dead code
|
||||
|
||||
### 3.5.0 (May 2014) ###
|
||||
|
||||
* OkHttp has broken headers. Updating for ASF compliance.
|
||||
* Revert accidentally removed lines from NOTICE
|
||||
* CB-6552: added top level package.json
|
||||
* CB-6491 add CONTRIBUTING.md
|
||||
* CB-6543 Fix cordova/run failure when no custom_rules.xml available
|
||||
* defaults.xml: Add AndroidLaunchMode preference
|
||||
* Add JavaDoc for CordovaResourceApi
|
||||
* CB-6388: Handle binary data correctly in LOAD_URL bridge
|
||||
* Fix CB-6048: Set launchMode=singleTop so tapping app icon does not always restart app
|
||||
* Remove incorrect usage of AlertDialog.Builder.create
|
||||
* Catch uncaught exceptions in from plugins and turn them into error responses.
|
||||
* Add NOTICE file
|
||||
* CB-6047 Fix online sometimes getting in a bad state on page transitions.
|
||||
* Add another convenience overload for CordovaResourceApi.copyResource
|
||||
* Update framework's .classpath to what Eclipse wants it to be.
|
||||
* README.md: `android update` to `android-19`.
|
||||
* Fix NPE when POLLING bridge mode is used.
|
||||
* Updating NOTICE to include Square for OkHttp
|
||||
* CB-5398 Apply KitKat content URI fix to all content URIs
|
||||
* CB-5398 Work-around for KitKat content: URLs not rendering in <img> tags
|
||||
* CB-5908: add splascreen images to template
|
||||
* CB-5395: Make scheme and host (but not path) case-insensitive in whitelist
|
||||
* Ignore multiple onPageFinished() callbacks & onReceivedError due to stopLoading()
|
||||
* Removing addJavascriptInterface support from all Android versions lower than 4.2 due to security vu
|
||||
* CB-4984 Don't create on CordovaActivity name
|
||||
* CB-5917 Add a loadUrlIntoView overload that doesn't recreate plugins.
|
||||
* Use thread pool for load timeout.
|
||||
* CB-5715 For CLI, hide assets/www and res/xml/config.xml by default
|
||||
* CB-5793 ant builds: Rename AndroidManifest during -post-build to avoid Eclipse detecting ant-build/
|
||||
* CB-5889 Make update script find project name instead of using "null" for CordovaLib
|
||||
* CB-5889 Add a message in the update script about needing to import CordovaLib when using an IDE.
|
||||
|
||||
### 3.4.0 (Feb 2014) ###
|
||||
|
||||
43 commits from 10 authors. Highlights include:
|
||||
|
||||
* Removing addJavascriptInterface support from all Android versions lower than 4.2 due to security vulnerability
|
||||
* CB-5917 Add a loadUrlIntoView overload that doesn't recreate plugins.
|
||||
* CB-5889 Make update script find project name instead of using "null" for CordovaLib
|
||||
* CB-5889 Add a message in the update script about needing to import CordovaLib when using an IDE.
|
||||
* CB-5793 Don't clean before build and change output directory to ant-build to avoid conflicts with Eclipse.
|
||||
* CB-5803 Fix cordova/emulate on windows.
|
||||
* CB-5801 exec->spawn in build to make sure compile errors are shown.
|
||||
* CB-5799 Update version of OkHTTP to 1.3
|
||||
* CB-4910 Update CLI project template to point to config.xml at the root now that it's not in www/ by default.
|
||||
* CB-5504 Adding onDestroy to app plugin to deregister telephonyReceiver
|
||||
* CB-5715 Add Eclipse .project file to create template. For CLI projects, it adds refs for root www/ & config.xml and hides platform versions
|
||||
* CB-5447 Removed android:debuggable=“true” from project template.
|
||||
* CB-5714 Fix of android build when too big output stops build with error due to buffer overflow.
|
||||
* CB-5592 Set MIME type for openExternal when scheme is file:
|
||||
|
||||
### 3.3.0 (Dec 2013) ###
|
||||
|
||||
41 commits from 11 authors. Highlights include:
|
||||
|
||||
* CB-5481 Fix for Cordova trying to get config.xml from the wrong namespace
|
||||
* CB-5487 Enable Remote Debugging when your Android app is debuggable.
|
||||
* CB-5445 Adding onScrollChanged and the ScrollEvent object
|
||||
* CB-5422 Don't require JAVA_HOME to be defined
|
||||
* CB-5490 Add javadoc target to ant script
|
||||
* CB-5471 Deprecated DroidGap class
|
||||
* CB-5255 Prefer Google API targets over android-## targets when building.
|
||||
* CB-5232 Change create script to use Cordova as a Library Project instead of a .jar
|
||||
* CB-5302 Massive movement to get tests working again
|
||||
* CB-4996 Fix paths with spaces while launching on emulator and device
|
||||
* CB-5209 Cannot build Android app if project path contains spaces
|
||||
|
||||
|
||||
### 3.2.0 (Nov 2013) ###
|
||||
|
||||
27 commits from 7 authors. Highlights include:
|
||||
|
||||
* CB-5193 Fix Android WebSQL sometime throwing SECURITY_ERR.
|
||||
* CB-5191 Deprecate <url-filter>
|
||||
* Updating shelljs to 0.2.6. Copy now preserves mode bits.
|
||||
* CB-4872 Added android version scripts (android_sdk_version, etc)
|
||||
* CB-5117 Output confirmation message if check_reqs passes.
|
||||
* CB-5080 Find resources in a way that works with aapt's --rename-manifest-package
|
||||
* CB-4527 Don't delete .bat files even when on non-windows platform
|
||||
* CB-4892 Fix create script only escaping the first space instead of all spaces.
|
||||
|
||||
### 3.1.0 (Sept 2013) ###
|
||||
|
||||
55 commits from 9 authors. Highlights include:
|
||||
|
||||
* [CB-4817] Remove unused assets in project template.
|
||||
* Fail fast in create script if package name is not com.foo.bar.
|
||||
* [CB-4782] Convert ApplicationInfo.java -> appinfo.js
|
||||
* [CB-4766] Deprecated JSONUtils.java (moved into plugins)
|
||||
* [CB-4765] Deprecated ExifHelper.java (moved into plugins)
|
||||
* [CB-4764] Deprecated DirectoryManager.java (moved into plugins)
|
||||
* [CB-4763] Deprecated FileHelper.java (moved into plugins), Move getMimeType() into CordovaResourceApi.
|
||||
* [CB-4725] Add CordovaWebView.CORDOVA_VERSION constant
|
||||
* Incrementing version check for Android 4.3 API Level 18
|
||||
* [CB-3542] rewrote cli tooling scripts in node
|
||||
* Allow CordovaChromeClient subclasses access to CordovaInterface and CordovaWebView members
|
||||
* Refactor CordovaActivity.init so that subclasses can easily override factory methods for webview objects
|
||||
* [CB-4652] Allow default project template to be overridden on create
|
||||
* Tweak the online bridge to not send excess online events.
|
||||
* [CB-4495] Modify start-emulator script to exit immediately on a fatal emulator error.
|
||||
* Log WebView IOExceptions only when they are not 404s
|
||||
* Use a higher threshold for slow exec() warnings when debugger is attached.
|
||||
* Fix data URI decoding in CordovaResourceApi
|
||||
* [CB-3819] Made it easier to set SplashScreen delay.
|
||||
* [CB-4013] Fixed loadUrlTimeoutValue preference.
|
||||
* Upgrading project to Android 4.3
|
||||
* [CB-4198] bin/create script should be better at handling non-word characters in activity name. Patched windows script as well.
|
||||
* [CB-4198] bin/create should handle spaces in activity better.
|
||||
* [CB-4096] Implemented new unified whitelist for android
|
||||
* [CB-3384] Fix thread assertion when plugins remap URIs
|
||||
|
||||
4
bin/BOOM
4
bin/BOOM
@@ -1,4 +0,0 @@
|
||||
#! /bin/sh
|
||||
|
||||
./bin/create
|
||||
cd ./example && ./cordova/debug && ./cordova/log
|
||||
14
framework/src/org/apache/cordova/file/InvalidModificationException.java → bin/android_sdk_version
Normal file → Executable file
14
framework/src/org/apache/cordova/file/InvalidModificationException.java → bin/android_sdk_version
Normal file → Executable file
@@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/*
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
@@ -17,13 +19,11 @@
|
||||
under the License.
|
||||
*/
|
||||
|
||||
var android_sdk_version = require('./lib/android_sdk_version');
|
||||
|
||||
package org.apache.cordova.file;
|
||||
android_sdk_version.run().done(null, function(err) {
|
||||
console.log(err);
|
||||
process.exit(2);
|
||||
});
|
||||
|
||||
public class InvalidModificationException extends Exception {
|
||||
|
||||
public InvalidModificationException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
}
|
||||
26
bin/android_sdk_version.bat
Normal file
26
bin/android_sdk_version.bat
Normal file
@@ -0,0 +1,26 @@
|
||||
:: Licensed to the Apache Software Foundation (ASF) under one
|
||||
:: or more contributor license agreements. See the NOTICE file
|
||||
:: distributed with this work for additional information
|
||||
:: regarding copyright ownership. The ASF licenses this file
|
||||
:: to you under the Apache License, Version 2.0 (the
|
||||
:: "License"); you may not use this file except in compliance
|
||||
:: with the License. You may obtain a copy of the License at
|
||||
::
|
||||
:: http://www.apache.org/licenses/LICENSE-2.0
|
||||
::
|
||||
:: Unless required by applicable law or agreed to in writing,
|
||||
:: software distributed under the License is distributed on an
|
||||
:: "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
:: KIND, either express or implied. See the License for the
|
||||
:: specific language governing permissions and limitations
|
||||
:: under the License.
|
||||
|
||||
@ECHO OFF
|
||||
SET script_path="%~dp0android_sdk_version"
|
||||
IF EXIST %script_path% (
|
||||
node "%script_path%" %*
|
||||
) ELSE (
|
||||
ECHO.
|
||||
ECHO ERROR: Could not find 'android_sdk_version' script in 'bin' folder, aborting...>&2
|
||||
EXIT /B 1
|
||||
)
|
||||
@@ -1,2 +0,0 @@
|
||||
#! /usr/bin/env node
|
||||
require('nodeunit').reporters.default.run(['bin/tests'])
|
||||
29
bin/bench
29
bin/bench
@@ -1,29 +0,0 @@
|
||||
#! /bin/sh
|
||||
#
|
||||
# Creates an app in `./bench` that posts results to http://cordova-bench.heroku.com with current cordova/Android sha.
|
||||
#
|
||||
# USAGE
|
||||
# ./bin/bench
|
||||
#
|
||||
|
||||
# clobber any existing bench
|
||||
if [ -e ./bench ]
|
||||
then
|
||||
rm -rf ./bench
|
||||
fi
|
||||
|
||||
# create a benching app
|
||||
./bin/create ./bench org.apache.cordova.bench cordovaBench
|
||||
|
||||
# grab the latest bench www code
|
||||
git clone git@github.com:brianleroux/cordova-bench.git
|
||||
|
||||
# copy it into the app
|
||||
cat ./cordova-bench/www/index.html > ./bench/assets/www/index.html
|
||||
#cat ~/Desktop/cordova-bench/www/index.html > ./bench/assets/www/index.html
|
||||
|
||||
# clean up
|
||||
rm -rf ./cordova-bench
|
||||
|
||||
# launch to the first device found
|
||||
./bin/debug ./bench
|
||||
31
bin/check_reqs
Executable file
31
bin/check_reqs
Executable file
@@ -0,0 +1,31 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/*
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the License is distributed on an
|
||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
*/
|
||||
|
||||
var check_reqs = require('./lib/check_reqs');
|
||||
|
||||
check_reqs.run().done(
|
||||
function success() {
|
||||
console.log('Looks like your environment fully supports cordova-android development!');
|
||||
}, function fail(err) {
|
||||
console.log(err);
|
||||
process.exit(2);
|
||||
}
|
||||
);
|
||||
26
bin/check_reqs.bat
Normal file
26
bin/check_reqs.bat
Normal file
@@ -0,0 +1,26 @@
|
||||
:: Licensed to the Apache Software Foundation (ASF) under one
|
||||
:: or more contributor license agreements. See the NOTICE file
|
||||
:: distributed with this work for additional information
|
||||
:: regarding copyright ownership. The ASF licenses this file
|
||||
:: to you under the Apache License, Version 2.0 (the
|
||||
:: "License"); you may not use this file except in compliance
|
||||
:: with the License. You may obtain a copy of the License at
|
||||
::
|
||||
:: http://www.apache.org/licenses/LICENSE-2.0
|
||||
::
|
||||
:: Unless required by applicable law or agreed to in writing,
|
||||
:: software distributed under the License is distributed on an
|
||||
:: "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
:: KIND, either express or implied. See the License for the
|
||||
:: specific language governing permissions and limitations
|
||||
:: under the License.
|
||||
|
||||
@ECHO OFF
|
||||
SET script_path="%~dp0check_reqs"
|
||||
IF EXIST %script_path% (
|
||||
node "%script_path%" %*
|
||||
) ELSE (
|
||||
ECHO.
|
||||
ECHO ERROR: Could not find 'check_reqs' script in 'bin' folder, aborting...>&2
|
||||
EXIT /B 1
|
||||
)
|
||||
74
bin/create
74
bin/create
@@ -1,50 +1,36 @@
|
||||
#! /bin/sh
|
||||
#
|
||||
# create a cordova/android project
|
||||
#
|
||||
# USAGE
|
||||
# ./create [path package activity]
|
||||
#
|
||||
set -e
|
||||
#!/usr/bin/env node
|
||||
|
||||
PROJECT_PATH=${1:-"./example"}
|
||||
PACKAGE=${2:-"org.apache.cordova.example"}
|
||||
ACTIVITY=${3:-"cordovaExample"}
|
||||
TARGET=$(android list targets | grep 'id: ' | sed 's/id: \([0-9]*\).*/\1/g' | tail -1)
|
||||
VERSION=$(cat ./VERSION)
|
||||
/*
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
# clobber any existing example
|
||||
if [ $# -eq 0 ]
|
||||
then
|
||||
rm -rf $PROJECT_PATH
|
||||
fi
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
# update the cordova-android framework for the desired target
|
||||
android update project --target $TARGET --path ./framework
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the License is distributed on an
|
||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
*/
|
||||
var path = require('path');
|
||||
var create = require('./lib/create');
|
||||
var args = require('./lib/simpleargs').getArgs(process.argv);
|
||||
|
||||
# compile cordova.js and cordova.jar
|
||||
cd ./framework && ant jar && cd ../
|
||||
if (args['--help'] || args._.length === 0) {
|
||||
console.log('Usage: ' + path.relative(process.cwd(), path.join(__dirname, 'create')) + ' <path_to_new_project> <package_name> <project_name> [<template_path>] [--shared]');
|
||||
console.log(' <path_to_new_project>: Path to your new Cordova Android project');
|
||||
console.log(' <package_name>: Package name, following reverse-domain style convention');
|
||||
console.log(' <project_name>: Project name');
|
||||
console.log(' <template_path>: Path to a custom application template to use');
|
||||
console.log(' --shared will use the CordovaLib project directly instead of making a copy.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
# copy all the bin scripts etc in there
|
||||
cp -R ./bin/templates/project/ $PROJECT_PATH
|
||||
create.createProject(args._[0], args._[1], args._[2], args._[3], args['--shared'], args['--cli']).done();
|
||||
|
||||
# copy in cordova.js
|
||||
cp ./framework/assets/www/cordova-$VERSION.js $PROJECT_PATH/.cordova/android/cordova-$VERSION.js
|
||||
|
||||
# copy in cordova.jar
|
||||
cp ./framework/cordova-$VERSION.jar $PROJECT_PATH/.cordova/android/cordova-$VERSION.jar
|
||||
|
||||
# copy in res/xml
|
||||
cp ./framework/res/xml/cordova.xml $PROJECT_PATH/.cordova/android/cordova.xml
|
||||
cp ./framework/res/xml/plugins.xml $PROJECT_PATH/.cordova/android/plugins.xml
|
||||
|
||||
# app properties
|
||||
cat > $PROJECT_PATH/.cordova/config <<eom
|
||||
VERSION=$VERSION
|
||||
PROJECT_PATH=$PROJECT_PATH
|
||||
PACKAGE=$PACKAGE
|
||||
ACTIVITY=$ACTIVITY
|
||||
TARGET=$TARGET
|
||||
eom
|
||||
|
||||
(cd $PROJECT_PATH && ./cordova/create)
|
||||
|
||||
@@ -1 +1,26 @@
|
||||
cscript create.js
|
||||
:: Licensed to the Apache Software Foundation (ASF) under one
|
||||
:: or more contributor license agreements. See the NOTICE file
|
||||
:: distributed with this work for additional information
|
||||
:: regarding copyright ownership. The ASF licenses this file
|
||||
:: to you under the Apache License, Version 2.0 (the
|
||||
:: "License"); you may not use this file except in compliance
|
||||
:: with the License. You may obtain a copy of the License at
|
||||
::
|
||||
:: http://www.apache.org/licenses/LICENSE-2.0
|
||||
::
|
||||
:: Unless required by applicable law or agreed to in writing,
|
||||
:: software distributed under the License is distributed on an
|
||||
:: "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
:: KIND, either express or implied. See the License for the
|
||||
:: specific language governing permissions and limitations
|
||||
:: under the License.
|
||||
|
||||
@ECHO OFF
|
||||
SET script_path="%~dp0create"
|
||||
IF EXIST %script_path% (
|
||||
node %script_path% %*
|
||||
) ELSE (
|
||||
ECHO.
|
||||
ECHO ERROR: Could not find 'create' script in 'bin' folder, aborting...>&2
|
||||
EXIT /B 1
|
||||
)
|
||||
@@ -1,88 +0,0 @@
|
||||
/*
|
||||
* create a cordova/android project
|
||||
*
|
||||
* USAGE
|
||||
* ./create [path package activity]
|
||||
*/
|
||||
|
||||
function read(filename) {
|
||||
var fso=WScript.CreateObject("Scripting.FileSystemObject");
|
||||
var f=fso.OpenTextFile(filename, 1, true);
|
||||
var s=f.ReadAll();
|
||||
f.Close();
|
||||
return s;
|
||||
}
|
||||
function write(filename, contents) {
|
||||
var fso=WScript.CreateObject("Scripting.FileSystemObject");
|
||||
var f=fso.OpenTextFile(filename, 2, true);
|
||||
f.Write(contents);
|
||||
f.Close();
|
||||
}
|
||||
function replaceInFile(filename, regexp, replacement) {
|
||||
write(filename, read(filename).replace(regexp, replacement));
|
||||
}
|
||||
function exec(s) {
|
||||
var o=shell.Exec(s);
|
||||
}
|
||||
|
||||
var args = WScript.Arguments, PROJECT_PATH="example",
|
||||
PACKAGE="org.apache.cordova.example", ACTIVITY="cordovaExample",
|
||||
shell=WScript.CreateObject("WScript.Shell");
|
||||
|
||||
if (args.Count() == 3) {
|
||||
WScript.Echo('Found expected arguments');
|
||||
PROJECT_PATH=args(0);
|
||||
PACKAGE=args(1);
|
||||
ACTIVITY=args(2);
|
||||
}
|
||||
|
||||
var PACKAGE_AS_PATH=PACKAGE.replace(/\./g, '\\');
|
||||
var ACTIVITY_PATH=PROJECT_PATH+'\\src\\'+PACKAGE_AS_PATH+'\\'+ACTIVITY+'.java';
|
||||
var MANIFEST_PATH=PROJECT_PATH+'\\AndroidManifest.xml';
|
||||
var TARGET=shell.Exec('android.bat list targets').StdOut.ReadAll().match(/id:\s([0-9]).*/)[1];
|
||||
var VERSION=read('VERSION').replace(/\r\n/,'').replace(/\n/,'');
|
||||
|
||||
// clobber any existing example
|
||||
|
||||
/*
|
||||
if [ $# -eq 0 ]
|
||||
then
|
||||
rm -rf $PROJECT_PATH
|
||||
fi
|
||||
*/
|
||||
|
||||
// create the project
|
||||
exec('android.bat create project --target '+TARGET+' --path '+PROJECT_PATH+' --package '+PACKAGE+' --activity '+ACTIVITY);
|
||||
|
||||
// update the cordova framework project to a target that exists on this machine
|
||||
exec('android.bat update project --target '+TARGET+' --path framework');
|
||||
|
||||
// compile cordova.js and cordova.jar
|
||||
// if you see an error about "Unable to resolve target" then you may need to
|
||||
// update your android tools or install an additional Android platform version
|
||||
exec('ant.bat -f framework\\build.xml jar');
|
||||
|
||||
// copy in the project template
|
||||
exec('cmd /c xcopy bin\\templates\\project '+PROJECT_PATH+' /S /Y');
|
||||
|
||||
// copy in cordova.js
|
||||
exec('cmd /c copy framework\\assets\\www\\cordova-'+VERSION+'.js '+PROJECT_PATH+'\\assets\\www\\cordova-'+VERSION+'.js /Y');
|
||||
|
||||
// copy in cordova.jar
|
||||
exec('cmd /c copy framework\\cordova-'+VERSION+'.jar '+PROJECT_PATH+'\\libs\\cordova-'+VERSION+'.jar /Y');
|
||||
|
||||
// copy in default activity
|
||||
exec('cmd /c copy bin\\templates\\Activity.java '+ACTIVITY_PATH+' /Y');
|
||||
|
||||
// interpolate the activity name and package
|
||||
replaceInFile(ACTIVITY_PATH, /__ACTIVITY__/, ACTIVITY);
|
||||
replaceInFile(ACTIVITY_PATH, /__ID__/, PACKAGE);
|
||||
|
||||
replaceInFile(MANIFEST_PATH, /__ACTIVITY__/, ACTIVITY);
|
||||
replaceInFile(MANIFEST_PATH, /__PACKAGE__/, PACKAGE);
|
||||
|
||||
/*
|
||||
# leave the id for launching
|
||||
touch $PROJECT_PATH/package-activity
|
||||
echo $PACKAGE/$PACKAGE.$ACTIVITY > $PROJECT_PATH/package-activity
|
||||
*/
|
||||
@@ -1,79 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="cordova" default="create" basedir="../">
|
||||
|
||||
<property name="project.path" value="${basedir}/example"/>
|
||||
<property name="package" value="org.apache.cordova.example"/>
|
||||
<property name="activity" value="cordovaExample"/>
|
||||
|
||||
<target name="create">
|
||||
|
||||
<!-- this stuff is seriously stupid -->
|
||||
<echo file="tmp/package.tmp">package-as-path=${package}</echo>
|
||||
<replace file="tmp/package.tmp" token="." value="\\" />
|
||||
<property file="tmp/package.tmp" />
|
||||
|
||||
<property name="activity.path" value="${project.path}/src/${package-as-path}/${activity}.java" />
|
||||
<property name="manifest.path" value="${project.path}/AndroidManifest.xml" />
|
||||
|
||||
<!-- get the highest target on this machine -->
|
||||
<!-- this stuff is also seriously stupid -->
|
||||
<exec executable="cmd" osfamily="windows" output="tmp/target.list.tmp">
|
||||
<arg line="/c android.bat list targets"/>
|
||||
</exec>
|
||||
<exec executable="android" osfamily="mac" output="tmp/target.list.tmp">
|
||||
<arg line="list targets"/>
|
||||
</exec>
|
||||
<replaceregexp file="tmp/target.list.tmp" match=".*id:\s([0-9]).*" replace="target=\1" flags="s" />
|
||||
<property file="tmp/target.list.tmp" />
|
||||
|
||||
<!-- var VERSION=read('VERSION').replace(/\r\n/,'').replace(/\n/,''); -->
|
||||
<copy file="VERSION" tofile="tmp/VERSION.tmp" overwrite="true" />
|
||||
<replaceregexp file="tmp/VERSION.tmp" match="^" replace="version=" />
|
||||
<replaceregexp file="tmp/VERSION.tmp" match="\r\n" replace="" />
|
||||
<property file="tmp/VERSION.tmp" />
|
||||
|
||||
<!-- clobber any existing example -->
|
||||
|
||||
<!-- create the project -->
|
||||
<exec executable="cmd" osfamily="windows">
|
||||
<arg line="/c android.bat create project --target ${target} --path ${project.path} --package ${package} --activity ${activity}"/>
|
||||
</exec>
|
||||
<exec executable="android" osfamily="mac">
|
||||
<arg line="create project --target ${target} --path ${project.path} --package ${package} --activity ${activity}"/>
|
||||
</exec>
|
||||
|
||||
<!-- update the framework dir -->
|
||||
<exec executable="cmd" osfamily="windows">
|
||||
<arg line="/c android.bat update project --target ${target} --path ${basedir}/framework"/>
|
||||
</exec>
|
||||
<exec executable="android" osfamily="mac">
|
||||
<arg line="update project --target ${target} --path ${basedir}/framework"/>
|
||||
</exec>
|
||||
|
||||
<!-- compile cordova.js and cordova.jar -->
|
||||
<!-- // if you see an error about "Unable to resolve target" then you may need to
|
||||
// update your android tools or install an additional Android platform version -->
|
||||
<ant antfile="${basedir}/framework/build.xml" useNativeBasedir="true" inheritAll="false" />
|
||||
|
||||
<!-- copy in the project template -->
|
||||
<copy todir="${project.path}" overwrite="true">
|
||||
<fileset dir="${basedir}/bin/templates/project"/>
|
||||
</copy>
|
||||
|
||||
<!-- copy in cordova.js -->
|
||||
<copy file="${basedir}/framework/assets/www/cordova-${version}.js" todir="${project.path}/assets/www/" />
|
||||
|
||||
<!-- copy in cordova.jar -->
|
||||
<copy file="${basedir}/framework/cordova-${version}.jar" todir="${project.path}/libs/" />
|
||||
|
||||
<!-- copy in default activity -->
|
||||
<copy file="${basedir}/bin/templates/Activity.java" tofile="${activity.path}" overwrite="true" />
|
||||
|
||||
<!-- interpolate the activity name and package -->
|
||||
<replaceregexp file="${activity.path}" match="__ACTIVITY__" replace="${activity}" />
|
||||
<replaceregexp file="${activity.path}" match="__ID__" replace="${package}" />
|
||||
|
||||
<replaceregexp file="${manifest.path}" match="__ACTIVITY__" replace="${activity}" />
|
||||
<replaceregexp file="${manifest.path}" match="__PACKAGE__" replace="${package}" />
|
||||
</target>
|
||||
</project>
|
||||
65
bin/lib/android_sdk_version.js
Executable file
65
bin/lib/android_sdk_version.js
Executable file
@@ -0,0 +1,65 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/*
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the License is distributed on an
|
||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
*/
|
||||
|
||||
var shell = require('shelljs'),
|
||||
child_process = require('child_process'),
|
||||
Q = require('q');
|
||||
|
||||
get_highest_sdk = function(results){
|
||||
var reg = /\d+/;
|
||||
var apiLevels = [];
|
||||
for(var i=0;i<results.length;i++){
|
||||
apiLevels[i] = parseInt(results[i].match(reg)[0]);
|
||||
}
|
||||
apiLevels.sort(function(a,b){return b-a});
|
||||
console.log(apiLevels[0]);
|
||||
}
|
||||
|
||||
get_sdks = function() {
|
||||
var d = Q.defer();
|
||||
child_process.exec('android list targets', function(err, stdout, stderr) {
|
||||
if (err) d.reject(stderr);
|
||||
else d.resolve(stdout);
|
||||
});
|
||||
|
||||
return d.promise.then(function(output) {
|
||||
var reg = /android-\d+/gi;
|
||||
var results = output.match(reg);
|
||||
if(results.length===0){
|
||||
return Q.reject(new Error('No android sdks installed.'));
|
||||
}else{
|
||||
get_highest_sdk(results);
|
||||
}
|
||||
|
||||
return Q();
|
||||
}, function(stderr) {
|
||||
if (stderr.match(/command\snot\sfound/) || stderr.match(/'android' is not recognized/)) {
|
||||
return Q.reject(new Error('The command \"android\" failed. Make sure you have the latest Android SDK installed, and the \"android\" command (inside the tools/ folder) is added to your path.'));
|
||||
} else {
|
||||
return Q.reject(new Error('An error occurred while listing Android targets'));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
module.exports.run = function() {
|
||||
return Q.all([get_sdks()]);
|
||||
}
|
||||
|
||||
242
bin/lib/check_reqs.js
Normal file
242
bin/lib/check_reqs.js
Normal file
@@ -0,0 +1,242 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/*
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the License is distributed on an
|
||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
*/
|
||||
|
||||
var shelljs = require('shelljs'),
|
||||
child_process = require('child_process'),
|
||||
Q = require('q'),
|
||||
path = require('path'),
|
||||
fs = require('fs'),
|
||||
which = require('which'),
|
||||
ROOT = path.join(__dirname, '..', '..');
|
||||
|
||||
var isWindows = process.platform == 'win32';
|
||||
|
||||
function forgivingWhichSync(cmd) {
|
||||
try {
|
||||
return fs.realpathSync(which.sync(cmd));
|
||||
} catch (e) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
function tryCommand(cmd, errMsg) {
|
||||
var d = Q.defer();
|
||||
child_process.exec(cmd, function(err, stdout, stderr) {
|
||||
if (err) d.reject(new Error(errMsg));
|
||||
else d.resolve(stdout);
|
||||
});
|
||||
return d.promise;
|
||||
}
|
||||
|
||||
// Get valid target from framework/project.properties
|
||||
module.exports.get_target = function() {
|
||||
function extractFromFile(filePath) {
|
||||
var target = shelljs.grep(/\btarget=/, filePath);
|
||||
if (!target) {
|
||||
throw new Error('Could not find android target within: ' + filePath);
|
||||
}
|
||||
return target.split('=')[1].trim();
|
||||
}
|
||||
if (fs.existsSync(path.join(ROOT, 'framework', 'project.properties'))) {
|
||||
return extractFromFile(path.join(ROOT, 'framework', 'project.properties'));
|
||||
}
|
||||
if (fs.existsSync(path.join(ROOT, 'project.properties'))) {
|
||||
// if no target found, we're probably in a project and project.properties is in ROOT.
|
||||
return extractFromFile(path.join(ROOT, 'project.properties'));
|
||||
}
|
||||
throw new Error('Could not find android target. File missing: ' + path.join(ROOT, 'project.properties'));
|
||||
}
|
||||
|
||||
// Returns a promise. Called only by build and clean commands.
|
||||
module.exports.check_ant = function() {
|
||||
return tryCommand('ant -version', 'Failed to run "ant -version", make sure you have ant installed and added to your PATH.');
|
||||
};
|
||||
|
||||
// Returns a promise. Called only by build and clean commands.
|
||||
module.exports.check_gradle = function() {
|
||||
var sdkDir = process.env['ANDROID_HOME'];
|
||||
var wrapperDir = path.join(sdkDir, 'tools', 'templates', 'gradle', 'wrapper');
|
||||
if (!fs.existsSync(wrapperDir)) {
|
||||
return Q.reject(new Error('Could not find gradle wrapper within android sdk. Might need to update your Android SDK.\n' +
|
||||
'Looked here: ' + wrapperDir));
|
||||
}
|
||||
return Q.when();
|
||||
};
|
||||
|
||||
// Returns a promise.
|
||||
module.exports.check_java = function() {
|
||||
var javacPath = forgivingWhichSync('javac');
|
||||
var hasJavaHome = !!process.env['JAVA_HOME'];
|
||||
return Q().then(function() {
|
||||
if (hasJavaHome) {
|
||||
// Windows java installer doesn't add javac to PATH, nor set JAVA_HOME (ugh).
|
||||
if (!javacPath) {
|
||||
process.env['PATH'] += path.delimiter + path.join(process.env['JAVA_HOME'], 'bin');
|
||||
}
|
||||
} else {
|
||||
if (javacPath) {
|
||||
// OS X has a command for finding JAVA_HOME.
|
||||
if (fs.existsSync('/usr/libexec/java_home')) {
|
||||
return tryCommand('/usr/libexec/java_home', 'Failed to run: /usr/libexec/java_home')
|
||||
.then(function(stdout) {
|
||||
process.env['JAVA_HOME'] = stdout.trim();
|
||||
});
|
||||
} else {
|
||||
// See if we can derive it from javac's location.
|
||||
// fs.realpathSync is require on Ubuntu, which symplinks from /usr/bin -> JDK
|
||||
var maybeJavaHome = path.dirname(path.dirname(javacPath));
|
||||
if (fs.existsSync(path.join(maybeJavaHome, 'lib', 'tools.jar'))) {
|
||||
process.env['JAVA_HOME'] = maybeJavaHome;
|
||||
} else {
|
||||
throw new Error('Could not find JAVA_HOME. Try setting the environment variable manually');
|
||||
}
|
||||
}
|
||||
} else if (isWindows) {
|
||||
// Try to auto-detect java in the default install paths.
|
||||
var oldSilent = shelljs.config.silent;
|
||||
shelljs.config.silent = true;
|
||||
var firstJdkDir =
|
||||
shelljs.ls(process.env['ProgramFiles'] + '\\java\\jdk*')[0] ||
|
||||
shelljs.ls('C:\\Program Files\\java\\jdk*')[0] ||
|
||||
shelljs.ls('C:\\Program Files (x86)\\java\\jdk*')[0];
|
||||
shelljs.config.silent = oldSilent;
|
||||
if (firstJdkDir) {
|
||||
// shelljs always uses / in paths.
|
||||
firstJdkDir = firstJdkDir.replace(/\//g, path.sep);
|
||||
if (!javacPath) {
|
||||
process.env['PATH'] += path.delimiter + path.join(firstJdkDir, 'bin');
|
||||
}
|
||||
process.env['JAVA_HOME'] = firstJdkDir;
|
||||
}
|
||||
}
|
||||
}
|
||||
}).then(function() {
|
||||
var msg =
|
||||
'Failed to run "java -version", make sure that you have a JDK installed.\n' +
|
||||
'You can get it from: http://www.oracle.com/technetwork/java/javase/downloads.\n';
|
||||
if (process.env['JAVA_HOME']) {
|
||||
msg += 'Your JAVA_HOME is invalid: ' + process.env['JAVA_HOME'] + '\n';
|
||||
}
|
||||
return tryCommand('java -version', msg)
|
||||
.then(function() {
|
||||
return tryCommand('javac -version', msg);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Returns a promise.
|
||||
module.exports.check_android = function() {
|
||||
return Q().then(function() {
|
||||
var androidCmdPath = forgivingWhichSync('android');
|
||||
var adbInPath = !!forgivingWhichSync('adb');
|
||||
var hasAndroidHome = !!process.env['ANDROID_HOME'] && fs.existsSync(process.env['ANDROID_HOME']);
|
||||
function maybeSetAndroidHome(value) {
|
||||
if (!hasAndroidHome && fs.existsSync(value)) {
|
||||
hasAndroidHome = true;
|
||||
process.env['ANDROID_HOME'] = value;
|
||||
}
|
||||
}
|
||||
if (!hasAndroidHome && !androidCmdPath) {
|
||||
if (isWindows) {
|
||||
// Android Studio 1.0 installer
|
||||
maybeSetAndroidHome(path.join(process.env['LOCALAPPDATA'], 'Android', 'sdk'));
|
||||
maybeSetAndroidHome(path.join(process.env['ProgramFiles'], 'Android', 'sdk'));
|
||||
// Android Studio pre-1.0 installer
|
||||
maybeSetAndroidHome(path.join(process.env['LOCALAPPDATA'], 'Android', 'android-studio', 'sdk'));
|
||||
maybeSetAndroidHome(path.join(process.env['ProgramFiles'], 'Android', 'android-studio', 'sdk'));
|
||||
// Stand-alone installer
|
||||
maybeSetAndroidHome(path.join(process.env['LOCALAPPDATA'], 'Android', 'android-sdk'));
|
||||
maybeSetAndroidHome(path.join(process.env['ProgramFiles'], 'Android', 'android-sdk'));
|
||||
} else if (process.platform == 'darwin') {
|
||||
// Android Studio 1.0 installer
|
||||
maybeSetAndroidHome(path.join(process.env['HOME'], 'Library', 'Android', 'sdk'));
|
||||
// Android Studio pre-1.0 installer
|
||||
maybeSetAndroidHome('/Applications/Android Studio.app/sdk');
|
||||
// Stand-alone zip file that user might think to put under /Applications
|
||||
maybeSetAndroidHome('/Applications/android-sdk-macosx');
|
||||
maybeSetAndroidHome('/Applications/android-sdk');
|
||||
}
|
||||
if (process.env['HOME']) {
|
||||
// Stand-alone zip file that user might think to put under their home directory
|
||||
maybeSetAndroidHome(path.join(process.env['HOME'], 'android-sdk-macosx'));
|
||||
maybeSetAndroidHome(path.join(process.env['HOME'], 'android-sdk'));
|
||||
}
|
||||
}
|
||||
if (hasAndroidHome && !androidCmdPath) {
|
||||
process.env['PATH'] += path.delimiter + path.join(process.env['ANDROID_HOME'], 'tools');
|
||||
}
|
||||
if (androidCmdPath && !hasAndroidHome) {
|
||||
var parentDir = path.dirname(androidCmdPath);
|
||||
var grandParentDir = path.dirname(parentDir);
|
||||
if (path.basename(parentDir) == 'tools') {
|
||||
process.env['ANDROID_HOME'] = path.dirname(parentDir);
|
||||
hasAndroidHome = true;
|
||||
} else if (fs.existsSync(path.join(grandParentDir, 'tools', 'android'))) {
|
||||
process.env['ANDROID_HOME'] = grandParentDir;
|
||||
hasAndroidHome = true;
|
||||
} else {
|
||||
throw new Error('ANDROID_HOME is not set and no "tools" directory found at ' + parentDir);
|
||||
}
|
||||
}
|
||||
if (hasAndroidHome && !adbInPath) {
|
||||
process.env['PATH'] += path.delimiter + path.join(process.env['ANDROID_HOME'], 'platform-tools');
|
||||
}
|
||||
if (!process.env['ANDROID_HOME']) {
|
||||
throw new Error('ANDROID_HOME is not set and "android" command not in your PATH. You must fulfill at least one of these conditions.');
|
||||
}
|
||||
if (!fs.existsSync(process.env['ANDROID_HOME'])) {
|
||||
throw new Error('ANDROID_HOME is set to a non-existant path: ' + process.env['ANDROID_HOME']);
|
||||
}
|
||||
// Check that the target sdk level is installed.
|
||||
return module.exports.check_android_target(module.exports.get_target());
|
||||
});
|
||||
};
|
||||
|
||||
module.exports.getAbsoluteAndroidCmd = function() {
|
||||
return forgivingWhichSync('android').replace(/(\s)/g, '\\$1');
|
||||
};
|
||||
|
||||
module.exports.check_android_target = function(valid_target) {
|
||||
// valid_target can look like:
|
||||
// android-19
|
||||
// android-L
|
||||
// Google Inc.:Google APIs:20
|
||||
// Google Inc.:Glass Development Kit Preview:20
|
||||
var msg = 'Android SDK not found. Make sure that it is installed. If it is not at the default location, set the ANDROID_HOME environment variable.';
|
||||
return tryCommand('android list targets --compact', msg)
|
||||
.then(function(output) {
|
||||
if (output.split('\n').indexOf(valid_target) == -1) {
|
||||
var androidCmd = module.exports.getAbsoluteAndroidCmd();
|
||||
throw new Error('Please install Android target: "' + valid_target + '".\n\n' +
|
||||
'Hint: Open the SDK manager by running: ' + androidCmd + '\n' +
|
||||
'You will require:\n' +
|
||||
'1. "SDK Platform" for ' + valid_target + '\n' +
|
||||
'2. "Android SDK Platform-tools (latest)\n' +
|
||||
'3. "Android SDK Build-tools" (latest)');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Returns a promise.
|
||||
module.exports.run = function() {
|
||||
return Q.all([this.check_java(), this.check_android()]);
|
||||
}
|
||||
|
||||
323
bin/lib/create.js
Executable file
323
bin/lib/create.js
Executable file
@@ -0,0 +1,323 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/*
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the License is distributed on an
|
||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
*/
|
||||
var shell = require('shelljs'),
|
||||
child_process = require('child_process'),
|
||||
Q = require('q'),
|
||||
path = require('path'),
|
||||
fs = require('fs'),
|
||||
check_reqs = require('./check_reqs'),
|
||||
ROOT = path.join(__dirname, '..', '..');
|
||||
|
||||
// Returns a promise.
|
||||
function exec(command, opt_cwd) {
|
||||
var d = Q.defer();
|
||||
console.log('Running: ' + command);
|
||||
child_process.exec(command, { cwd: opt_cwd }, function(err, stdout, stderr) {
|
||||
stdout && console.log(stdout);
|
||||
stderr && console.error(stderr);
|
||||
if (err) d.reject(err);
|
||||
else d.resolve(stdout);
|
||||
});
|
||||
return d.promise;
|
||||
}
|
||||
|
||||
function setShellFatal(value, func) {
|
||||
var oldVal = shell.config.fatal;
|
||||
shell.config.fatal = value;
|
||||
func();
|
||||
shell.config.fatal = oldVal;
|
||||
}
|
||||
|
||||
function getFrameworkDir(projectPath, shared) {
|
||||
return shared ? path.join(ROOT, 'framework') : path.join(projectPath, 'CordovaLib');
|
||||
}
|
||||
|
||||
function copyJsAndLibrary(projectPath, shared, projectName) {
|
||||
var nestedCordovaLibPath = getFrameworkDir(projectPath, false);
|
||||
shell.cp('-f', path.join(ROOT, 'framework', 'assets', 'www', 'cordova.js'), path.join(projectPath, 'assets', 'www', 'cordova.js'));
|
||||
// Don't fail if there are no old jars.
|
||||
setShellFatal(false, function() {
|
||||
shell.ls(path.join(projectPath, 'libs', 'cordova-*.jar')).forEach(function(oldJar) {
|
||||
console.log("Deleting " + oldJar);
|
||||
shell.rm('-f', oldJar);
|
||||
});
|
||||
// Delete old library project if it existed.
|
||||
if (shared) {
|
||||
shell.rm('-rf', nestedCordovaLibPath);
|
||||
} else {
|
||||
// Delete only the src, since eclipse can't handle its .project file being deleted.
|
||||
shell.rm('-rf', path.join(nestedCordovaLibPath, 'src'));
|
||||
}
|
||||
});
|
||||
if (!shared) {
|
||||
shell.mkdir('-p', nestedCordovaLibPath);
|
||||
shell.cp('-f', path.join(ROOT, 'framework', 'AndroidManifest.xml'), nestedCordovaLibPath);
|
||||
shell.cp('-f', path.join(ROOT, 'framework', 'project.properties'), nestedCordovaLibPath);
|
||||
shell.cp('-f', path.join(ROOT, 'framework', 'build.gradle'), nestedCordovaLibPath);
|
||||
shell.cp('-f', path.join(ROOT, 'framework', 'cordova.gradle'), nestedCordovaLibPath);
|
||||
shell.cp('-r', path.join(ROOT, 'framework', 'src'), nestedCordovaLibPath);
|
||||
// Create an eclipse project file and set the name of it to something unique.
|
||||
// Without this, you can't import multiple CordovaLib projects into the same workspace.
|
||||
var eclipseProjectFilePath = path.join(nestedCordovaLibPath, '.project');
|
||||
if (!fs.existsSync(eclipseProjectFilePath)) {
|
||||
var data = '<?xml version="1.0" encoding="UTF-8"?><projectDescription><name>' + projectName + '-' + 'CordovaLib</name></projectDescription>';
|
||||
fs.writeFileSync(eclipseProjectFilePath, data, 'utf8');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function extractSubProjectPaths(data) {
|
||||
var ret = {};
|
||||
var r = /^\s*android\.library\.reference\.\d+=(.*)(?:\s|$)/mg
|
||||
var m;
|
||||
while (m = r.exec(data)) {
|
||||
ret[m[1]] = 1;
|
||||
}
|
||||
return Object.keys(ret);
|
||||
}
|
||||
|
||||
function writeProjectProperties(projectPath, target_api, shared) {
|
||||
var dstPath = path.join(projectPath, 'project.properties');
|
||||
var templatePath = path.join(ROOT, 'bin', 'templates', 'project', 'project.properties');
|
||||
var srcPath = fs.existsSync(dstPath) ? dstPath : templatePath;
|
||||
var data = fs.readFileSync(srcPath, 'utf8');
|
||||
data = data.replace(/^target=.*/m, 'target=' + target_api);
|
||||
var subProjects = extractSubProjectPaths(data);
|
||||
subProjects = subProjects.filter(function(p) {
|
||||
return !(/^CordovaLib$/m.exec(p) ||
|
||||
/[\\\/]cordova-android[\\\/]framework$/m.exec(p) ||
|
||||
/^(\.\.[\\\/])+framework$/m.exec(p)
|
||||
);
|
||||
});
|
||||
subProjects.unshift(shared ? path.relative(projectPath, path.join(ROOT, 'framework')) : 'CordovaLib');
|
||||
data = data.replace(/^\s*android\.library\.reference\.\d+=.*\n/mg, '');
|
||||
if (!/\n$/.exec(data)) {
|
||||
data += '\n';
|
||||
}
|
||||
for (var i = 0; i < subProjects.length; ++i) {
|
||||
data += 'android.library.reference.' + (i+1) + '=' + subProjects[i] + '\n';
|
||||
}
|
||||
fs.writeFileSync(dstPath, data);
|
||||
}
|
||||
|
||||
function copyBuildRules(projectPath) {
|
||||
var srcDir = path.join(ROOT, 'bin', 'templates', 'project');
|
||||
shell.cp('-f', path.join(srcDir, 'custom_rules.xml'), projectPath);
|
||||
|
||||
shell.cp('-f', path.join(srcDir, 'build.gradle'), projectPath);
|
||||
}
|
||||
|
||||
function copyScripts(projectPath) {
|
||||
var srcScriptsDir = path.join(ROOT, 'bin', 'templates', 'cordova');
|
||||
var destScriptsDir = path.join(projectPath, 'cordova');
|
||||
// Delete old scripts directory if this is an update.
|
||||
shell.rm('-rf', destScriptsDir);
|
||||
// Copy in the new ones.
|
||||
shell.cp('-r', srcScriptsDir, projectPath);
|
||||
shell.cp('-r', path.join(ROOT, 'bin', 'node_modules'), destScriptsDir);
|
||||
shell.cp(path.join(ROOT, 'bin', 'check_reqs'), path.join(destScriptsDir, 'check_reqs'));
|
||||
shell.cp(path.join(ROOT, 'bin', 'lib', 'check_reqs.js'), path.join(projectPath, 'cordova', 'lib', 'check_reqs.js'));
|
||||
shell.cp(path.join(ROOT, 'bin', 'android_sdk_version'), path.join(destScriptsDir, 'android_sdk_version'));
|
||||
shell.cp(path.join(ROOT, 'bin', 'lib', 'android_sdk_version.js'), path.join(projectPath, 'cordova', 'lib', 'android_sdk_version.js'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether a package name is acceptable for use as an android project.
|
||||
* Returns a promise, fulfilled if the package name is acceptable; rejected
|
||||
* otherwise.
|
||||
*/
|
||||
function validatePackageName(package_name) {
|
||||
//Make the package conform to Java package types
|
||||
//Enforce underscore limitation
|
||||
if (!/^[a-zA-Z]+(\.[a-zA-Z0-9][a-zA-Z0-9_]*)+$/.test(package_name)) {
|
||||
return Q.reject('Package name must look like: com.company.Name');
|
||||
}
|
||||
|
||||
//Class is a reserved word
|
||||
if(/\b[Cc]lass\b/.test(package_name)) {
|
||||
return Q.reject('class is a reserved word');
|
||||
}
|
||||
|
||||
return Q.resolve();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether a project name is acceptable for use as an android class.
|
||||
* Returns a promise, fulfilled if the project name is acceptable; rejected
|
||||
* otherwise.
|
||||
*/
|
||||
function validateProjectName(project_name) {
|
||||
//Make sure there's something there
|
||||
if (project_name === '') {
|
||||
return Q.reject('Project name cannot be empty');
|
||||
}
|
||||
|
||||
//Enforce stupid name error
|
||||
if (project_name === 'CordovaActivity') {
|
||||
return Q.reject('Project name cannot be CordovaActivity');
|
||||
}
|
||||
|
||||
//Classes in Java don't begin with numbers
|
||||
if (/^[0-9]/.test(project_name)) {
|
||||
return Q.reject('Project name must not begin with a number');
|
||||
}
|
||||
|
||||
return Q.resolve();
|
||||
}
|
||||
|
||||
/**
|
||||
* $ create [options]
|
||||
*
|
||||
* Creates an android application with the given options.
|
||||
*
|
||||
* Options:
|
||||
*
|
||||
* - `project_path` {String} Path to the new Cordova android project.
|
||||
* - `package_name`{String} Package name, following reverse-domain style convention.
|
||||
* - `project_name` {String} Project name.
|
||||
* - 'project_template_dir' {String} Path to project template (override).
|
||||
*
|
||||
* Returns a promise.
|
||||
*/
|
||||
|
||||
exports.createProject = function(project_path, package_name, project_name, project_template_dir, use_shared_project, use_cli_template) {
|
||||
var VERSION = fs.readFileSync(path.join(ROOT, 'VERSION'), 'utf-8').trim();
|
||||
|
||||
// Set default values for path, package and name
|
||||
project_path = typeof project_path !== 'undefined' ? project_path : "CordovaExample";
|
||||
project_path = path.relative(process.cwd(), project_path);
|
||||
package_name = typeof package_name !== 'undefined' ? package_name : 'my.cordova.project';
|
||||
project_name = typeof project_name !== 'undefined' ? project_name : 'CordovaExample';
|
||||
project_template_dir = typeof project_template_dir !== 'undefined' ?
|
||||
project_template_dir :
|
||||
path.join(ROOT, 'bin', 'templates', 'project');
|
||||
|
||||
var package_as_path = package_name.replace(/\./g, path.sep);
|
||||
var activity_dir = path.join(project_path, 'src', package_as_path);
|
||||
// safe_activity_name is being hardcoded to avoid issues with unicode app name (https://issues.apache.org/jira/browse/CB-6511)
|
||||
// TODO: provide option to specify activity name via CLI (proposal: https://issues.apache.org/jira/browse/CB-7231)
|
||||
var safe_activity_name = 'MainActivity';
|
||||
var activity_path = path.join(activity_dir, safe_activity_name + '.java');
|
||||
var target_api = check_reqs.get_target();
|
||||
var manifest_path = path.join(project_path, 'AndroidManifest.xml');
|
||||
|
||||
// Check if project already exists
|
||||
if(fs.existsSync(project_path)) {
|
||||
return Q.reject('Project already exists! Delete and recreate');
|
||||
}
|
||||
|
||||
//Make the package conform to Java package types
|
||||
return validatePackageName(package_name)
|
||||
.then(function() {
|
||||
validateProjectName(project_name);
|
||||
}).then(function() {
|
||||
// Log the given values for the project
|
||||
console.log('Creating Cordova project for the Android platform:');
|
||||
console.log('\tPath: ' + project_path);
|
||||
console.log('\tPackage: ' + package_name);
|
||||
console.log('\tName: ' + project_name);
|
||||
console.log('\tAndroid target: ' + target_api);
|
||||
|
||||
console.log('Copying template files...');
|
||||
|
||||
setShellFatal(true, function() {
|
||||
// copy project template
|
||||
shell.cp('-r', path.join(project_template_dir, 'assets'), project_path);
|
||||
shell.cp('-r', path.join(project_template_dir, 'res'), project_path);
|
||||
shell.cp('-r', path.join(ROOT, 'framework', 'res', 'xml'), path.join(project_path, 'res'));
|
||||
shell.cp(path.join(project_template_dir, 'gitignore'), path.join(project_path, '.gitignore'));
|
||||
|
||||
// Manually create directories that would be empty within the template (since git doesn't track directories).
|
||||
shell.mkdir(path.join(project_path, 'libs'));
|
||||
|
||||
// Add in the proper eclipse project file.
|
||||
if (use_cli_template) {
|
||||
var note = 'To show `assets/www` or `res/xml/config.xml`, go to:\n' +
|
||||
' Project -> Properties -> Resource -> Resource Filters\n' +
|
||||
'And delete the exclusion filter.\n';
|
||||
shell.cp(path.join(project_template_dir, 'eclipse-project-CLI'), path.join(project_path, '.project'));
|
||||
fs.writeFileSync(path.join(project_path, 'assets', '_where-is-www.txt'), note);
|
||||
} else {
|
||||
shell.cp(path.join(project_template_dir, 'eclipse-project'), path.join(project_path, '.project'));
|
||||
}
|
||||
|
||||
// copy cordova.js, cordova.jar
|
||||
copyJsAndLibrary(project_path, use_shared_project, safe_activity_name);
|
||||
|
||||
// interpolate the activity name and package
|
||||
shell.mkdir('-p', activity_dir);
|
||||
shell.cp('-f', path.join(project_template_dir, 'Activity.java'), activity_path);
|
||||
shell.sed('-i', /__ACTIVITY__/, safe_activity_name, activity_path);
|
||||
shell.sed('-i', /__NAME__/, project_name, path.join(project_path, 'res', 'values', 'strings.xml'));
|
||||
shell.sed('-i', /__NAME__/, project_name, path.join(project_path, '.project'));
|
||||
shell.sed('-i', /__ID__/, package_name, activity_path);
|
||||
|
||||
shell.cp('-f', path.join(project_template_dir, 'AndroidManifest.xml'), manifest_path);
|
||||
shell.sed('-i', /__ACTIVITY__/, safe_activity_name, manifest_path);
|
||||
shell.sed('-i', /__PACKAGE__/, package_name, manifest_path);
|
||||
shell.sed('-i', /__APILEVEL__/, target_api.split('-')[1], manifest_path);
|
||||
copyScripts(project_path);
|
||||
copyBuildRules(project_path);
|
||||
});
|
||||
// Link it to local android install.
|
||||
writeProjectProperties(project_path, target_api, use_shared_project);
|
||||
}).then(function() {
|
||||
console.log('Project successfully created.');
|
||||
});
|
||||
}
|
||||
|
||||
// Attribute removed in Cordova 4.4 (CB-5447).
|
||||
function removeDebuggableFromManifest(projectPath) {
|
||||
var manifestPath = path.join(projectPath, 'AndroidManifest.xml');
|
||||
shell.sed('-i', /\s*android:debuggable="true"/, '', manifestPath);
|
||||
}
|
||||
|
||||
function extractProjectNameFromManifest(projectPath) {
|
||||
var manifestPath = path.join(projectPath, 'AndroidManifest.xml');
|
||||
var manifestData = fs.readFileSync(manifestPath, 'utf8');
|
||||
var m = /<activity[\s\S]*?android:name\s*=\s*"(.*?)"/i.exec(manifestData);
|
||||
if (!m) {
|
||||
throw new Error('Could not find activity name in ' + manifestPath);
|
||||
}
|
||||
return m[1];
|
||||
}
|
||||
|
||||
// Returns a promise.
|
||||
exports.updateProject = function(projectPath, shared) {
|
||||
var newVersion = fs.readFileSync(path.join(ROOT, 'VERSION'), 'utf-8').trim();
|
||||
return Q()
|
||||
.then(function() {
|
||||
var projectName = extractProjectNameFromManifest(projectPath);
|
||||
var target_api = check_reqs.get_target();
|
||||
copyJsAndLibrary(projectPath, shared, projectName);
|
||||
copyScripts(projectPath);
|
||||
copyBuildRules(projectPath);
|
||||
removeDebuggableFromManifest(projectPath);
|
||||
writeProjectProperties(projectPath, target_api, shared);
|
||||
console.log('Android project is now at version ' + newVersion);
|
||||
console.log('If you updated from a pre-3.2.0 version and use an IDE, we now require that you import the "CordovaLib" library project.');
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// For testing
|
||||
exports.validatePackageName = validatePackageName;
|
||||
exports.validateProjectName = validateProjectName;
|
||||
21
framework/src/com/phonegap/api/IPlugin.java → bin/lib/simpleargs.js
Executable file → Normal file
21
framework/src/com/phonegap/api/IPlugin.java → bin/lib/simpleargs.js
Executable file → Normal file
@@ -16,12 +16,17 @@
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
*/
|
||||
package com.phonegap.api;
|
||||
|
||||
/**
|
||||
* Plugin interface must be implemented by any plugin classes.
|
||||
*
|
||||
* The execute method is called by the PluginManager.
|
||||
*/
|
||||
public interface IPlugin extends org.apache.cordova.api.IPlugin {
|
||||
}
|
||||
exports.getArgs = function(argv) {
|
||||
var ret = {};
|
||||
var posArgs = [];
|
||||
for (var i = 2, arg; arg = argv[i] || i < argv.length; ++i) {
|
||||
if (/^--/.exec(arg)) {
|
||||
ret[arg] = true;
|
||||
} else {
|
||||
posArgs.push(arg);
|
||||
}
|
||||
}
|
||||
ret._ = posArgs;
|
||||
return ret;
|
||||
};
|
||||
1
bin/node_modules/.bin/cake
generated
vendored
1
bin/node_modules/.bin/cake
generated
vendored
@@ -1 +0,0 @@
|
||||
../coffee-script/bin/cake
|
||||
1
bin/node_modules/.bin/coffee
generated
vendored
1
bin/node_modules/.bin/coffee
generated
vendored
@@ -1 +0,0 @@
|
||||
../coffee-script/bin/coffee
|
||||
1
bin/node_modules/.bin/nodeunit
generated
vendored
1
bin/node_modules/.bin/nodeunit
generated
vendored
@@ -1 +0,0 @@
|
||||
../nodeunit/bin/nodeunit
|
||||
1
bin/node_modules/.bin/shjs
generated
vendored
Symbolic link
1
bin/node_modules/.bin/shjs
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../shelljs/bin/shjs
|
||||
11
bin/node_modules/coffee-script/.npmignore
generated
vendored
11
bin/node_modules/coffee-script/.npmignore
generated
vendored
@@ -1,11 +0,0 @@
|
||||
*.coffee
|
||||
*.html
|
||||
.DS_Store
|
||||
.git*
|
||||
Cakefile
|
||||
documentation/
|
||||
examples/
|
||||
extras/coffee-script.js
|
||||
raw/
|
||||
src/
|
||||
test/
|
||||
48
bin/node_modules/coffee-script/README
generated
vendored
48
bin/node_modules/coffee-script/README
generated
vendored
@@ -1,48 +0,0 @@
|
||||
=
|
||||
{
|
||||
} } {
|
||||
{ { } }
|
||||
} }{ {
|
||||
{ }{ } } _____ __ __
|
||||
( }{ }{ { ) / ____| / _|/ _|
|
||||
.- { { } { }} -. | | ___ | |_| |_ ___ ___
|
||||
( ( } { } { } } ) | | / _ \| _| _/ _ \/ _ \
|
||||
|`-..________ ..-'| | |___| (_) | | | || __/ __/
|
||||
| | \_____\___/|_| |_| \___|\___|
|
||||
| ;--.
|
||||
| (__ \ _____ _ _
|
||||
| | ) ) / ____| (_) | |
|
||||
| |/ / | (___ ___ _ __ _ _ __ | |_
|
||||
| ( / \___ \ / __| '__| | '_ \| __|
|
||||
| |/ ____) | (__| | | | |_) | |_
|
||||
| | |_____/ \___|_| |_| .__/ \__|
|
||||
`-.._________..-' | |
|
||||
|_|
|
||||
|
||||
|
||||
CoffeeScript is a little language that compiles into JavaScript.
|
||||
|
||||
Install Node.js, and then the CoffeeScript compiler:
|
||||
sudo bin/cake install
|
||||
|
||||
Or, if you have the Node Package Manager installed:
|
||||
npm install -g coffee-script
|
||||
(Leave off the -g if you don't wish to install globally.)
|
||||
|
||||
Compile a script:
|
||||
coffee /path/to/script.coffee
|
||||
|
||||
For documentation, usage, and examples, see:
|
||||
http://coffeescript.org/
|
||||
|
||||
To suggest a feature, report a bug, or general discussion:
|
||||
http://github.com/jashkenas/coffee-script/issues/
|
||||
|
||||
If you'd like to chat, drop by #coffeescript on Freenode IRC,
|
||||
or on webchat.freenode.net.
|
||||
|
||||
The source repository:
|
||||
git://github.com/jashkenas/coffee-script.git
|
||||
|
||||
All contributors are listed here:
|
||||
http://github.com/jashkenas/coffee-script/contributors
|
||||
78
bin/node_modules/coffee-script/Rakefile
generated
vendored
78
bin/node_modules/coffee-script/Rakefile
generated
vendored
@@ -1,78 +0,0 @@
|
||||
require 'rubygems'
|
||||
require 'erb'
|
||||
require 'fileutils'
|
||||
require 'rake/testtask'
|
||||
require 'json'
|
||||
|
||||
desc "Build the documentation page"
|
||||
task :doc do
|
||||
source = 'documentation/index.html.erb'
|
||||
child = fork { exec "bin/coffee -bcw -o documentation/js documentation/coffee/*.coffee" }
|
||||
at_exit { Process.kill("INT", child) }
|
||||
Signal.trap("INT") { exit }
|
||||
loop do
|
||||
mtime = File.stat(source).mtime
|
||||
if !@mtime || mtime > @mtime
|
||||
rendered = ERB.new(File.read(source)).result(binding)
|
||||
File.open('index.html', 'w+') {|f| f.write(rendered) }
|
||||
end
|
||||
@mtime = mtime
|
||||
sleep 1
|
||||
end
|
||||
end
|
||||
|
||||
desc "Build coffee-script-source gem"
|
||||
task :gem do
|
||||
require 'rubygems'
|
||||
require 'rubygems/package'
|
||||
|
||||
gemspec = Gem::Specification.new do |s|
|
||||
s.name = 'coffee-script-source'
|
||||
s.version = JSON.parse(File.read('package.json'))["version"]
|
||||
s.date = Time.now.strftime("%Y-%m-%d")
|
||||
|
||||
s.homepage = "http://jashkenas.github.com/coffee-script/"
|
||||
s.summary = "The CoffeeScript Compiler"
|
||||
s.description = <<-EOS
|
||||
CoffeeScript is a little language that compiles into JavaScript.
|
||||
Underneath all of those embarrassing braces and semicolons,
|
||||
JavaScript has always had a gorgeous object model at its heart.
|
||||
CoffeeScript is an attempt to expose the good parts of JavaScript
|
||||
in a simple way.
|
||||
EOS
|
||||
|
||||
s.files = [
|
||||
'lib/coffee_script/coffee-script.js',
|
||||
'lib/coffee_script/source.rb'
|
||||
]
|
||||
|
||||
s.authors = ['Jeremy Ashkenas']
|
||||
s.email = 'jashkenas@gmail.com'
|
||||
s.rubyforge_project = 'coffee-script-source'
|
||||
end
|
||||
|
||||
file = File.open("coffee-script-source.gem", "w")
|
||||
Gem::Package.open(file, 'w') do |pkg|
|
||||
pkg.metadata = gemspec.to_yaml
|
||||
|
||||
path = "lib/coffee_script/source.rb"
|
||||
contents = <<-ERUBY
|
||||
module CoffeeScript
|
||||
module Source
|
||||
def self.bundled_path
|
||||
File.expand_path("../coffee-script.js", __FILE__)
|
||||
end
|
||||
end
|
||||
end
|
||||
ERUBY
|
||||
pkg.add_file_simple(path, 0644, contents.size) do |tar_io|
|
||||
tar_io.write(contents)
|
||||
end
|
||||
|
||||
contents = File.read("extras/coffee-script.js")
|
||||
path = "lib/coffee_script/coffee-script.js"
|
||||
pkg.add_file_simple(path, 0644, contents.size) do |tar_io|
|
||||
tar_io.write(contents)
|
||||
end
|
||||
end
|
||||
end
|
||||
7
bin/node_modules/coffee-script/bin/cake
generated
vendored
7
bin/node_modules/coffee-script/bin/cake
generated
vendored
@@ -1,7 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
var path = require('path');
|
||||
var fs = require('fs');
|
||||
var lib = path.join(path.dirname(fs.realpathSync(__filename)), '../lib');
|
||||
|
||||
require(lib + '/cake').run();
|
||||
7
bin/node_modules/coffee-script/bin/coffee
generated
vendored
7
bin/node_modules/coffee-script/bin/coffee
generated
vendored
@@ -1,7 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
var path = require('path');
|
||||
var fs = require('fs');
|
||||
var lib = path.join(path.dirname(fs.realpathSync(__filename)), '../lib');
|
||||
|
||||
require(lib + '/command').run();
|
||||
44
bin/node_modules/coffee-script/extras/jsl.conf
generated
vendored
44
bin/node_modules/coffee-script/extras/jsl.conf
generated
vendored
@@ -1,44 +0,0 @@
|
||||
# JavaScriptLint configuration file for CoffeeScript.
|
||||
|
||||
+no_return_value # function {0} does not always return a value
|
||||
+duplicate_formal # duplicate formal argument {0}
|
||||
-equal_as_assign # test for equality (==) mistyped as assignment (=)?{0}
|
||||
+var_hides_arg # variable {0} hides argument
|
||||
+redeclared_var # redeclaration of {0} {1}
|
||||
-anon_no_return_value # anonymous function does not always return a value
|
||||
+missing_semicolon # missing semicolon
|
||||
+meaningless_block # meaningless block; curly braces have no impact
|
||||
-comma_separated_stmts # multiple statements separated by commas (use semicolons?)
|
||||
+unreachable_code # unreachable code
|
||||
+missing_break # missing break statement
|
||||
-missing_break_for_last_case # missing break statement for last case in switch
|
||||
-comparison_type_conv # comparisons against null, 0, true, false, or an empty string allowing implicit type conversion (use === or !==)
|
||||
-inc_dec_within_stmt # increment (++) and decrement (--) operators used as part of greater statement
|
||||
-useless_void # use of the void type may be unnecessary (void is always undefined)
|
||||
+multiple_plus_minus # unknown order of operations for successive plus (e.g. x+++y) or minus (e.g. x---y) signs
|
||||
+use_of_label # use of label
|
||||
-block_without_braces # block statement without curly braces
|
||||
+leading_decimal_point # leading decimal point may indicate a number or an object member
|
||||
+trailing_decimal_point # trailing decimal point may indicate a number or an object member
|
||||
+octal_number # leading zeros make an octal number
|
||||
+nested_comment # nested comment
|
||||
+misplaced_regex # regular expressions should be preceded by a left parenthesis, assignment, colon, or comma
|
||||
+ambiguous_newline # unexpected end of line; it is ambiguous whether these lines are part of the same statement
|
||||
+empty_statement # empty statement or extra semicolon
|
||||
-missing_option_explicit # the "option explicit" control comment is missing
|
||||
+partial_option_explicit # the "option explicit" control comment, if used, must be in the first script tag
|
||||
+dup_option_explicit # duplicate "option explicit" control comment
|
||||
+useless_assign # useless assignment
|
||||
+ambiguous_nested_stmt # block statements containing block statements should use curly braces to resolve ambiguity
|
||||
+ambiguous_else_stmt # the else statement could be matched with one of multiple if statements (use curly braces to indicate intent)
|
||||
-missing_default_case # missing default case in switch statement
|
||||
+duplicate_case_in_switch # duplicate case in switch statements
|
||||
+default_not_at_end # the default case is not at the end of the switch statement
|
||||
+legacy_cc_not_understood # couldn't understand control comment using /*@keyword@*/ syntax
|
||||
+jsl_cc_not_understood # couldn't understand control comment using /*jsl:keyword*/ syntax
|
||||
+useless_comparison # useless comparison; comparing identical expressions
|
||||
+with_statement # with statement hides undeclared variables; use temporary variable instead
|
||||
+trailing_comma_in_array # extra comma is not recommended in array initializers
|
||||
+assign_to_function_call # assignment to a function call
|
||||
+parseint_missing_radix # parseInt missing radix parameter
|
||||
+lambda_assign_requires_semicolon
|
||||
75
bin/node_modules/coffee-script/lib/browser.js
generated
vendored
75
bin/node_modules/coffee-script/lib/browser.js
generated
vendored
@@ -1,75 +0,0 @@
|
||||
(function() {
|
||||
var CoffeeScript, runScripts;
|
||||
CoffeeScript = require('./coffee-script');
|
||||
CoffeeScript.require = require;
|
||||
CoffeeScript.eval = function(code, options) {
|
||||
return eval(CoffeeScript.compile(code, options));
|
||||
};
|
||||
CoffeeScript.run = function(code, options) {
|
||||
if (options == null) {
|
||||
options = {};
|
||||
}
|
||||
options.bare = true;
|
||||
return Function(CoffeeScript.compile(code, options))();
|
||||
};
|
||||
if (typeof window === "undefined" || window === null) {
|
||||
return;
|
||||
}
|
||||
CoffeeScript.load = function(url, callback) {
|
||||
var xhr;
|
||||
xhr = new (window.ActiveXObject || XMLHttpRequest)('Microsoft.XMLHTTP');
|
||||
xhr.open('GET', url, true);
|
||||
if ('overrideMimeType' in xhr) {
|
||||
xhr.overrideMimeType('text/plain');
|
||||
}
|
||||
xhr.onreadystatechange = function() {
|
||||
var _ref;
|
||||
if (xhr.readyState === 4) {
|
||||
if ((_ref = xhr.status) === 0 || _ref === 200) {
|
||||
CoffeeScript.run(xhr.responseText);
|
||||
} else {
|
||||
throw new Error("Could not load " + url);
|
||||
}
|
||||
if (callback) {
|
||||
return callback();
|
||||
}
|
||||
}
|
||||
};
|
||||
return xhr.send(null);
|
||||
};
|
||||
runScripts = function() {
|
||||
var coffees, execute, index, length, s, scripts;
|
||||
scripts = document.getElementsByTagName('script');
|
||||
coffees = (function() {
|
||||
var _i, _len, _results;
|
||||
_results = [];
|
||||
for (_i = 0, _len = scripts.length; _i < _len; _i++) {
|
||||
s = scripts[_i];
|
||||
if (s.type === 'text/coffeescript') {
|
||||
_results.push(s);
|
||||
}
|
||||
}
|
||||
return _results;
|
||||
})();
|
||||
index = 0;
|
||||
length = coffees.length;
|
||||
(execute = function() {
|
||||
var script;
|
||||
script = coffees[index++];
|
||||
if ((script != null ? script.type : void 0) === 'text/coffeescript') {
|
||||
if (script.src) {
|
||||
return CoffeeScript.load(script.src, execute);
|
||||
} else {
|
||||
CoffeeScript.run(script.innerHTML);
|
||||
return execute();
|
||||
}
|
||||
}
|
||||
})();
|
||||
return null;
|
||||
};
|
||||
if (window.addEventListener) {
|
||||
addEventListener('DOMContentLoaded', runScripts, false);
|
||||
} else {
|
||||
attachEvent('onload', runScripts);
|
||||
}
|
||||
}).call(this);
|
||||
76
bin/node_modules/coffee-script/lib/cake.js
generated
vendored
76
bin/node_modules/coffee-script/lib/cake.js
generated
vendored
@@ -1,76 +0,0 @@
|
||||
(function() {
|
||||
var CoffeeScript, fs, helpers, missingTask, oparse, options, optparse, path, printTasks, switches, tasks;
|
||||
fs = require('fs');
|
||||
path = require('path');
|
||||
helpers = require('./helpers');
|
||||
optparse = require('./optparse');
|
||||
CoffeeScript = require('./coffee-script');
|
||||
tasks = {};
|
||||
options = {};
|
||||
switches = [];
|
||||
oparse = null;
|
||||
helpers.extend(global, {
|
||||
task: function(name, description, action) {
|
||||
var _ref;
|
||||
if (!action) {
|
||||
_ref = [description, action], action = _ref[0], description = _ref[1];
|
||||
}
|
||||
return tasks[name] = {
|
||||
name: name,
|
||||
description: description,
|
||||
action: action
|
||||
};
|
||||
},
|
||||
option: function(letter, flag, description) {
|
||||
return switches.push([letter, flag, description]);
|
||||
},
|
||||
invoke: function(name) {
|
||||
if (!tasks[name]) {
|
||||
missingTask(name);
|
||||
}
|
||||
return tasks[name].action(options);
|
||||
}
|
||||
});
|
||||
exports.run = function() {
|
||||
return path.exists('Cakefile', function(exists) {
|
||||
var arg, args, _i, _len, _ref, _results;
|
||||
if (!exists) {
|
||||
throw new Error("Cakefile not found in " + (process.cwd()));
|
||||
}
|
||||
args = process.argv.slice(2);
|
||||
CoffeeScript.run(fs.readFileSync('Cakefile').toString(), {
|
||||
filename: 'Cakefile'
|
||||
});
|
||||
oparse = new optparse.OptionParser(switches);
|
||||
if (!args.length) {
|
||||
return printTasks();
|
||||
}
|
||||
options = oparse.parse(args);
|
||||
_ref = options.arguments;
|
||||
_results = [];
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
arg = _ref[_i];
|
||||
_results.push(invoke(arg));
|
||||
}
|
||||
return _results;
|
||||
});
|
||||
};
|
||||
printTasks = function() {
|
||||
var desc, name, spaces, task;
|
||||
console.log('');
|
||||
for (name in tasks) {
|
||||
task = tasks[name];
|
||||
spaces = 20 - name.length;
|
||||
spaces = spaces > 0 ? Array(spaces + 1).join(' ') : '';
|
||||
desc = task.description ? "# " + task.description : '';
|
||||
console.log("cake " + name + spaces + " " + desc);
|
||||
}
|
||||
if (switches.length) {
|
||||
return console.log(oparse.help());
|
||||
}
|
||||
};
|
||||
missingTask = function(task) {
|
||||
console.log("No such task: \"" + task + "\"");
|
||||
return process.exit(1);
|
||||
};
|
||||
}).call(this);
|
||||
135
bin/node_modules/coffee-script/lib/coffee-script.js
generated
vendored
135
bin/node_modules/coffee-script/lib/coffee-script.js
generated
vendored
@@ -1,135 +0,0 @@
|
||||
(function() {
|
||||
var Lexer, RESERVED, compile, fs, lexer, parser, path, _ref;
|
||||
var __hasProp = Object.prototype.hasOwnProperty;
|
||||
fs = require('fs');
|
||||
path = require('path');
|
||||
_ref = require('./lexer'), Lexer = _ref.Lexer, RESERVED = _ref.RESERVED;
|
||||
parser = require('./parser').parser;
|
||||
if (require.extensions) {
|
||||
require.extensions['.coffee'] = function(module, filename) {
|
||||
var content;
|
||||
content = compile(fs.readFileSync(filename, 'utf8'), {
|
||||
filename: filename
|
||||
});
|
||||
return module._compile(content, filename);
|
||||
};
|
||||
} else if (require.registerExtension) {
|
||||
require.registerExtension('.coffee', function(content) {
|
||||
return compile(content);
|
||||
});
|
||||
}
|
||||
exports.VERSION = '1.1.2';
|
||||
exports.RESERVED = RESERVED;
|
||||
exports.helpers = require('./helpers');
|
||||
exports.compile = compile = function(code, options) {
|
||||
if (options == null) {
|
||||
options = {};
|
||||
}
|
||||
try {
|
||||
return (parser.parse(lexer.tokenize(code))).compile(options);
|
||||
} catch (err) {
|
||||
if (options.filename) {
|
||||
err.message = "In " + options.filename + ", " + err.message;
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
exports.tokens = function(code, options) {
|
||||
return lexer.tokenize(code, options);
|
||||
};
|
||||
exports.nodes = function(source, options) {
|
||||
if (typeof source === 'string') {
|
||||
return parser.parse(lexer.tokenize(source, options));
|
||||
} else {
|
||||
return parser.parse(source);
|
||||
}
|
||||
};
|
||||
exports.run = function(code, options) {
|
||||
var Module, mainModule;
|
||||
mainModule = require.main;
|
||||
mainModule.filename = process.argv[1] = options.filename ? fs.realpathSync(options.filename) : '.';
|
||||
mainModule.moduleCache && (mainModule.moduleCache = {});
|
||||
if (process.binding('natives').module) {
|
||||
Module = require('module').Module;
|
||||
mainModule.paths = Module._nodeModulePaths(path.dirname(options.filename));
|
||||
}
|
||||
if (path.extname(mainModule.filename) !== '.coffee' || require.extensions) {
|
||||
return mainModule._compile(compile(code, options), mainModule.filename);
|
||||
} else {
|
||||
return mainModule._compile(code, mainModule.filename);
|
||||
}
|
||||
};
|
||||
exports.eval = function(code, options) {
|
||||
var Module, Script, js, k, o, r, sandbox, v, _i, _len, _module, _ref2, _ref3, _ref4, _require;
|
||||
if (options == null) {
|
||||
options = {};
|
||||
}
|
||||
if (!(code = code.trim())) {
|
||||
return;
|
||||
}
|
||||
if (_ref2 = require('vm'), Script = _ref2.Script, _ref2) {
|
||||
sandbox = Script.createContext();
|
||||
sandbox.global = sandbox.root = sandbox.GLOBAL = sandbox;
|
||||
if (options.sandbox != null) {
|
||||
if (options.sandbox instanceof sandbox.constructor) {
|
||||
sandbox = options.sandbox;
|
||||
} else {
|
||||
_ref3 = options.sandbox;
|
||||
for (k in _ref3) {
|
||||
if (!__hasProp.call(_ref3, k)) continue;
|
||||
v = _ref3[k];
|
||||
sandbox[k] = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
sandbox.__filename = options.filename || 'eval';
|
||||
sandbox.__dirname = path.dirname(sandbox.__filename);
|
||||
if (!(sandbox.module || sandbox.require)) {
|
||||
Module = require('module');
|
||||
sandbox.module = _module = new Module(options.modulename || 'eval');
|
||||
sandbox.require = _require = function(path) {
|
||||
return Module._load(path, _module);
|
||||
};
|
||||
_module.filename = sandbox.__filename;
|
||||
_ref4 = Object.getOwnPropertyNames(require);
|
||||
for (_i = 0, _len = _ref4.length; _i < _len; _i++) {
|
||||
r = _ref4[_i];
|
||||
_require[r] = require[r];
|
||||
}
|
||||
_require.paths = _module.paths = Module._nodeModulePaths(process.cwd());
|
||||
_require.resolve = function(request) {
|
||||
return Module._resolveFilename(request, _module);
|
||||
};
|
||||
}
|
||||
}
|
||||
o = {};
|
||||
for (k in options) {
|
||||
if (!__hasProp.call(options, k)) continue;
|
||||
v = options[k];
|
||||
o[k] = v;
|
||||
}
|
||||
o.bare = true;
|
||||
js = compile(code, o);
|
||||
if (Script) {
|
||||
return Script.runInContext(js, sandbox);
|
||||
} else {
|
||||
return eval(js);
|
||||
}
|
||||
};
|
||||
lexer = new Lexer;
|
||||
parser.lexer = {
|
||||
lex: function() {
|
||||
var tag, _ref2;
|
||||
_ref2 = this.tokens[this.pos++] || [''], tag = _ref2[0], this.yytext = _ref2[1], this.yylineno = _ref2[2];
|
||||
return tag;
|
||||
},
|
||||
setInput: function(tokens) {
|
||||
this.tokens = tokens;
|
||||
return this.pos = 0;
|
||||
},
|
||||
upcomingInput: function() {
|
||||
return "";
|
||||
}
|
||||
};
|
||||
parser.yy = require('./nodes');
|
||||
}).call(this);
|
||||
301
bin/node_modules/coffee-script/lib/command.js
generated
vendored
301
bin/node_modules/coffee-script/lib/command.js
generated
vendored
@@ -1,301 +0,0 @@
|
||||
(function() {
|
||||
var BANNER, CoffeeScript, EventEmitter, SWITCHES, compileJoin, compileOptions, compileScript, compileScripts, compileStdio, contents, exec, forkNode, fs, helpers, lint, loadRequires, optionParser, optparse, opts, parseOptions, path, printLine, printTokens, printWarn, sources, spawn, usage, version, watch, writeJs, _ref;
|
||||
fs = require('fs');
|
||||
path = require('path');
|
||||
helpers = require('./helpers');
|
||||
optparse = require('./optparse');
|
||||
CoffeeScript = require('./coffee-script');
|
||||
_ref = require('child_process'), spawn = _ref.spawn, exec = _ref.exec;
|
||||
EventEmitter = require('events').EventEmitter;
|
||||
helpers.extend(CoffeeScript, new EventEmitter);
|
||||
printLine = function(line) {
|
||||
return process.stdout.write(line + '\n');
|
||||
};
|
||||
printWarn = function(line) {
|
||||
return process.binding('stdio').writeError(line + '\n');
|
||||
};
|
||||
BANNER = 'Usage: coffee [options] path/to/script.coffee';
|
||||
SWITCHES = [['-c', '--compile', 'compile to JavaScript and save as .js files'], ['-i', '--interactive', 'run an interactive CoffeeScript REPL'], ['-o', '--output [DIR]', 'set the directory for compiled JavaScript'], ['-j', '--join [FILE]', 'concatenate the scripts before compiling'], ['-w', '--watch', 'watch scripts for changes, and recompile'], ['-p', '--print', 'print the compiled JavaScript to stdout'], ['-l', '--lint', 'pipe the compiled JavaScript through JavaScript Lint'], ['-s', '--stdio', 'listen for and compile scripts over stdio'], ['-e', '--eval', 'compile a string from the command line'], ['-r', '--require [FILE*]', 'require a library before executing your script'], ['-b', '--bare', 'compile without the top-level function wrapper'], ['-t', '--tokens', 'print the tokens that the lexer produces'], ['-n', '--nodes', 'print the parse tree that Jison produces'], ['--nodejs [ARGS]', 'pass options through to the "node" binary'], ['-v', '--version', 'display CoffeeScript version'], ['-h', '--help', 'display this help message']];
|
||||
opts = {};
|
||||
sources = [];
|
||||
contents = [];
|
||||
optionParser = null;
|
||||
exports.run = function() {
|
||||
parseOptions();
|
||||
if (opts.nodejs) {
|
||||
return forkNode();
|
||||
}
|
||||
if (opts.help) {
|
||||
return usage();
|
||||
}
|
||||
if (opts.version) {
|
||||
return version();
|
||||
}
|
||||
if (opts.require) {
|
||||
loadRequires();
|
||||
}
|
||||
if (opts.interactive) {
|
||||
return require('./repl');
|
||||
}
|
||||
if (opts.stdio) {
|
||||
return compileStdio();
|
||||
}
|
||||
if (opts.eval) {
|
||||
return compileScript(null, sources[0]);
|
||||
}
|
||||
if (!sources.length) {
|
||||
return require('./repl');
|
||||
}
|
||||
if (opts.run) {
|
||||
opts.literals = sources.splice(1).concat(opts.literals);
|
||||
}
|
||||
process.ARGV = process.argv = process.argv.slice(0, 2).concat(opts.literals);
|
||||
process.argv[0] = 'coffee';
|
||||
process.execPath = require.main.filename;
|
||||
return compileScripts();
|
||||
};
|
||||
compileScripts = function() {
|
||||
var base, compile, source, unprocessed, _i, _j, _len, _len2, _results;
|
||||
unprocessed = [];
|
||||
for (_i = 0, _len = sources.length; _i < _len; _i++) {
|
||||
source = sources[_i];
|
||||
unprocessed[sources.indexOf(source)] = 1;
|
||||
}
|
||||
_results = [];
|
||||
for (_j = 0, _len2 = sources.length; _j < _len2; _j++) {
|
||||
source = sources[_j];
|
||||
base = path.join(source);
|
||||
compile = function(source, sourceIndex, topLevel) {
|
||||
var remaining_files;
|
||||
remaining_files = function() {
|
||||
var total, x, _k, _len3;
|
||||
total = 0;
|
||||
for (_k = 0, _len3 = unprocessed.length; _k < _len3; _k++) {
|
||||
x = unprocessed[_k];
|
||||
total += x;
|
||||
}
|
||||
return total;
|
||||
};
|
||||
return path.exists(source, function(exists) {
|
||||
if (topLevel && !exists && source.slice(-7) !== '.coffee') {
|
||||
return compile("" + source + ".coffee", sourceIndex, topLevel);
|
||||
}
|
||||
if (topLevel && !exists) {
|
||||
throw new Error("File not found: " + source);
|
||||
}
|
||||
return fs.stat(source, function(err, stats) {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
if (stats.isDirectory()) {
|
||||
return fs.readdir(source, function(err, files) {
|
||||
var file, _k, _len3;
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
unprocessed[sourceIndex] += files.length;
|
||||
for (_k = 0, _len3 = files.length; _k < _len3; _k++) {
|
||||
file = files[_k];
|
||||
compile(path.join(source, file), sourceIndex);
|
||||
}
|
||||
return unprocessed[sourceIndex] -= 1;
|
||||
});
|
||||
} else if (topLevel || path.extname(source) === '.coffee') {
|
||||
fs.readFile(source, function(err, code) {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
unprocessed[sourceIndex] -= 1;
|
||||
if (opts.join) {
|
||||
contents[sourceIndex] = helpers.compact([contents[sourceIndex], code.toString()]).join('\n');
|
||||
if (helpers.compact(contents).length > 0 && remaining_files() === 0) {
|
||||
return compileJoin();
|
||||
}
|
||||
} else {
|
||||
return compileScript(source, code.toString(), base);
|
||||
}
|
||||
});
|
||||
if (opts.watch && !opts.join) {
|
||||
return watch(source, base);
|
||||
}
|
||||
} else {
|
||||
return unprocessed[sourceIndex] -= 1;
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
_results.push(compile(source, sources.indexOf(source), true));
|
||||
}
|
||||
return _results;
|
||||
};
|
||||
compileScript = function(file, input, base) {
|
||||
var o, options, t, task;
|
||||
o = opts;
|
||||
options = compileOptions(file);
|
||||
try {
|
||||
t = task = {
|
||||
file: file,
|
||||
input: input,
|
||||
options: options
|
||||
};
|
||||
CoffeeScript.emit('compile', task);
|
||||
if (o.tokens) {
|
||||
return printTokens(CoffeeScript.tokens(t.input));
|
||||
} else if (o.nodes) {
|
||||
return printLine(CoffeeScript.nodes(t.input).toString().trim());
|
||||
} else if (o.run) {
|
||||
return CoffeeScript.run(t.input, t.options);
|
||||
} else {
|
||||
t.output = CoffeeScript.compile(t.input, t.options);
|
||||
CoffeeScript.emit('success', task);
|
||||
if (o.print) {
|
||||
return printLine(t.output.trim());
|
||||
} else if (o.compile) {
|
||||
return writeJs(t.file, t.output, base);
|
||||
} else if (o.lint) {
|
||||
return lint(t.file, t.output);
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
CoffeeScript.emit('failure', err, task);
|
||||
if (CoffeeScript.listeners('failure').length) {
|
||||
return;
|
||||
}
|
||||
if (o.watch) {
|
||||
return printLine(err.message);
|
||||
}
|
||||
printWarn(err.stack);
|
||||
return process.exit(1);
|
||||
}
|
||||
};
|
||||
compileStdio = function() {
|
||||
var code, stdin;
|
||||
code = '';
|
||||
stdin = process.openStdin();
|
||||
stdin.on('data', function(buffer) {
|
||||
if (buffer) {
|
||||
return code += buffer.toString();
|
||||
}
|
||||
});
|
||||
return stdin.on('end', function() {
|
||||
return compileScript(null, code);
|
||||
});
|
||||
};
|
||||
compileJoin = function() {
|
||||
var code;
|
||||
code = contents.join('\n');
|
||||
return compileScript(opts.join, code, opts.join);
|
||||
};
|
||||
loadRequires = function() {
|
||||
var realFilename, req, _i, _len, _ref2;
|
||||
realFilename = module.filename;
|
||||
module.filename = '.';
|
||||
_ref2 = opts.require;
|
||||
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
||||
req = _ref2[_i];
|
||||
require(req);
|
||||
}
|
||||
return module.filename = realFilename;
|
||||
};
|
||||
watch = function(source, base) {
|
||||
return fs.watchFile(source, {
|
||||
persistent: true,
|
||||
interval: 500
|
||||
}, function(curr, prev) {
|
||||
if (curr.size === prev.size && curr.mtime.getTime() === prev.mtime.getTime()) {
|
||||
return;
|
||||
}
|
||||
return fs.readFile(source, function(err, code) {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
return compileScript(source, code.toString(), base);
|
||||
});
|
||||
});
|
||||
};
|
||||
writeJs = function(source, js, base) {
|
||||
var baseDir, compile, dir, filename, jsPath, srcDir;
|
||||
filename = path.basename(source, path.extname(source)) + '.js';
|
||||
srcDir = path.dirname(source);
|
||||
baseDir = base === '.' ? srcDir : srcDir.substring(base.length);
|
||||
dir = opts.output ? path.join(opts.output, baseDir) : srcDir;
|
||||
jsPath = path.join(dir, filename);
|
||||
compile = function() {
|
||||
if (js.length <= 0) {
|
||||
js = ' ';
|
||||
}
|
||||
return fs.writeFile(jsPath, js, function(err) {
|
||||
if (err) {
|
||||
return printLine(err.message);
|
||||
} else if (opts.compile && opts.watch) {
|
||||
return console.log("" + ((new Date).toLocaleTimeString()) + " - compiled " + source);
|
||||
}
|
||||
});
|
||||
};
|
||||
return path.exists(dir, function(exists) {
|
||||
if (exists) {
|
||||
return compile();
|
||||
} else {
|
||||
return exec("mkdir -p " + dir, compile);
|
||||
}
|
||||
});
|
||||
};
|
||||
lint = function(file, js) {
|
||||
var conf, jsl, printIt;
|
||||
printIt = function(buffer) {
|
||||
return printLine(file + ':\t' + buffer.toString().trim());
|
||||
};
|
||||
conf = __dirname + '/../extras/jsl.conf';
|
||||
jsl = spawn('jsl', ['-nologo', '-stdin', '-conf', conf]);
|
||||
jsl.stdout.on('data', printIt);
|
||||
jsl.stderr.on('data', printIt);
|
||||
jsl.stdin.write(js);
|
||||
return jsl.stdin.end();
|
||||
};
|
||||
printTokens = function(tokens) {
|
||||
var strings, tag, token, value;
|
||||
strings = (function() {
|
||||
var _i, _len, _ref2, _results;
|
||||
_results = [];
|
||||
for (_i = 0, _len = tokens.length; _i < _len; _i++) {
|
||||
token = tokens[_i];
|
||||
_ref2 = [token[0], token[1].toString().replace(/\n/, '\\n')], tag = _ref2[0], value = _ref2[1];
|
||||
_results.push("[" + tag + " " + value + "]");
|
||||
}
|
||||
return _results;
|
||||
})();
|
||||
return printLine(strings.join(' '));
|
||||
};
|
||||
parseOptions = function() {
|
||||
var o;
|
||||
optionParser = new optparse.OptionParser(SWITCHES, BANNER);
|
||||
o = opts = optionParser.parse(process.argv.slice(2));
|
||||
o.compile || (o.compile = !!o.output);
|
||||
o.run = !(o.compile || o.print || o.lint);
|
||||
o.print = !!(o.print || (o.eval || o.stdio && o.compile));
|
||||
return sources = o.arguments;
|
||||
};
|
||||
compileOptions = function(filename) {
|
||||
return {
|
||||
filename: filename,
|
||||
bare: opts.bare
|
||||
};
|
||||
};
|
||||
forkNode = function() {
|
||||
var args, nodeArgs;
|
||||
nodeArgs = opts.nodejs.split(/\s+/);
|
||||
args = process.argv.slice(1);
|
||||
args.splice(args.indexOf('--nodejs'), 2);
|
||||
return spawn(process.execPath, nodeArgs.concat(args), {
|
||||
cwd: process.cwd(),
|
||||
env: process.env,
|
||||
customFds: [0, 1, 2]
|
||||
});
|
||||
};
|
||||
usage = function() {
|
||||
return printLine((new optparse.OptionParser(SWITCHES, BANNER)).help());
|
||||
};
|
||||
version = function() {
|
||||
return printLine("CoffeeScript version " + CoffeeScript.VERSION);
|
||||
};
|
||||
}).call(this);
|
||||
591
bin/node_modules/coffee-script/lib/grammar.js
generated
vendored
591
bin/node_modules/coffee-script/lib/grammar.js
generated
vendored
@@ -1,591 +0,0 @@
|
||||
(function() {
|
||||
var Parser, alt, alternatives, grammar, name, o, operators, token, tokens, unwrap;
|
||||
Parser = require('jison').Parser;
|
||||
unwrap = /^function\s*\(\)\s*\{\s*return\s*([\s\S]*);\s*\}/;
|
||||
o = function(patternString, action, options) {
|
||||
var match;
|
||||
patternString = patternString.replace(/\s{2,}/g, ' ');
|
||||
if (!action) {
|
||||
return [patternString, '$$ = $1;', options];
|
||||
}
|
||||
action = (match = unwrap.exec(action)) ? match[1] : "(" + action + "())";
|
||||
action = action.replace(/\bnew /g, '$&yy.');
|
||||
action = action.replace(/\b(?:Block\.wrap|extend)\b/g, 'yy.$&');
|
||||
return [patternString, "$$ = " + action + ";", options];
|
||||
};
|
||||
grammar = {
|
||||
Root: [
|
||||
o('', function() {
|
||||
return new Block;
|
||||
}), o('Body'), o('Block TERMINATOR')
|
||||
],
|
||||
Body: [
|
||||
o('Line', function() {
|
||||
return Block.wrap([$1]);
|
||||
}), o('Body TERMINATOR Line', function() {
|
||||
return $1.push($3);
|
||||
}), o('Body TERMINATOR')
|
||||
],
|
||||
Line: [o('Expression'), o('Statement')],
|
||||
Statement: [
|
||||
o('Return'), o('Throw'), o('Comment'), o('STATEMENT', function() {
|
||||
return new Literal($1);
|
||||
})
|
||||
],
|
||||
Expression: [o('Value'), o('Invocation'), o('Code'), o('Operation'), o('Assign'), o('If'), o('Try'), o('While'), o('For'), o('Switch'), o('Class')],
|
||||
Block: [
|
||||
o('INDENT OUTDENT', function() {
|
||||
return new Block;
|
||||
}), o('INDENT Body OUTDENT', function() {
|
||||
return $2;
|
||||
})
|
||||
],
|
||||
Identifier: [
|
||||
o('IDENTIFIER', function() {
|
||||
return new Literal($1);
|
||||
})
|
||||
],
|
||||
AlphaNumeric: [
|
||||
o('NUMBER', function() {
|
||||
return new Literal($1);
|
||||
}), o('STRING', function() {
|
||||
return new Literal($1);
|
||||
})
|
||||
],
|
||||
Literal: [
|
||||
o('AlphaNumeric'), o('JS', function() {
|
||||
return new Literal($1);
|
||||
}), o('REGEX', function() {
|
||||
return new Literal($1);
|
||||
}), o('BOOL', function() {
|
||||
var val;
|
||||
val = new Literal($1);
|
||||
if ($1 === 'undefined') {
|
||||
val.isUndefined = true;
|
||||
}
|
||||
return val;
|
||||
})
|
||||
],
|
||||
Assign: [
|
||||
o('Assignable = Expression', function() {
|
||||
return new Assign($1, $3);
|
||||
}), o('Assignable = INDENT Expression OUTDENT', function() {
|
||||
return new Assign($1, $4);
|
||||
})
|
||||
],
|
||||
AssignObj: [
|
||||
o('ObjAssignable', function() {
|
||||
return new Value($1);
|
||||
}), o('ObjAssignable : Expression', function() {
|
||||
return new Assign(new Value($1), $3, 'object');
|
||||
}), o('ObjAssignable :\
|
||||
INDENT Expression OUTDENT', function() {
|
||||
return new Assign(new Value($1), $4, 'object');
|
||||
}), o('Comment')
|
||||
],
|
||||
ObjAssignable: [o('Identifier'), o('AlphaNumeric'), o('ThisProperty')],
|
||||
Return: [
|
||||
o('RETURN Expression', function() {
|
||||
return new Return($2);
|
||||
}), o('RETURN', function() {
|
||||
return new Return;
|
||||
})
|
||||
],
|
||||
Comment: [
|
||||
o('HERECOMMENT', function() {
|
||||
return new Comment($1);
|
||||
})
|
||||
],
|
||||
Code: [
|
||||
o('PARAM_START ParamList PARAM_END FuncGlyph Block', function() {
|
||||
return new Code($2, $5, $4);
|
||||
}), o('FuncGlyph Block', function() {
|
||||
return new Code([], $2, $1);
|
||||
})
|
||||
],
|
||||
FuncGlyph: [
|
||||
o('->', function() {
|
||||
return 'func';
|
||||
}), o('=>', function() {
|
||||
return 'boundfunc';
|
||||
})
|
||||
],
|
||||
OptComma: [o(''), o(',')],
|
||||
ParamList: [
|
||||
o('', function() {
|
||||
return [];
|
||||
}), o('Param', function() {
|
||||
return [$1];
|
||||
}), o('ParamList , Param', function() {
|
||||
return $1.concat($3);
|
||||
})
|
||||
],
|
||||
Param: [
|
||||
o('ParamVar', function() {
|
||||
return new Param($1);
|
||||
}), o('ParamVar ...', function() {
|
||||
return new Param($1, null, true);
|
||||
}), o('ParamVar = Expression', function() {
|
||||
return new Param($1, $3);
|
||||
})
|
||||
],
|
||||
ParamVar: [o('Identifier'), o('ThisProperty'), o('Array'), o('Object')],
|
||||
Splat: [
|
||||
o('Expression ...', function() {
|
||||
return new Splat($1);
|
||||
})
|
||||
],
|
||||
SimpleAssignable: [
|
||||
o('Identifier', function() {
|
||||
return new Value($1);
|
||||
}), o('Value Accessor', function() {
|
||||
return $1.push($2);
|
||||
}), o('Invocation Accessor', function() {
|
||||
return new Value($1, [$2]);
|
||||
}), o('ThisProperty')
|
||||
],
|
||||
Assignable: [
|
||||
o('SimpleAssignable'), o('Array', function() {
|
||||
return new Value($1);
|
||||
}), o('Object', function() {
|
||||
return new Value($1);
|
||||
})
|
||||
],
|
||||
Value: [
|
||||
o('Assignable'), o('Literal', function() {
|
||||
return new Value($1);
|
||||
}), o('Parenthetical', function() {
|
||||
return new Value($1);
|
||||
}), o('Range', function() {
|
||||
return new Value($1);
|
||||
}), o('This')
|
||||
],
|
||||
Accessor: [
|
||||
o('. Identifier', function() {
|
||||
return new Access($2);
|
||||
}), o('?. Identifier', function() {
|
||||
return new Access($2, 'soak');
|
||||
}), o(':: Identifier', function() {
|
||||
return new Access($2, 'proto');
|
||||
}), o('::', function() {
|
||||
return new Access(new Literal('prototype'));
|
||||
}), o('Index')
|
||||
],
|
||||
Index: [
|
||||
o('INDEX_START IndexValue INDEX_END', function() {
|
||||
return $2;
|
||||
}), o('INDEX_SOAK Index', function() {
|
||||
return extend($2, {
|
||||
soak: true
|
||||
});
|
||||
}), o('INDEX_PROTO Index', function() {
|
||||
return extend($2, {
|
||||
proto: true
|
||||
});
|
||||
})
|
||||
],
|
||||
IndexValue: [
|
||||
o('Expression', function() {
|
||||
return new Index($1);
|
||||
}), o('Slice', function() {
|
||||
return new Slice($1);
|
||||
})
|
||||
],
|
||||
Object: [
|
||||
o('{ AssignList OptComma }', function() {
|
||||
return new Obj($2, $1.generated);
|
||||
})
|
||||
],
|
||||
AssignList: [
|
||||
o('', function() {
|
||||
return [];
|
||||
}), o('AssignObj', function() {
|
||||
return [$1];
|
||||
}), o('AssignList , AssignObj', function() {
|
||||
return $1.concat($3);
|
||||
}), o('AssignList OptComma TERMINATOR AssignObj', function() {
|
||||
return $1.concat($4);
|
||||
}), o('AssignList OptComma INDENT AssignList OptComma OUTDENT', function() {
|
||||
return $1.concat($4);
|
||||
})
|
||||
],
|
||||
Class: [
|
||||
o('CLASS', function() {
|
||||
return new Class;
|
||||
}), o('CLASS Block', function() {
|
||||
return new Class(null, null, $2);
|
||||
}), o('CLASS EXTENDS Value', function() {
|
||||
return new Class(null, $3);
|
||||
}), o('CLASS EXTENDS Value Block', function() {
|
||||
return new Class(null, $3, $4);
|
||||
}), o('CLASS SimpleAssignable', function() {
|
||||
return new Class($2);
|
||||
}), o('CLASS SimpleAssignable Block', function() {
|
||||
return new Class($2, null, $3);
|
||||
}), o('CLASS SimpleAssignable EXTENDS Value', function() {
|
||||
return new Class($2, $4);
|
||||
}), o('CLASS SimpleAssignable EXTENDS Value Block', function() {
|
||||
return new Class($2, $4, $5);
|
||||
})
|
||||
],
|
||||
Invocation: [
|
||||
o('Value OptFuncExist Arguments', function() {
|
||||
return new Call($1, $3, $2);
|
||||
}), o('Invocation OptFuncExist Arguments', function() {
|
||||
return new Call($1, $3, $2);
|
||||
}), o('SUPER', function() {
|
||||
return new Call('super', [new Splat(new Literal('arguments'))]);
|
||||
}), o('SUPER Arguments', function() {
|
||||
return new Call('super', $2);
|
||||
})
|
||||
],
|
||||
OptFuncExist: [
|
||||
o('', function() {
|
||||
return false;
|
||||
}), o('FUNC_EXIST', function() {
|
||||
return true;
|
||||
})
|
||||
],
|
||||
Arguments: [
|
||||
o('CALL_START CALL_END', function() {
|
||||
return [];
|
||||
}), o('CALL_START ArgList OptComma CALL_END', function() {
|
||||
return $2;
|
||||
})
|
||||
],
|
||||
This: [
|
||||
o('THIS', function() {
|
||||
return new Value(new Literal('this'));
|
||||
}), o('@', function() {
|
||||
return new Value(new Literal('this'));
|
||||
})
|
||||
],
|
||||
ThisProperty: [
|
||||
o('@ Identifier', function() {
|
||||
return new Value(new Literal('this'), [new Access($2)], 'this');
|
||||
})
|
||||
],
|
||||
Array: [
|
||||
o('[ ]', function() {
|
||||
return new Arr([]);
|
||||
}), o('[ ArgList OptComma ]', function() {
|
||||
return new Arr($2);
|
||||
})
|
||||
],
|
||||
RangeDots: [
|
||||
o('..', function() {
|
||||
return 'inclusive';
|
||||
}), o('...', function() {
|
||||
return 'exclusive';
|
||||
})
|
||||
],
|
||||
Range: [
|
||||
o('[ Expression RangeDots Expression ]', function() {
|
||||
return new Range($2, $4, $3);
|
||||
})
|
||||
],
|
||||
Slice: [
|
||||
o('Expression RangeDots Expression', function() {
|
||||
return new Range($1, $3, $2);
|
||||
}), o('Expression RangeDots', function() {
|
||||
return new Range($1, null, $2);
|
||||
}), o('RangeDots Expression', function() {
|
||||
return new Range(null, $2, $1);
|
||||
})
|
||||
],
|
||||
ArgList: [
|
||||
o('Arg', function() {
|
||||
return [$1];
|
||||
}), o('ArgList , Arg', function() {
|
||||
return $1.concat($3);
|
||||
}), o('ArgList OptComma TERMINATOR Arg', function() {
|
||||
return $1.concat($4);
|
||||
}), o('INDENT ArgList OptComma OUTDENT', function() {
|
||||
return $2;
|
||||
}), o('ArgList OptComma INDENT ArgList OptComma OUTDENT', function() {
|
||||
return $1.concat($4);
|
||||
})
|
||||
],
|
||||
Arg: [o('Expression'), o('Splat')],
|
||||
SimpleArgs: [
|
||||
o('Expression'), o('SimpleArgs , Expression', function() {
|
||||
return [].concat($1, $3);
|
||||
})
|
||||
],
|
||||
Try: [
|
||||
o('TRY Block', function() {
|
||||
return new Try($2);
|
||||
}), o('TRY Block Catch', function() {
|
||||
return new Try($2, $3[0], $3[1]);
|
||||
}), o('TRY Block FINALLY Block', function() {
|
||||
return new Try($2, null, null, $4);
|
||||
}), o('TRY Block Catch FINALLY Block', function() {
|
||||
return new Try($2, $3[0], $3[1], $5);
|
||||
})
|
||||
],
|
||||
Catch: [
|
||||
o('CATCH Identifier Block', function() {
|
||||
return [$2, $3];
|
||||
})
|
||||
],
|
||||
Throw: [
|
||||
o('THROW Expression', function() {
|
||||
return new Throw($2);
|
||||
})
|
||||
],
|
||||
Parenthetical: [
|
||||
o('( Body )', function() {
|
||||
return new Parens($2);
|
||||
}), o('( INDENT Body OUTDENT )', function() {
|
||||
return new Parens($3);
|
||||
})
|
||||
],
|
||||
WhileSource: [
|
||||
o('WHILE Expression', function() {
|
||||
return new While($2);
|
||||
}), o('WHILE Expression WHEN Expression', function() {
|
||||
return new While($2, {
|
||||
guard: $4
|
||||
});
|
||||
}), o('UNTIL Expression', function() {
|
||||
return new While($2, {
|
||||
invert: true
|
||||
});
|
||||
}), o('UNTIL Expression WHEN Expression', function() {
|
||||
return new While($2, {
|
||||
invert: true,
|
||||
guard: $4
|
||||
});
|
||||
})
|
||||
],
|
||||
While: [
|
||||
o('WhileSource Block', function() {
|
||||
return $1.addBody($2);
|
||||
}), o('Statement WhileSource', function() {
|
||||
return $2.addBody(Block.wrap([$1]));
|
||||
}), o('Expression WhileSource', function() {
|
||||
return $2.addBody(Block.wrap([$1]));
|
||||
}), o('Loop', function() {
|
||||
return $1;
|
||||
})
|
||||
],
|
||||
Loop: [
|
||||
o('LOOP Block', function() {
|
||||
return new While(new Literal('true')).addBody($2);
|
||||
}), o('LOOP Expression', function() {
|
||||
return new While(new Literal('true')).addBody(Block.wrap([$2]));
|
||||
})
|
||||
],
|
||||
For: [
|
||||
o('Statement ForBody', function() {
|
||||
return new For($1, $2);
|
||||
}), o('Expression ForBody', function() {
|
||||
return new For($1, $2);
|
||||
}), o('ForBody Block', function() {
|
||||
return new For($2, $1);
|
||||
})
|
||||
],
|
||||
ForBody: [
|
||||
o('FOR Range', function() {
|
||||
return {
|
||||
source: new Value($2)
|
||||
};
|
||||
}), o('ForStart ForSource', function() {
|
||||
$2.own = $1.own;
|
||||
$2.name = $1[0];
|
||||
$2.index = $1[1];
|
||||
return $2;
|
||||
})
|
||||
],
|
||||
ForStart: [
|
||||
o('FOR ForVariables', function() {
|
||||
return $2;
|
||||
}), o('FOR OWN ForVariables', function() {
|
||||
$3.own = true;
|
||||
return $3;
|
||||
})
|
||||
],
|
||||
ForValue: [
|
||||
o('Identifier'), o('Array', function() {
|
||||
return new Value($1);
|
||||
}), o('Object', function() {
|
||||
return new Value($1);
|
||||
})
|
||||
],
|
||||
ForVariables: [
|
||||
o('ForValue', function() {
|
||||
return [$1];
|
||||
}), o('ForValue , ForValue', function() {
|
||||
return [$1, $3];
|
||||
})
|
||||
],
|
||||
ForSource: [
|
||||
o('FORIN Expression', function() {
|
||||
return {
|
||||
source: $2
|
||||
};
|
||||
}), o('FOROF Expression', function() {
|
||||
return {
|
||||
source: $2,
|
||||
object: true
|
||||
};
|
||||
}), o('FORIN Expression WHEN Expression', function() {
|
||||
return {
|
||||
source: $2,
|
||||
guard: $4
|
||||
};
|
||||
}), o('FOROF Expression WHEN Expression', function() {
|
||||
return {
|
||||
source: $2,
|
||||
guard: $4,
|
||||
object: true
|
||||
};
|
||||
}), o('FORIN Expression BY Expression', function() {
|
||||
return {
|
||||
source: $2,
|
||||
step: $4
|
||||
};
|
||||
}), o('FORIN Expression WHEN Expression BY Expression', function() {
|
||||
return {
|
||||
source: $2,
|
||||
guard: $4,
|
||||
step: $6
|
||||
};
|
||||
}), o('FORIN Expression BY Expression WHEN Expression', function() {
|
||||
return {
|
||||
source: $2,
|
||||
step: $4,
|
||||
guard: $6
|
||||
};
|
||||
})
|
||||
],
|
||||
Switch: [
|
||||
o('SWITCH Expression INDENT Whens OUTDENT', function() {
|
||||
return new Switch($2, $4);
|
||||
}), o('SWITCH Expression INDENT Whens ELSE Block OUTDENT', function() {
|
||||
return new Switch($2, $4, $6);
|
||||
}), o('SWITCH INDENT Whens OUTDENT', function() {
|
||||
return new Switch(null, $3);
|
||||
}), o('SWITCH INDENT Whens ELSE Block OUTDENT', function() {
|
||||
return new Switch(null, $3, $5);
|
||||
})
|
||||
],
|
||||
Whens: [
|
||||
o('When'), o('Whens When', function() {
|
||||
return $1.concat($2);
|
||||
})
|
||||
],
|
||||
When: [
|
||||
o('LEADING_WHEN SimpleArgs Block', function() {
|
||||
return [[$2, $3]];
|
||||
}), o('LEADING_WHEN SimpleArgs Block TERMINATOR', function() {
|
||||
return [[$2, $3]];
|
||||
})
|
||||
],
|
||||
IfBlock: [
|
||||
o('IF Expression Block', function() {
|
||||
return new If($2, $3, {
|
||||
type: $1
|
||||
});
|
||||
}), o('IfBlock ELSE IF Expression Block', function() {
|
||||
return $1.addElse(new If($4, $5, {
|
||||
type: $3
|
||||
}));
|
||||
})
|
||||
],
|
||||
If: [
|
||||
o('IfBlock'), o('IfBlock ELSE Block', function() {
|
||||
return $1.addElse($3);
|
||||
}), o('Statement POST_IF Expression', function() {
|
||||
return new If($3, Block.wrap([$1]), {
|
||||
type: $2,
|
||||
statement: true
|
||||
});
|
||||
}), o('Expression POST_IF Expression', function() {
|
||||
return new If($3, Block.wrap([$1]), {
|
||||
type: $2,
|
||||
statement: true
|
||||
});
|
||||
})
|
||||
],
|
||||
Operation: [
|
||||
o('UNARY Expression', function() {
|
||||
return new Op($1, $2);
|
||||
}), o('- Expression', (function() {
|
||||
return new Op('-', $2);
|
||||
}), {
|
||||
prec: 'UNARY'
|
||||
}), o('+ Expression', (function() {
|
||||
return new Op('+', $2);
|
||||
}), {
|
||||
prec: 'UNARY'
|
||||
}), o('-- SimpleAssignable', function() {
|
||||
return new Op('--', $2);
|
||||
}), o('++ SimpleAssignable', function() {
|
||||
return new Op('++', $2);
|
||||
}), o('SimpleAssignable --', function() {
|
||||
return new Op('--', $1, null, true);
|
||||
}), o('SimpleAssignable ++', function() {
|
||||
return new Op('++', $1, null, true);
|
||||
}), o('Expression ?', function() {
|
||||
return new Existence($1);
|
||||
}), o('Expression + Expression', function() {
|
||||
return new Op('+', $1, $3);
|
||||
}), o('Expression - Expression', function() {
|
||||
return new Op('-', $1, $3);
|
||||
}), o('Expression MATH Expression', function() {
|
||||
return new Op($2, $1, $3);
|
||||
}), o('Expression SHIFT Expression', function() {
|
||||
return new Op($2, $1, $3);
|
||||
}), o('Expression COMPARE Expression', function() {
|
||||
return new Op($2, $1, $3);
|
||||
}), o('Expression LOGIC Expression', function() {
|
||||
return new Op($2, $1, $3);
|
||||
}), o('Expression RELATION Expression', function() {
|
||||
if ($2.charAt(0) === '!') {
|
||||
return new Op($2.slice(1), $1, $3).invert();
|
||||
} else {
|
||||
return new Op($2, $1, $3);
|
||||
}
|
||||
}), o('SimpleAssignable COMPOUND_ASSIGN\
|
||||
Expression', function() {
|
||||
return new Assign($1, $3, $2);
|
||||
}), o('SimpleAssignable COMPOUND_ASSIGN\
|
||||
INDENT Expression OUTDENT', function() {
|
||||
return new Assign($1, $4, $2);
|
||||
}), o('SimpleAssignable EXTENDS Expression', function() {
|
||||
return new Extends($1, $3);
|
||||
})
|
||||
]
|
||||
};
|
||||
operators = [['left', '.', '?.', '::'], ['left', 'CALL_START', 'CALL_END'], ['nonassoc', '++', '--'], ['left', '?'], ['right', 'UNARY'], ['left', 'MATH'], ['left', '+', '-'], ['left', 'SHIFT'], ['left', 'RELATION'], ['left', 'COMPARE'], ['left', 'LOGIC'], ['nonassoc', 'INDENT', 'OUTDENT'], ['right', '=', ':', 'COMPOUND_ASSIGN', 'RETURN', 'THROW', 'EXTENDS'], ['right', 'FORIN', 'FOROF', 'BY', 'WHEN'], ['right', 'IF', 'ELSE', 'FOR', 'DO', 'WHILE', 'UNTIL', 'LOOP', 'SUPER', 'CLASS'], ['right', 'POST_IF']];
|
||||
tokens = [];
|
||||
for (name in grammar) {
|
||||
alternatives = grammar[name];
|
||||
grammar[name] = (function() {
|
||||
var _i, _j, _len, _len2, _ref, _results;
|
||||
_results = [];
|
||||
for (_i = 0, _len = alternatives.length; _i < _len; _i++) {
|
||||
alt = alternatives[_i];
|
||||
_ref = alt[0].split(' ');
|
||||
for (_j = 0, _len2 = _ref.length; _j < _len2; _j++) {
|
||||
token = _ref[_j];
|
||||
if (!grammar[token]) {
|
||||
tokens.push(token);
|
||||
}
|
||||
}
|
||||
if (name === 'Root') {
|
||||
alt[1] = "return " + alt[1];
|
||||
}
|
||||
_results.push(alt);
|
||||
}
|
||||
return _results;
|
||||
})();
|
||||
}
|
||||
exports.parser = new Parser({
|
||||
tokens: tokens.join(' '),
|
||||
bnf: grammar,
|
||||
operators: operators.reverse(),
|
||||
startSymbol: 'Root'
|
||||
});
|
||||
}).call(this);
|
||||
66
bin/node_modules/coffee-script/lib/helpers.js
generated
vendored
66
bin/node_modules/coffee-script/lib/helpers.js
generated
vendored
@@ -1,66 +0,0 @@
|
||||
(function() {
|
||||
var extend, flatten;
|
||||
exports.starts = function(string, literal, start) {
|
||||
return literal === string.substr(start, literal.length);
|
||||
};
|
||||
exports.ends = function(string, literal, back) {
|
||||
var len;
|
||||
len = literal.length;
|
||||
return literal === string.substr(string.length - len - (back || 0), len);
|
||||
};
|
||||
exports.compact = function(array) {
|
||||
var item, _i, _len, _results;
|
||||
_results = [];
|
||||
for (_i = 0, _len = array.length; _i < _len; _i++) {
|
||||
item = array[_i];
|
||||
if (item) {
|
||||
_results.push(item);
|
||||
}
|
||||
}
|
||||
return _results;
|
||||
};
|
||||
exports.count = function(string, substr) {
|
||||
var num, pos;
|
||||
num = pos = 0;
|
||||
if (!substr.length) {
|
||||
return 1 / 0;
|
||||
}
|
||||
while (pos = 1 + string.indexOf(substr, pos)) {
|
||||
num++;
|
||||
}
|
||||
return num;
|
||||
};
|
||||
exports.merge = function(options, overrides) {
|
||||
return extend(extend({}, options), overrides);
|
||||
};
|
||||
extend = exports.extend = function(object, properties) {
|
||||
var key, val;
|
||||
for (key in properties) {
|
||||
val = properties[key];
|
||||
object[key] = val;
|
||||
}
|
||||
return object;
|
||||
};
|
||||
exports.flatten = flatten = function(array) {
|
||||
var element, flattened, _i, _len;
|
||||
flattened = [];
|
||||
for (_i = 0, _len = array.length; _i < _len; _i++) {
|
||||
element = array[_i];
|
||||
if (element instanceof Array) {
|
||||
flattened = flattened.concat(flatten(element));
|
||||
} else {
|
||||
flattened.push(element);
|
||||
}
|
||||
}
|
||||
return flattened;
|
||||
};
|
||||
exports.del = function(obj, key) {
|
||||
var val;
|
||||
val = obj[key];
|
||||
delete obj[key];
|
||||
return val;
|
||||
};
|
||||
exports.last = function(array, back) {
|
||||
return array[array.length - (back || 0) - 1];
|
||||
};
|
||||
}).call(this);
|
||||
8
bin/node_modules/coffee-script/lib/index.js
generated
vendored
8
bin/node_modules/coffee-script/lib/index.js
generated
vendored
@@ -1,8 +0,0 @@
|
||||
(function() {
|
||||
var key, val, _ref;
|
||||
_ref = require('./coffee-script');
|
||||
for (key in _ref) {
|
||||
val = _ref[key];
|
||||
exports[key] = val;
|
||||
}
|
||||
}).call(this);
|
||||
656
bin/node_modules/coffee-script/lib/lexer.js
generated
vendored
656
bin/node_modules/coffee-script/lib/lexer.js
generated
vendored
@@ -1,656 +0,0 @@
|
||||
(function() {
|
||||
var ASSIGNED, BOOL, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_ALIAS_MAP, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, HEREDOC, HEREDOC_ILLEGAL, HEREDOC_INDENT, HEREGEX, HEREGEX_OMIT, IDENTIFIER, INDEXABLE, JSTOKEN, JS_FORBIDDEN, JS_KEYWORDS, LINE_BREAK, LINE_CONTINUER, LOGIC, Lexer, MATH, MULTILINER, MULTI_DENT, NOT_REGEX, NOT_SPACED_REGEX, NO_NEWLINE, NUMBER, OPERATOR, REGEX, RELATION, RESERVED, Rewriter, SHIFT, SIMPLESTR, TRAILING_SPACES, UNARY, WHITESPACE, compact, count, key, last, starts, _ref;
|
||||
var __indexOf = Array.prototype.indexOf || function(item) {
|
||||
for (var i = 0, l = this.length; i < l; i++) {
|
||||
if (this[i] === item) return i;
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
Rewriter = require('./rewriter').Rewriter;
|
||||
_ref = require('./helpers'), count = _ref.count, starts = _ref.starts, compact = _ref.compact, last = _ref.last;
|
||||
exports.Lexer = Lexer = (function() {
|
||||
function Lexer() {}
|
||||
Lexer.prototype.tokenize = function(code, opts) {
|
||||
var i;
|
||||
if (opts == null) {
|
||||
opts = {};
|
||||
}
|
||||
if (WHITESPACE.test(code)) {
|
||||
code = "\n" + code;
|
||||
}
|
||||
code = code.replace(/\r/g, '').replace(TRAILING_SPACES, '');
|
||||
this.code = code;
|
||||
this.line = opts.line || 0;
|
||||
this.indent = 0;
|
||||
this.indebt = 0;
|
||||
this.outdebt = 0;
|
||||
this.indents = [];
|
||||
this.tokens = [];
|
||||
i = 0;
|
||||
while (this.chunk = code.slice(i)) {
|
||||
i += this.identifierToken() || this.commentToken() || this.whitespaceToken() || this.lineToken() || this.heredocToken() || this.stringToken() || this.numberToken() || this.regexToken() || this.jsToken() || this.literalToken();
|
||||
}
|
||||
this.closeIndentation();
|
||||
if (opts.rewrite === false) {
|
||||
return this.tokens;
|
||||
}
|
||||
return (new Rewriter).rewrite(this.tokens);
|
||||
};
|
||||
Lexer.prototype.identifierToken = function() {
|
||||
var colon, forcedIdentifier, id, input, match, prev, tag, _ref2, _ref3;
|
||||
if (!(match = IDENTIFIER.exec(this.chunk))) {
|
||||
return 0;
|
||||
}
|
||||
input = match[0], id = match[1], colon = match[2];
|
||||
if (id === 'own' && this.tag() === 'FOR') {
|
||||
this.token('OWN', id);
|
||||
return id.length;
|
||||
}
|
||||
forcedIdentifier = colon || (prev = last(this.tokens)) && (((_ref2 = prev[0]) === '.' || _ref2 === '?.' || _ref2 === '::') || !prev.spaced && prev[0] === '@');
|
||||
tag = 'IDENTIFIER';
|
||||
if (!forcedIdentifier && (__indexOf.call(JS_KEYWORDS, id) >= 0 || __indexOf.call(COFFEE_KEYWORDS, id) >= 0)) {
|
||||
tag = id.toUpperCase();
|
||||
if (tag === 'WHEN' && (_ref3 = this.tag(), __indexOf.call(LINE_BREAK, _ref3) >= 0)) {
|
||||
tag = 'LEADING_WHEN';
|
||||
} else if (tag === 'FOR') {
|
||||
this.seenFor = true;
|
||||
} else if (tag === 'UNLESS') {
|
||||
tag = 'IF';
|
||||
} else if (__indexOf.call(UNARY, tag) >= 0) {
|
||||
tag = 'UNARY';
|
||||
} else if (__indexOf.call(RELATION, tag) >= 0) {
|
||||
if (tag !== 'INSTANCEOF' && this.seenFor) {
|
||||
tag = 'FOR' + tag;
|
||||
this.seenFor = false;
|
||||
} else {
|
||||
tag = 'RELATION';
|
||||
if (this.value() === '!') {
|
||||
this.tokens.pop();
|
||||
id = '!' + id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (__indexOf.call(JS_FORBIDDEN, id) >= 0) {
|
||||
if (forcedIdentifier) {
|
||||
tag = 'IDENTIFIER';
|
||||
id = new String(id);
|
||||
id.reserved = true;
|
||||
} else if (__indexOf.call(RESERVED, id) >= 0) {
|
||||
this.identifierError(id);
|
||||
}
|
||||
}
|
||||
if (!forcedIdentifier) {
|
||||
if (__indexOf.call(COFFEE_ALIASES, id) >= 0) {
|
||||
id = COFFEE_ALIAS_MAP[id];
|
||||
}
|
||||
tag = (function() {
|
||||
switch (id) {
|
||||
case '!':
|
||||
return 'UNARY';
|
||||
case '==':
|
||||
case '!=':
|
||||
return 'COMPARE';
|
||||
case '&&':
|
||||
case '||':
|
||||
return 'LOGIC';
|
||||
case 'true':
|
||||
case 'false':
|
||||
case 'null':
|
||||
case 'undefined':
|
||||
return 'BOOL';
|
||||
case 'break':
|
||||
case 'continue':
|
||||
case 'debugger':
|
||||
return 'STATEMENT';
|
||||
default:
|
||||
return tag;
|
||||
}
|
||||
})();
|
||||
}
|
||||
this.token(tag, id);
|
||||
if (colon) {
|
||||
this.token(':', ':');
|
||||
}
|
||||
return input.length;
|
||||
};
|
||||
Lexer.prototype.numberToken = function() {
|
||||
var match, number;
|
||||
if (!(match = NUMBER.exec(this.chunk))) {
|
||||
return 0;
|
||||
}
|
||||
number = match[0];
|
||||
this.token('NUMBER', number);
|
||||
return number.length;
|
||||
};
|
||||
Lexer.prototype.stringToken = function() {
|
||||
var match, string;
|
||||
switch (this.chunk.charAt(0)) {
|
||||
case "'":
|
||||
if (!(match = SIMPLESTR.exec(this.chunk))) {
|
||||
return 0;
|
||||
}
|
||||
this.token('STRING', (string = match[0]).replace(MULTILINER, '\\\n'));
|
||||
break;
|
||||
case '"':
|
||||
if (!(string = this.balancedString(this.chunk, '"'))) {
|
||||
return 0;
|
||||
}
|
||||
if (0 < string.indexOf('#{', 1)) {
|
||||
this.interpolateString(string.slice(1, -1));
|
||||
} else {
|
||||
this.token('STRING', this.escapeLines(string));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
this.line += count(string, '\n');
|
||||
return string.length;
|
||||
};
|
||||
Lexer.prototype.heredocToken = function() {
|
||||
var doc, heredoc, match, quote;
|
||||
if (!(match = HEREDOC.exec(this.chunk))) {
|
||||
return 0;
|
||||
}
|
||||
heredoc = match[0];
|
||||
quote = heredoc.charAt(0);
|
||||
doc = this.sanitizeHeredoc(match[2], {
|
||||
quote: quote,
|
||||
indent: null
|
||||
});
|
||||
if (quote === '"' && 0 <= doc.indexOf('#{')) {
|
||||
this.interpolateString(doc, {
|
||||
heredoc: true
|
||||
});
|
||||
} else {
|
||||
this.token('STRING', this.makeString(doc, quote, true));
|
||||
}
|
||||
this.line += count(heredoc, '\n');
|
||||
return heredoc.length;
|
||||
};
|
||||
Lexer.prototype.commentToken = function() {
|
||||
var comment, here, match;
|
||||
if (!(match = this.chunk.match(COMMENT))) {
|
||||
return 0;
|
||||
}
|
||||
comment = match[0], here = match[1];
|
||||
if (here) {
|
||||
this.token('HERECOMMENT', this.sanitizeHeredoc(here, {
|
||||
herecomment: true,
|
||||
indent: Array(this.indent + 1).join(' ')
|
||||
}));
|
||||
this.token('TERMINATOR', '\n');
|
||||
}
|
||||
this.line += count(comment, '\n');
|
||||
return comment.length;
|
||||
};
|
||||
Lexer.prototype.jsToken = function() {
|
||||
var match, script;
|
||||
if (!(this.chunk.charAt(0) === '`' && (match = JSTOKEN.exec(this.chunk)))) {
|
||||
return 0;
|
||||
}
|
||||
this.token('JS', (script = match[0]).slice(1, -1));
|
||||
return script.length;
|
||||
};
|
||||
Lexer.prototype.regexToken = function() {
|
||||
var length, match, prev, regex, _ref2;
|
||||
if (this.chunk.charAt(0) !== '/') {
|
||||
return 0;
|
||||
}
|
||||
if (match = HEREGEX.exec(this.chunk)) {
|
||||
length = this.heregexToken(match);
|
||||
this.line += count(match[0], '\n');
|
||||
return length;
|
||||
}
|
||||
prev = last(this.tokens);
|
||||
if (prev && (_ref2 = prev[0], __indexOf.call((prev.spaced ? NOT_REGEX : NOT_SPACED_REGEX), _ref2) >= 0)) {
|
||||
return 0;
|
||||
}
|
||||
if (!(match = REGEX.exec(this.chunk))) {
|
||||
return 0;
|
||||
}
|
||||
regex = match[0];
|
||||
this.token('REGEX', regex === '//' ? '/(?:)/' : regex);
|
||||
return regex.length;
|
||||
};
|
||||
Lexer.prototype.heregexToken = function(match) {
|
||||
var body, flags, heregex, re, tag, tokens, value, _i, _len, _ref2, _ref3, _ref4, _ref5;
|
||||
heregex = match[0], body = match[1], flags = match[2];
|
||||
if (0 > body.indexOf('#{')) {
|
||||
re = body.replace(HEREGEX_OMIT, '').replace(/\//g, '\\/');
|
||||
this.token('REGEX', "/" + (re || '(?:)') + "/" + flags);
|
||||
return heregex.length;
|
||||
}
|
||||
this.token('IDENTIFIER', 'RegExp');
|
||||
this.tokens.push(['CALL_START', '(']);
|
||||
tokens = [];
|
||||
_ref2 = this.interpolateString(body, {
|
||||
regex: true
|
||||
});
|
||||
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
||||
_ref3 = _ref2[_i], tag = _ref3[0], value = _ref3[1];
|
||||
if (tag === 'TOKENS') {
|
||||
tokens.push.apply(tokens, value);
|
||||
} else {
|
||||
if (!(value = value.replace(HEREGEX_OMIT, ''))) {
|
||||
continue;
|
||||
}
|
||||
value = value.replace(/\\/g, '\\\\');
|
||||
tokens.push(['STRING', this.makeString(value, '"', true)]);
|
||||
}
|
||||
tokens.push(['+', '+']);
|
||||
}
|
||||
tokens.pop();
|
||||
if (((_ref4 = tokens[0]) != null ? _ref4[0] : void 0) !== 'STRING') {
|
||||
this.tokens.push(['STRING', '""'], ['+', '+']);
|
||||
}
|
||||
(_ref5 = this.tokens).push.apply(_ref5, tokens);
|
||||
if (flags) {
|
||||
this.tokens.push([',', ','], ['STRING', '"' + flags + '"']);
|
||||
}
|
||||
this.token(')', ')');
|
||||
return heregex.length;
|
||||
};
|
||||
Lexer.prototype.lineToken = function() {
|
||||
var diff, indent, match, noNewlines, prev, size;
|
||||
if (!(match = MULTI_DENT.exec(this.chunk))) {
|
||||
return 0;
|
||||
}
|
||||
indent = match[0];
|
||||
this.line += count(indent, '\n');
|
||||
prev = last(this.tokens, 1);
|
||||
size = indent.length - 1 - indent.lastIndexOf('\n');
|
||||
noNewlines = this.unfinished();
|
||||
if (size - this.indebt === this.indent) {
|
||||
if (noNewlines) {
|
||||
this.suppressNewlines();
|
||||
} else {
|
||||
this.newlineToken();
|
||||
}
|
||||
return indent.length;
|
||||
}
|
||||
if (size > this.indent) {
|
||||
if (noNewlines) {
|
||||
this.indebt = size - this.indent;
|
||||
this.suppressNewlines();
|
||||
return indent.length;
|
||||
}
|
||||
diff = size - this.indent + this.outdebt;
|
||||
this.token('INDENT', diff);
|
||||
this.indents.push(diff);
|
||||
this.outdebt = this.indebt = 0;
|
||||
} else {
|
||||
this.indebt = 0;
|
||||
this.outdentToken(this.indent - size, noNewlines);
|
||||
}
|
||||
this.indent = size;
|
||||
return indent.length;
|
||||
};
|
||||
Lexer.prototype.outdentToken = function(moveOut, noNewlines, close) {
|
||||
var dent, len;
|
||||
while (moveOut > 0) {
|
||||
len = this.indents.length - 1;
|
||||
if (this.indents[len] === void 0) {
|
||||
moveOut = 0;
|
||||
} else if (this.indents[len] === this.outdebt) {
|
||||
moveOut -= this.outdebt;
|
||||
this.outdebt = 0;
|
||||
} else if (this.indents[len] < this.outdebt) {
|
||||
this.outdebt -= this.indents[len];
|
||||
moveOut -= this.indents[len];
|
||||
} else {
|
||||
dent = this.indents.pop() - this.outdebt;
|
||||
moveOut -= dent;
|
||||
this.outdebt = 0;
|
||||
this.token('OUTDENT', dent);
|
||||
}
|
||||
}
|
||||
if (dent) {
|
||||
this.outdebt -= moveOut;
|
||||
}
|
||||
if (!(this.tag() === 'TERMINATOR' || noNewlines)) {
|
||||
this.token('TERMINATOR', '\n');
|
||||
}
|
||||
return this;
|
||||
};
|
||||
Lexer.prototype.whitespaceToken = function() {
|
||||
var match, nline, prev;
|
||||
if (!((match = WHITESPACE.exec(this.chunk)) || (nline = this.chunk.charAt(0) === '\n'))) {
|
||||
return 0;
|
||||
}
|
||||
prev = last(this.tokens);
|
||||
if (prev) {
|
||||
prev[match ? 'spaced' : 'newLine'] = true;
|
||||
}
|
||||
if (match) {
|
||||
return match[0].length;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
Lexer.prototype.newlineToken = function() {
|
||||
if (this.tag() !== 'TERMINATOR') {
|
||||
this.token('TERMINATOR', '\n');
|
||||
}
|
||||
return this;
|
||||
};
|
||||
Lexer.prototype.suppressNewlines = function() {
|
||||
if (this.value() === '\\') {
|
||||
this.tokens.pop();
|
||||
}
|
||||
return this;
|
||||
};
|
||||
Lexer.prototype.literalToken = function() {
|
||||
var match, prev, tag, value, _ref2, _ref3, _ref4, _ref5;
|
||||
if (match = OPERATOR.exec(this.chunk)) {
|
||||
value = match[0];
|
||||
if (CODE.test(value)) {
|
||||
this.tagParameters();
|
||||
}
|
||||
} else {
|
||||
value = this.chunk.charAt(0);
|
||||
}
|
||||
tag = value;
|
||||
prev = last(this.tokens);
|
||||
if (value === '=' && prev) {
|
||||
if (!prev[1].reserved && (_ref2 = prev[1], __indexOf.call(JS_FORBIDDEN, _ref2) >= 0)) {
|
||||
this.assignmentError();
|
||||
}
|
||||
if ((_ref3 = prev[1]) === '||' || _ref3 === '&&') {
|
||||
prev[0] = 'COMPOUND_ASSIGN';
|
||||
prev[1] += '=';
|
||||
return value.length;
|
||||
}
|
||||
}
|
||||
if (value === ';') {
|
||||
tag = 'TERMINATOR';
|
||||
} else if (__indexOf.call(MATH, value) >= 0) {
|
||||
tag = 'MATH';
|
||||
} else if (__indexOf.call(COMPARE, value) >= 0) {
|
||||
tag = 'COMPARE';
|
||||
} else if (__indexOf.call(COMPOUND_ASSIGN, value) >= 0) {
|
||||
tag = 'COMPOUND_ASSIGN';
|
||||
} else if (__indexOf.call(UNARY, value) >= 0) {
|
||||
tag = 'UNARY';
|
||||
} else if (__indexOf.call(SHIFT, value) >= 0) {
|
||||
tag = 'SHIFT';
|
||||
} else if (__indexOf.call(LOGIC, value) >= 0 || value === '?' && (prev != null ? prev.spaced : void 0)) {
|
||||
tag = 'LOGIC';
|
||||
} else if (prev && !prev.spaced) {
|
||||
if (value === '(' && (_ref4 = prev[0], __indexOf.call(CALLABLE, _ref4) >= 0)) {
|
||||
if (prev[0] === '?') {
|
||||
prev[0] = 'FUNC_EXIST';
|
||||
}
|
||||
tag = 'CALL_START';
|
||||
} else if (value === '[' && (_ref5 = prev[0], __indexOf.call(INDEXABLE, _ref5) >= 0)) {
|
||||
tag = 'INDEX_START';
|
||||
switch (prev[0]) {
|
||||
case '?':
|
||||
prev[0] = 'INDEX_SOAK';
|
||||
break;
|
||||
case '::':
|
||||
prev[0] = 'INDEX_PROTO';
|
||||
}
|
||||
}
|
||||
}
|
||||
this.token(tag, value);
|
||||
return value.length;
|
||||
};
|
||||
Lexer.prototype.sanitizeHeredoc = function(doc, options) {
|
||||
var attempt, herecomment, indent, match, _ref2;
|
||||
indent = options.indent, herecomment = options.herecomment;
|
||||
if (herecomment) {
|
||||
if (HEREDOC_ILLEGAL.test(doc)) {
|
||||
throw new Error("block comment cannot contain \"*/\", starting on line " + (this.line + 1));
|
||||
}
|
||||
if (doc.indexOf('\n') <= 0) {
|
||||
return doc;
|
||||
}
|
||||
} else {
|
||||
while (match = HEREDOC_INDENT.exec(doc)) {
|
||||
attempt = match[1];
|
||||
if (indent === null || (0 < (_ref2 = attempt.length) && _ref2 < indent.length)) {
|
||||
indent = attempt;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (indent) {
|
||||
doc = doc.replace(RegExp("\\n" + indent, "g"), '\n');
|
||||
}
|
||||
if (!herecomment) {
|
||||
doc = doc.replace(/^\n/, '');
|
||||
}
|
||||
return doc;
|
||||
};
|
||||
Lexer.prototype.tagParameters = function() {
|
||||
var i, stack, tok, tokens;
|
||||
if (this.tag() !== ')') {
|
||||
return this;
|
||||
}
|
||||
stack = [];
|
||||
tokens = this.tokens;
|
||||
i = tokens.length;
|
||||
tokens[--i][0] = 'PARAM_END';
|
||||
while (tok = tokens[--i]) {
|
||||
switch (tok[0]) {
|
||||
case ')':
|
||||
stack.push(tok);
|
||||
break;
|
||||
case '(':
|
||||
case 'CALL_START':
|
||||
if (stack.length) {
|
||||
stack.pop();
|
||||
} else if (tok[0] === '(') {
|
||||
tok[0] = 'PARAM_START';
|
||||
return this;
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
};
|
||||
Lexer.prototype.closeIndentation = function() {
|
||||
return this.outdentToken(this.indent);
|
||||
};
|
||||
Lexer.prototype.identifierError = function(word) {
|
||||
throw SyntaxError("Reserved word \"" + word + "\" on line " + (this.line + 1));
|
||||
};
|
||||
Lexer.prototype.assignmentError = function() {
|
||||
throw SyntaxError("Reserved word \"" + (this.value()) + "\" on line " + (this.line + 1) + " can't be assigned");
|
||||
};
|
||||
Lexer.prototype.balancedString = function(str, end) {
|
||||
var i, letter, match, prev, stack, _ref2;
|
||||
stack = [end];
|
||||
for (i = 1, _ref2 = str.length; 1 <= _ref2 ? i < _ref2 : i > _ref2; 1 <= _ref2 ? i++ : i--) {
|
||||
switch (letter = str.charAt(i)) {
|
||||
case '\\':
|
||||
i++;
|
||||
continue;
|
||||
case end:
|
||||
stack.pop();
|
||||
if (!stack.length) {
|
||||
return str.slice(0, i + 1);
|
||||
}
|
||||
end = stack[stack.length - 1];
|
||||
continue;
|
||||
}
|
||||
if (end === '}' && (letter === '"' || letter === "'")) {
|
||||
stack.push(end = letter);
|
||||
} else if (end === '}' && letter === '/' && (match = HEREGEX.exec(str.slice(i)) || REGEX.exec(str.slice(i)))) {
|
||||
i += match[0].length - 1;
|
||||
} else if (end === '}' && letter === '{') {
|
||||
stack.push(end = '}');
|
||||
} else if (end === '"' && prev === '#' && letter === '{') {
|
||||
stack.push(end = '}');
|
||||
}
|
||||
prev = letter;
|
||||
}
|
||||
throw new Error("missing " + (stack.pop()) + ", starting on line " + (this.line + 1));
|
||||
};
|
||||
Lexer.prototype.interpolateString = function(str, options) {
|
||||
var expr, heredoc, i, inner, interpolated, len, letter, nested, pi, regex, tag, tokens, value, _len, _ref2, _ref3, _ref4;
|
||||
if (options == null) {
|
||||
options = {};
|
||||
}
|
||||
heredoc = options.heredoc, regex = options.regex;
|
||||
tokens = [];
|
||||
pi = 0;
|
||||
i = -1;
|
||||
while (letter = str.charAt(i += 1)) {
|
||||
if (letter === '\\') {
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
if (!(letter === '#' && str.charAt(i + 1) === '{' && (expr = this.balancedString(str.slice(i + 1), '}')))) {
|
||||
continue;
|
||||
}
|
||||
if (pi < i) {
|
||||
tokens.push(['NEOSTRING', str.slice(pi, i)]);
|
||||
}
|
||||
inner = expr.slice(1, -1);
|
||||
if (inner.length) {
|
||||
nested = new Lexer().tokenize(inner, {
|
||||
line: this.line,
|
||||
rewrite: false
|
||||
});
|
||||
nested.pop();
|
||||
if (((_ref2 = nested[0]) != null ? _ref2[0] : void 0) === 'TERMINATOR') {
|
||||
nested.shift();
|
||||
}
|
||||
if (len = nested.length) {
|
||||
if (len > 1) {
|
||||
nested.unshift(['(', '(']);
|
||||
nested.push([')', ')']);
|
||||
}
|
||||
tokens.push(['TOKENS', nested]);
|
||||
}
|
||||
}
|
||||
i += expr.length;
|
||||
pi = i + 1;
|
||||
}
|
||||
if ((i > pi && pi < str.length)) {
|
||||
tokens.push(['NEOSTRING', str.slice(pi)]);
|
||||
}
|
||||
if (regex) {
|
||||
return tokens;
|
||||
}
|
||||
if (!tokens.length) {
|
||||
return this.token('STRING', '""');
|
||||
}
|
||||
if (tokens[0][0] !== 'NEOSTRING') {
|
||||
tokens.unshift(['', '']);
|
||||
}
|
||||
if (interpolated = tokens.length > 1) {
|
||||
this.token('(', '(');
|
||||
}
|
||||
for (i = 0, _len = tokens.length; i < _len; i++) {
|
||||
_ref3 = tokens[i], tag = _ref3[0], value = _ref3[1];
|
||||
if (i) {
|
||||
this.token('+', '+');
|
||||
}
|
||||
if (tag === 'TOKENS') {
|
||||
(_ref4 = this.tokens).push.apply(_ref4, value);
|
||||
} else {
|
||||
this.token('STRING', this.makeString(value, '"', heredoc));
|
||||
}
|
||||
}
|
||||
if (interpolated) {
|
||||
this.token(')', ')');
|
||||
}
|
||||
return tokens;
|
||||
};
|
||||
Lexer.prototype.token = function(tag, value) {
|
||||
return this.tokens.push([tag, value, this.line]);
|
||||
};
|
||||
Lexer.prototype.tag = function(index, tag) {
|
||||
var tok;
|
||||
return (tok = last(this.tokens, index)) && (tag ? tok[0] = tag : tok[0]);
|
||||
};
|
||||
Lexer.prototype.value = function(index, val) {
|
||||
var tok;
|
||||
return (tok = last(this.tokens, index)) && (val ? tok[1] = val : tok[1]);
|
||||
};
|
||||
Lexer.prototype.unfinished = function() {
|
||||
var prev, value;
|
||||
return LINE_CONTINUER.test(this.chunk) || (prev = last(this.tokens, 1)) && prev[0] !== '.' && (value = this.value()) && !value.reserved && NO_NEWLINE.test(value) && !CODE.test(value) && !ASSIGNED.test(this.chunk);
|
||||
};
|
||||
Lexer.prototype.escapeLines = function(str, heredoc) {
|
||||
return str.replace(MULTILINER, heredoc ? '\\n' : '');
|
||||
};
|
||||
Lexer.prototype.makeString = function(body, quote, heredoc) {
|
||||
if (!body) {
|
||||
return quote + quote;
|
||||
}
|
||||
body = body.replace(/\\([\s\S])/g, function(match, contents) {
|
||||
if (contents === '\n' || contents === quote) {
|
||||
return contents;
|
||||
} else {
|
||||
return match;
|
||||
}
|
||||
});
|
||||
body = body.replace(RegExp("" + quote, "g"), '\\$&');
|
||||
return quote + this.escapeLines(body, heredoc) + quote;
|
||||
};
|
||||
return Lexer;
|
||||
})();
|
||||
JS_KEYWORDS = ['true', 'false', 'null', 'this', 'new', 'delete', 'typeof', 'in', 'instanceof', 'return', 'throw', 'break', 'continue', 'debugger', 'if', 'else', 'switch', 'for', 'while', 'do', 'try', 'catch', 'finally', 'class', 'extends', 'super'];
|
||||
COFFEE_KEYWORDS = ['undefined', 'then', 'unless', 'until', 'loop', 'of', 'by', 'when'];
|
||||
COFFEE_ALIAS_MAP = {
|
||||
and: '&&',
|
||||
or: '||',
|
||||
is: '==',
|
||||
isnt: '!=',
|
||||
not: '!',
|
||||
yes: 'true',
|
||||
no: 'false',
|
||||
on: 'true',
|
||||
off: 'false'
|
||||
};
|
||||
COFFEE_ALIASES = (function() {
|
||||
var _results;
|
||||
_results = [];
|
||||
for (key in COFFEE_ALIAS_MAP) {
|
||||
_results.push(key);
|
||||
}
|
||||
return _results;
|
||||
})();
|
||||
COFFEE_KEYWORDS = COFFEE_KEYWORDS.concat(COFFEE_ALIASES);
|
||||
RESERVED = ['case', 'default', 'function', 'var', 'void', 'with', 'const', 'let', 'enum', 'export', 'import', 'native', '__hasProp', '__extends', '__slice', '__bind', '__indexOf'];
|
||||
JS_FORBIDDEN = JS_KEYWORDS.concat(RESERVED);
|
||||
exports.RESERVED = RESERVED.concat(JS_KEYWORDS).concat(COFFEE_KEYWORDS);
|
||||
IDENTIFIER = /^([$A-Za-z_\x7f-\uffff][$\w\x7f-\uffff]*)([^\n\S]*:(?!:))?/;
|
||||
NUMBER = /^0x[\da-f]+|^\d*\.?\d+(?:e[+-]?\d+)?/i;
|
||||
HEREDOC = /^("""|''')([\s\S]*?)(?:\n[^\n\S]*)?\1/;
|
||||
OPERATOR = /^(?:[-=]>|[-+*\/%<>&|^!?=]=|>>>=?|([-+:])\1|([&|<>])\2=?|\?\.|\.{2,3})/;
|
||||
WHITESPACE = /^[^\n\S]+/;
|
||||
COMMENT = /^###([^#][\s\S]*?)(?:###[^\n\S]*|(?:###)?$)|^(?:\s*#(?!##[^#]).*)+/;
|
||||
CODE = /^[-=]>/;
|
||||
MULTI_DENT = /^(?:\n[^\n\S]*)+/;
|
||||
SIMPLESTR = /^'[^\\']*(?:\\.[^\\']*)*'/;
|
||||
JSTOKEN = /^`[^\\`]*(?:\\.[^\\`]*)*`/;
|
||||
REGEX = /^\/(?![\s=])[^[\/\n\\]*(?:(?:\\[\s\S]|\[[^\]\n\\]*(?:\\[\s\S][^\]\n\\]*)*])[^[\/\n\\]*)*\/[imgy]{0,4}(?!\w)/;
|
||||
HEREGEX = /^\/{3}([\s\S]+?)\/{3}([imgy]{0,4})(?!\w)/;
|
||||
HEREGEX_OMIT = /\s+(?:#.*)?/g;
|
||||
MULTILINER = /\n/g;
|
||||
HEREDOC_INDENT = /\n+([^\n\S]*)/g;
|
||||
HEREDOC_ILLEGAL = /\*\//;
|
||||
ASSIGNED = /^\s*@?([$A-Za-z_][$\w\x7f-\uffff]*|['"].*['"])[^\n\S]*?[:=][^:=>]/;
|
||||
LINE_CONTINUER = /^\s*(?:,|\??\.(?![.\d])|::)/;
|
||||
TRAILING_SPACES = /\s+$/;
|
||||
NO_NEWLINE = /^(?:[-+*&|\/%=<>!.\\][<>=&|]*|and|or|is(?:nt)?|n(?:ot|ew)|delete|typeof|instanceof)$/;
|
||||
COMPOUND_ASSIGN = ['-=', '+=', '/=', '*=', '%=', '||=', '&&=', '?=', '<<=', '>>=', '>>>=', '&=', '^=', '|='];
|
||||
UNARY = ['!', '~', 'NEW', 'TYPEOF', 'DELETE', 'DO'];
|
||||
LOGIC = ['&&', '||', '&', '|', '^'];
|
||||
SHIFT = ['<<', '>>', '>>>'];
|
||||
COMPARE = ['==', '!=', '<', '>', '<=', '>='];
|
||||
MATH = ['*', '/', '%'];
|
||||
RELATION = ['IN', 'OF', 'INSTANCEOF'];
|
||||
BOOL = ['TRUE', 'FALSE', 'NULL', 'UNDEFINED'];
|
||||
NOT_REGEX = ['NUMBER', 'REGEX', 'BOOL', '++', '--', ']'];
|
||||
NOT_SPACED_REGEX = NOT_REGEX.concat(')', '}', 'THIS', 'IDENTIFIER', 'STRING');
|
||||
CALLABLE = ['IDENTIFIER', 'STRING', 'REGEX', ')', ']', '}', '?', '::', '@', 'THIS', 'SUPER'];
|
||||
INDEXABLE = CALLABLE.concat('NUMBER', 'BOOL');
|
||||
LINE_BREAK = ['INDENT', 'OUTDENT', 'TERMINATOR'];
|
||||
}).call(this);
|
||||
2289
bin/node_modules/coffee-script/lib/nodes.js
generated
vendored
2289
bin/node_modules/coffee-script/lib/nodes.js
generated
vendored
File diff suppressed because it is too large
Load Diff
111
bin/node_modules/coffee-script/lib/optparse.js
generated
vendored
111
bin/node_modules/coffee-script/lib/optparse.js
generated
vendored
@@ -1,111 +0,0 @@
|
||||
(function() {
|
||||
var LONG_FLAG, MULTI_FLAG, OPTIONAL, OptionParser, SHORT_FLAG, buildRule, buildRules, normalizeArguments;
|
||||
exports.OptionParser = OptionParser = (function() {
|
||||
function OptionParser(rules, banner) {
|
||||
this.banner = banner;
|
||||
this.rules = buildRules(rules);
|
||||
}
|
||||
OptionParser.prototype.parse = function(args) {
|
||||
var arg, i, isOption, matchedRule, options, rule, value, _i, _len, _len2, _ref;
|
||||
options = {
|
||||
arguments: [],
|
||||
literals: []
|
||||
};
|
||||
args = normalizeArguments(args);
|
||||
for (i = 0, _len = args.length; i < _len; i++) {
|
||||
arg = args[i];
|
||||
if (arg === '--') {
|
||||
options.literals = args.slice(i + 1);
|
||||
break;
|
||||
}
|
||||
isOption = !!(arg.match(LONG_FLAG) || arg.match(SHORT_FLAG));
|
||||
matchedRule = false;
|
||||
_ref = this.rules;
|
||||
for (_i = 0, _len2 = _ref.length; _i < _len2; _i++) {
|
||||
rule = _ref[_i];
|
||||
if (rule.shortFlag === arg || rule.longFlag === arg) {
|
||||
value = rule.hasArgument ? args[i += 1] : true;
|
||||
options[rule.name] = rule.isList ? (options[rule.name] || []).concat(value) : value;
|
||||
matchedRule = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isOption && !matchedRule) {
|
||||
throw new Error("unrecognized option: " + arg);
|
||||
}
|
||||
if (!isOption) {
|
||||
options.arguments = args.slice(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return options;
|
||||
};
|
||||
OptionParser.prototype.help = function() {
|
||||
var letPart, lines, rule, spaces, _i, _len, _ref;
|
||||
lines = [];
|
||||
if (this.banner) {
|
||||
lines.unshift("" + this.banner + "\n");
|
||||
}
|
||||
_ref = this.rules;
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
rule = _ref[_i];
|
||||
spaces = 15 - rule.longFlag.length;
|
||||
spaces = spaces > 0 ? Array(spaces + 1).join(' ') : '';
|
||||
letPart = rule.shortFlag ? rule.shortFlag + ', ' : ' ';
|
||||
lines.push(' ' + letPart + rule.longFlag + spaces + rule.description);
|
||||
}
|
||||
return "\n" + (lines.join('\n')) + "\n";
|
||||
};
|
||||
return OptionParser;
|
||||
})();
|
||||
LONG_FLAG = /^(--\w[\w\-]+)/;
|
||||
SHORT_FLAG = /^(-\w)/;
|
||||
MULTI_FLAG = /^-(\w{2,})/;
|
||||
OPTIONAL = /\[(\w+(\*?))\]/;
|
||||
buildRules = function(rules) {
|
||||
var tuple, _i, _len, _results;
|
||||
_results = [];
|
||||
for (_i = 0, _len = rules.length; _i < _len; _i++) {
|
||||
tuple = rules[_i];
|
||||
if (tuple.length < 3) {
|
||||
tuple.unshift(null);
|
||||
}
|
||||
_results.push(buildRule.apply(null, tuple));
|
||||
}
|
||||
return _results;
|
||||
};
|
||||
buildRule = function(shortFlag, longFlag, description, options) {
|
||||
var match;
|
||||
if (options == null) {
|
||||
options = {};
|
||||
}
|
||||
match = longFlag.match(OPTIONAL);
|
||||
longFlag = longFlag.match(LONG_FLAG)[1];
|
||||
return {
|
||||
name: longFlag.substr(2),
|
||||
shortFlag: shortFlag,
|
||||
longFlag: longFlag,
|
||||
description: description,
|
||||
hasArgument: !!(match && match[1]),
|
||||
isList: !!(match && match[2])
|
||||
};
|
||||
};
|
||||
normalizeArguments = function(args) {
|
||||
var arg, l, match, result, _i, _j, _len, _len2, _ref;
|
||||
args = args.slice(0);
|
||||
result = [];
|
||||
for (_i = 0, _len = args.length; _i < _len; _i++) {
|
||||
arg = args[_i];
|
||||
if (match = arg.match(MULTI_FLAG)) {
|
||||
_ref = match[1].split('');
|
||||
for (_j = 0, _len2 = _ref.length; _j < _len2; _j++) {
|
||||
l = _ref[_j];
|
||||
result.push('-' + l);
|
||||
}
|
||||
} else {
|
||||
result.push(arg);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
}).call(this);
|
||||
676
bin/node_modules/coffee-script/lib/parser.js
generated
vendored
676
bin/node_modules/coffee-script/lib/parser.js
generated
vendored
File diff suppressed because one or more lines are too long
123
bin/node_modules/coffee-script/lib/repl.js
generated
vendored
123
bin/node_modules/coffee-script/lib/repl.js
generated
vendored
@@ -1,123 +0,0 @@
|
||||
(function() {
|
||||
var ACCESSOR, CoffeeScript, Module, REPL_PROMPT, REPL_PROMPT_CONTINUATION, SIMPLEVAR, Script, autocomplete, backlog, completeAttribute, completeVariable, enableColours, error, g, getCompletions, inspect, nonContextGlobals, readline, repl, run, sandbox, stdin, stdout, _i, _len;
|
||||
CoffeeScript = require('./coffee-script');
|
||||
readline = require('readline');
|
||||
inspect = require('util').inspect;
|
||||
Script = require('vm').Script;
|
||||
Module = require('module');
|
||||
REPL_PROMPT = 'coffee> ';
|
||||
REPL_PROMPT_CONTINUATION = '......> ';
|
||||
enableColours = false;
|
||||
if (process.platform !== 'win32') {
|
||||
enableColours = !process.env.NODE_DISABLE_COLORS;
|
||||
}
|
||||
stdin = process.openStdin();
|
||||
stdout = process.stdout;
|
||||
error = function(err) {
|
||||
return stdout.write((err.stack || err.toString()) + '\n\n');
|
||||
};
|
||||
backlog = '';
|
||||
sandbox = Script.createContext();
|
||||
nonContextGlobals = ['Buffer', 'console', 'process', 'setInterval', 'clearInterval', 'setTimeout', 'clearTimeout'];
|
||||
for (_i = 0, _len = nonContextGlobals.length; _i < _len; _i++) {
|
||||
g = nonContextGlobals[_i];
|
||||
sandbox[g] = global[g];
|
||||
}
|
||||
sandbox.global = sandbox.root = sandbox.GLOBAL = sandbox;
|
||||
run = function(buffer) {
|
||||
var code, returnValue, _;
|
||||
if (!buffer.toString().trim() && !backlog) {
|
||||
repl.prompt();
|
||||
return;
|
||||
}
|
||||
code = backlog += buffer;
|
||||
if (code[code.length - 1] === '\\') {
|
||||
backlog = "" + backlog.slice(0, -1) + "\n";
|
||||
repl.setPrompt(REPL_PROMPT_CONTINUATION);
|
||||
repl.prompt();
|
||||
return;
|
||||
}
|
||||
repl.setPrompt(REPL_PROMPT);
|
||||
backlog = '';
|
||||
try {
|
||||
_ = sandbox._;
|
||||
returnValue = CoffeeScript.eval("_=(" + code + "\n)", {
|
||||
sandbox: sandbox,
|
||||
filename: 'repl',
|
||||
modulename: 'repl'
|
||||
});
|
||||
if (returnValue === void 0) {
|
||||
sandbox._ = _;
|
||||
} else {
|
||||
process.stdout.write(inspect(returnValue, false, 2, enableColours) + '\n');
|
||||
}
|
||||
} catch (err) {
|
||||
error(err);
|
||||
}
|
||||
return repl.prompt();
|
||||
};
|
||||
ACCESSOR = /\s*([\w\.]+)(?:\.(\w*))$/;
|
||||
SIMPLEVAR = /\s*(\w*)$/i;
|
||||
autocomplete = function(text) {
|
||||
return completeAttribute(text) || completeVariable(text) || [[], text];
|
||||
};
|
||||
completeAttribute = function(text) {
|
||||
var all, completions, match, obj, prefix, val;
|
||||
if (match = text.match(ACCESSOR)) {
|
||||
all = match[0], obj = match[1], prefix = match[2];
|
||||
try {
|
||||
val = Script.runInContext(obj, sandbox);
|
||||
} catch (error) {
|
||||
return;
|
||||
}
|
||||
completions = getCompletions(prefix, Object.getOwnPropertyNames(val));
|
||||
return [completions, prefix];
|
||||
}
|
||||
};
|
||||
completeVariable = function(text) {
|
||||
var completions, free, possibilities, vars, _ref;
|
||||
if (free = (_ref = text.match(SIMPLEVAR)) != null ? _ref[1] : void 0) {
|
||||
vars = Script.runInContext('Object.getOwnPropertyNames(this)', sandbox);
|
||||
possibilities = vars.concat(CoffeeScript.RESERVED);
|
||||
completions = getCompletions(free, possibilities);
|
||||
return [completions, free];
|
||||
}
|
||||
};
|
||||
getCompletions = function(prefix, candidates) {
|
||||
var el, _j, _len2, _results;
|
||||
_results = [];
|
||||
for (_j = 0, _len2 = candidates.length; _j < _len2; _j++) {
|
||||
el = candidates[_j];
|
||||
if (el.indexOf(prefix) === 0) {
|
||||
_results.push(el);
|
||||
}
|
||||
}
|
||||
return _results;
|
||||
};
|
||||
process.on('uncaughtException', error);
|
||||
if (readline.createInterface.length < 3) {
|
||||
repl = readline.createInterface(stdin, autocomplete);
|
||||
stdin.on('data', function(buffer) {
|
||||
return repl.write(buffer);
|
||||
});
|
||||
} else {
|
||||
repl = readline.createInterface(stdin, stdout, autocomplete);
|
||||
}
|
||||
repl.on('attemptClose', function() {
|
||||
if (backlog) {
|
||||
backlog = '';
|
||||
process.stdout.write('\n');
|
||||
repl.setPrompt(REPL_PROMPT);
|
||||
return repl.prompt();
|
||||
} else {
|
||||
return repl.close();
|
||||
}
|
||||
});
|
||||
repl.on('close', function() {
|
||||
process.stdout.write('\n');
|
||||
return stdin.destroy();
|
||||
});
|
||||
repl.on('line', run);
|
||||
repl.setPrompt(REPL_PROMPT);
|
||||
repl.prompt();
|
||||
}).call(this);
|
||||
363
bin/node_modules/coffee-script/lib/rewriter.js
generated
vendored
363
bin/node_modules/coffee-script/lib/rewriter.js
generated
vendored
@@ -1,363 +0,0 @@
|
||||
(function() {
|
||||
var BALANCED_PAIRS, EXPRESSION_CLOSE, EXPRESSION_END, EXPRESSION_START, IMPLICIT_BLOCK, IMPLICIT_CALL, IMPLICIT_END, IMPLICIT_FUNC, IMPLICIT_UNSPACED_CALL, INVERSES, LINEBREAKS, SINGLE_CLOSERS, SINGLE_LINERS, left, rite, _i, _len, _ref;
|
||||
var __indexOf = Array.prototype.indexOf || function(item) {
|
||||
for (var i = 0, l = this.length; i < l; i++) {
|
||||
if (this[i] === item) return i;
|
||||
}
|
||||
return -1;
|
||||
}, __slice = Array.prototype.slice;
|
||||
exports.Rewriter = (function() {
|
||||
function Rewriter() {}
|
||||
Rewriter.prototype.rewrite = function(tokens) {
|
||||
this.tokens = tokens;
|
||||
this.removeLeadingNewlines();
|
||||
this.removeMidExpressionNewlines();
|
||||
this.closeOpenCalls();
|
||||
this.closeOpenIndexes();
|
||||
this.addImplicitIndentation();
|
||||
this.tagPostfixConditionals();
|
||||
this.addImplicitBraces();
|
||||
this.addImplicitParentheses();
|
||||
this.ensureBalance(BALANCED_PAIRS);
|
||||
this.rewriteClosingParens();
|
||||
return this.tokens;
|
||||
};
|
||||
Rewriter.prototype.scanTokens = function(block) {
|
||||
var i, token, tokens;
|
||||
tokens = this.tokens;
|
||||
i = 0;
|
||||
while (token = tokens[i]) {
|
||||
i += block.call(this, token, i, tokens);
|
||||
}
|
||||
return true;
|
||||
};
|
||||
Rewriter.prototype.detectEnd = function(i, condition, action) {
|
||||
var levels, token, tokens, _ref, _ref2;
|
||||
tokens = this.tokens;
|
||||
levels = 0;
|
||||
while (token = tokens[i]) {
|
||||
if (levels === 0 && condition.call(this, token, i)) {
|
||||
return action.call(this, token, i);
|
||||
}
|
||||
if (!token || levels < 0) {
|
||||
return action.call(this, token, i - 1);
|
||||
}
|
||||
if (_ref = token[0], __indexOf.call(EXPRESSION_START, _ref) >= 0) {
|
||||
levels += 1;
|
||||
} else if (_ref2 = token[0], __indexOf.call(EXPRESSION_END, _ref2) >= 0) {
|
||||
levels -= 1;
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
return i - 1;
|
||||
};
|
||||
Rewriter.prototype.removeLeadingNewlines = function() {
|
||||
var i, tag, _len, _ref;
|
||||
_ref = this.tokens;
|
||||
for (i = 0, _len = _ref.length; i < _len; i++) {
|
||||
tag = _ref[i][0];
|
||||
if (tag !== 'TERMINATOR') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i) {
|
||||
return this.tokens.splice(0, i);
|
||||
}
|
||||
};
|
||||
Rewriter.prototype.removeMidExpressionNewlines = function() {
|
||||
return this.scanTokens(function(token, i, tokens) {
|
||||
var _ref;
|
||||
if (!(token[0] === 'TERMINATOR' && (_ref = this.tag(i + 1), __indexOf.call(EXPRESSION_CLOSE, _ref) >= 0))) {
|
||||
return 1;
|
||||
}
|
||||
tokens.splice(i, 1);
|
||||
return 0;
|
||||
});
|
||||
};
|
||||
Rewriter.prototype.closeOpenCalls = function() {
|
||||
var action, condition;
|
||||
condition = function(token, i) {
|
||||
var _ref;
|
||||
return ((_ref = token[0]) === ')' || _ref === 'CALL_END') || token[0] === 'OUTDENT' && this.tag(i - 1) === ')';
|
||||
};
|
||||
action = function(token, i) {
|
||||
return this.tokens[token[0] === 'OUTDENT' ? i - 1 : i][0] = 'CALL_END';
|
||||
};
|
||||
return this.scanTokens(function(token, i) {
|
||||
if (token[0] === 'CALL_START') {
|
||||
this.detectEnd(i + 1, condition, action);
|
||||
}
|
||||
return 1;
|
||||
});
|
||||
};
|
||||
Rewriter.prototype.closeOpenIndexes = function() {
|
||||
var action, condition;
|
||||
condition = function(token, i) {
|
||||
var _ref;
|
||||
return (_ref = token[0]) === ']' || _ref === 'INDEX_END';
|
||||
};
|
||||
action = function(token, i) {
|
||||
return token[0] = 'INDEX_END';
|
||||
};
|
||||
return this.scanTokens(function(token, i) {
|
||||
if (token[0] === 'INDEX_START') {
|
||||
this.detectEnd(i + 1, condition, action);
|
||||
}
|
||||
return 1;
|
||||
});
|
||||
};
|
||||
Rewriter.prototype.addImplicitBraces = function() {
|
||||
var action, condition, stack, start, startIndent;
|
||||
stack = [];
|
||||
start = null;
|
||||
startIndent = 0;
|
||||
condition = function(token, i) {
|
||||
var one, tag, three, two, _ref, _ref2;
|
||||
_ref = this.tokens.slice(i + 1, (i + 3 + 1) || 9e9), one = _ref[0], two = _ref[1], three = _ref[2];
|
||||
if ('HERECOMMENT' === (one != null ? one[0] : void 0)) {
|
||||
return false;
|
||||
}
|
||||
tag = token[0];
|
||||
return ((tag === 'TERMINATOR' || tag === 'OUTDENT') && !((two != null ? two[0] : void 0) === ':' || (one != null ? one[0] : void 0) === '@' && (three != null ? three[0] : void 0) === ':')) || (tag === ',' && one && ((_ref2 = one[0]) !== 'IDENTIFIER' && _ref2 !== 'NUMBER' && _ref2 !== 'STRING' && _ref2 !== '@' && _ref2 !== 'TERMINATOR' && _ref2 !== 'OUTDENT'));
|
||||
};
|
||||
action = function(token, i) {
|
||||
var tok;
|
||||
tok = ['}', '}', token[2]];
|
||||
tok.generated = true;
|
||||
return this.tokens.splice(i, 0, tok);
|
||||
};
|
||||
return this.scanTokens(function(token, i, tokens) {
|
||||
var ago, idx, tag, tok, value, _ref, _ref2;
|
||||
if (_ref = (tag = token[0]), __indexOf.call(EXPRESSION_START, _ref) >= 0) {
|
||||
stack.push([(tag === 'INDENT' && this.tag(i - 1) === '{' ? '{' : tag), i]);
|
||||
return 1;
|
||||
}
|
||||
if (__indexOf.call(EXPRESSION_END, tag) >= 0) {
|
||||
start = stack.pop();
|
||||
return 1;
|
||||
}
|
||||
if (!(tag === ':' && ((ago = this.tag(i - 2)) === ':' || ((_ref2 = stack[stack.length - 1]) != null ? _ref2[0] : void 0) !== '{'))) {
|
||||
return 1;
|
||||
}
|
||||
stack.push(['{']);
|
||||
idx = ago === '@' ? i - 2 : i - 1;
|
||||
while (this.tag(idx - 2) === 'HERECOMMENT') {
|
||||
idx -= 2;
|
||||
}
|
||||
value = new String('{');
|
||||
value.generated = true;
|
||||
tok = ['{', value, token[2]];
|
||||
tok.generated = true;
|
||||
tokens.splice(idx, 0, tok);
|
||||
this.detectEnd(i + 2, condition, action);
|
||||
return 2;
|
||||
});
|
||||
};
|
||||
Rewriter.prototype.addImplicitParentheses = function() {
|
||||
var action, noCall;
|
||||
noCall = false;
|
||||
action = function(token, i) {
|
||||
var idx;
|
||||
idx = token[0] === 'OUTDENT' ? i + 1 : i;
|
||||
return this.tokens.splice(idx, 0, ['CALL_END', ')', token[2]]);
|
||||
};
|
||||
return this.scanTokens(function(token, i, tokens) {
|
||||
var callObject, current, next, prev, seenControl, seenSingle, tag, _ref, _ref2, _ref3;
|
||||
tag = token[0];
|
||||
if (tag === 'CLASS' || tag === 'IF') {
|
||||
noCall = true;
|
||||
}
|
||||
_ref = tokens.slice(i - 1, (i + 1 + 1) || 9e9), prev = _ref[0], current = _ref[1], next = _ref[2];
|
||||
callObject = !noCall && tag === 'INDENT' && next && next.generated && next[0] === '{' && prev && (_ref2 = prev[0], __indexOf.call(IMPLICIT_FUNC, _ref2) >= 0);
|
||||
seenSingle = false;
|
||||
seenControl = false;
|
||||
if (__indexOf.call(LINEBREAKS, tag) >= 0) {
|
||||
noCall = false;
|
||||
}
|
||||
if (prev && !prev.spaced && tag === '?') {
|
||||
token.call = true;
|
||||
}
|
||||
if (token.fromThen) {
|
||||
return 1;
|
||||
}
|
||||
if (!(callObject || (prev != null ? prev.spaced : void 0) && (prev.call || (_ref3 = prev[0], __indexOf.call(IMPLICIT_FUNC, _ref3) >= 0)) && (__indexOf.call(IMPLICIT_CALL, tag) >= 0 || !(token.spaced || token.newLine) && __indexOf.call(IMPLICIT_UNSPACED_CALL, tag) >= 0))) {
|
||||
return 1;
|
||||
}
|
||||
tokens.splice(i, 0, ['CALL_START', '(', token[2]]);
|
||||
this.detectEnd(i + 1, function(token, i) {
|
||||
var post, _ref4;
|
||||
tag = token[0];
|
||||
if (!seenSingle && token.fromThen) {
|
||||
return true;
|
||||
}
|
||||
if (tag === 'IF' || tag === 'ELSE' || tag === 'CATCH' || tag === '->' || tag === '=>') {
|
||||
seenSingle = true;
|
||||
}
|
||||
if (tag === 'IF' || tag === 'ELSE' || tag === 'SWITCH' || tag === 'TRY') {
|
||||
seenControl = true;
|
||||
}
|
||||
if ((tag === '.' || tag === '?.' || tag === '::') && this.tag(i - 1) === 'OUTDENT') {
|
||||
return true;
|
||||
}
|
||||
return !token.generated && this.tag(i - 1) !== ',' && (__indexOf.call(IMPLICIT_END, tag) >= 0 || (tag === 'INDENT' && !seenControl)) && (tag !== 'INDENT' || (this.tag(i - 2) !== 'CLASS' && (_ref4 = this.tag(i - 1), __indexOf.call(IMPLICIT_BLOCK, _ref4) < 0) && !((post = this.tokens[i + 1]) && post.generated && post[0] === '{')));
|
||||
}, action);
|
||||
if (prev[0] === '?') {
|
||||
prev[0] = 'FUNC_EXIST';
|
||||
}
|
||||
return 2;
|
||||
});
|
||||
};
|
||||
Rewriter.prototype.addImplicitIndentation = function() {
|
||||
return this.scanTokens(function(token, i, tokens) {
|
||||
var action, condition, indent, outdent, starter, tag, _ref, _ref2;
|
||||
tag = token[0];
|
||||
if (tag === 'TERMINATOR' && this.tag(i + 1) === 'THEN') {
|
||||
tokens.splice(i, 1);
|
||||
return 0;
|
||||
}
|
||||
if (tag === 'ELSE' && this.tag(i - 1) !== 'OUTDENT') {
|
||||
tokens.splice.apply(tokens, [i, 0].concat(__slice.call(this.indentation(token))));
|
||||
return 2;
|
||||
}
|
||||
if (tag === 'CATCH' && ((_ref = this.tag(i + 2)) === 'OUTDENT' || _ref === 'TERMINATOR' || _ref === 'FINALLY')) {
|
||||
tokens.splice.apply(tokens, [i + 2, 0].concat(__slice.call(this.indentation(token))));
|
||||
return 4;
|
||||
}
|
||||
if (__indexOf.call(SINGLE_LINERS, tag) >= 0 && this.tag(i + 1) !== 'INDENT' && !(tag === 'ELSE' && this.tag(i + 1) === 'IF')) {
|
||||
starter = tag;
|
||||
_ref2 = this.indentation(token), indent = _ref2[0], outdent = _ref2[1];
|
||||
if (starter === 'THEN') {
|
||||
indent.fromThen = true;
|
||||
}
|
||||
indent.generated = outdent.generated = true;
|
||||
tokens.splice(i + 1, 0, indent);
|
||||
condition = function(token, i) {
|
||||
var _ref3;
|
||||
return token[1] !== ';' && (_ref3 = token[0], __indexOf.call(SINGLE_CLOSERS, _ref3) >= 0) && !(token[0] === 'ELSE' && (starter !== 'IF' && starter !== 'THEN'));
|
||||
};
|
||||
action = function(token, i) {
|
||||
return this.tokens.splice((this.tag(i - 1) === ',' ? i - 1 : i), 0, outdent);
|
||||
};
|
||||
this.detectEnd(i + 2, condition, action);
|
||||
if (tag === 'THEN') {
|
||||
tokens.splice(i, 1);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
});
|
||||
};
|
||||
Rewriter.prototype.tagPostfixConditionals = function() {
|
||||
var condition;
|
||||
condition = function(token, i) {
|
||||
var _ref;
|
||||
return (_ref = token[0]) === 'TERMINATOR' || _ref === 'INDENT';
|
||||
};
|
||||
return this.scanTokens(function(token, i) {
|
||||
var original;
|
||||
if (token[0] !== 'IF') {
|
||||
return 1;
|
||||
}
|
||||
original = token;
|
||||
this.detectEnd(i + 1, condition, function(token, i) {
|
||||
if (token[0] !== 'INDENT') {
|
||||
return original[0] = 'POST_' + original[0];
|
||||
}
|
||||
});
|
||||
return 1;
|
||||
});
|
||||
};
|
||||
Rewriter.prototype.ensureBalance = function(pairs) {
|
||||
var close, level, levels, open, openLine, tag, token, _i, _j, _len, _len2, _ref, _ref2;
|
||||
levels = {};
|
||||
openLine = {};
|
||||
_ref = this.tokens;
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
token = _ref[_i];
|
||||
tag = token[0];
|
||||
for (_j = 0, _len2 = pairs.length; _j < _len2; _j++) {
|
||||
_ref2 = pairs[_j], open = _ref2[0], close = _ref2[1];
|
||||
levels[open] |= 0;
|
||||
if (tag === open) {
|
||||
if (levels[open]++ === 0) {
|
||||
openLine[open] = token[2];
|
||||
}
|
||||
} else if (tag === close && --levels[open] < 0) {
|
||||
throw Error("too many " + token[1] + " on line " + (token[2] + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
for (open in levels) {
|
||||
level = levels[open];
|
||||
if (level > 0) {
|
||||
throw Error("unclosed " + open + " on line " + (openLine[open] + 1));
|
||||
}
|
||||
}
|
||||
return this;
|
||||
};
|
||||
Rewriter.prototype.rewriteClosingParens = function() {
|
||||
var debt, key, stack;
|
||||
stack = [];
|
||||
debt = {};
|
||||
for (key in INVERSES) {
|
||||
debt[key] = 0;
|
||||
}
|
||||
return this.scanTokens(function(token, i, tokens) {
|
||||
var inv, match, mtag, oppos, tag, val, _ref;
|
||||
if (_ref = (tag = token[0]), __indexOf.call(EXPRESSION_START, _ref) >= 0) {
|
||||
stack.push(token);
|
||||
return 1;
|
||||
}
|
||||
if (__indexOf.call(EXPRESSION_END, tag) < 0) {
|
||||
return 1;
|
||||
}
|
||||
if (debt[inv = INVERSES[tag]] > 0) {
|
||||
debt[inv] -= 1;
|
||||
tokens.splice(i, 1);
|
||||
return 0;
|
||||
}
|
||||
match = stack.pop();
|
||||
mtag = match[0];
|
||||
oppos = INVERSES[mtag];
|
||||
if (tag === oppos) {
|
||||
return 1;
|
||||
}
|
||||
debt[mtag] += 1;
|
||||
val = [oppos, mtag === 'INDENT' ? match[1] : oppos];
|
||||
if (this.tag(i + 2) === mtag) {
|
||||
tokens.splice(i + 3, 0, val);
|
||||
stack.push(match);
|
||||
} else {
|
||||
tokens.splice(i, 0, val);
|
||||
}
|
||||
return 1;
|
||||
});
|
||||
};
|
||||
Rewriter.prototype.indentation = function(token) {
|
||||
return [['INDENT', 2, token[2]], ['OUTDENT', 2, token[2]]];
|
||||
};
|
||||
Rewriter.prototype.tag = function(i) {
|
||||
var _ref;
|
||||
return (_ref = this.tokens[i]) != null ? _ref[0] : void 0;
|
||||
};
|
||||
return Rewriter;
|
||||
})();
|
||||
BALANCED_PAIRS = [['(', ')'], ['[', ']'], ['{', '}'], ['INDENT', 'OUTDENT'], ['CALL_START', 'CALL_END'], ['PARAM_START', 'PARAM_END'], ['INDEX_START', 'INDEX_END']];
|
||||
INVERSES = {};
|
||||
EXPRESSION_START = [];
|
||||
EXPRESSION_END = [];
|
||||
for (_i = 0, _len = BALANCED_PAIRS.length; _i < _len; _i++) {
|
||||
_ref = BALANCED_PAIRS[_i], left = _ref[0], rite = _ref[1];
|
||||
EXPRESSION_START.push(INVERSES[rite] = left);
|
||||
EXPRESSION_END.push(INVERSES[left] = rite);
|
||||
}
|
||||
EXPRESSION_CLOSE = ['CATCH', 'WHEN', 'ELSE', 'FINALLY'].concat(EXPRESSION_END);
|
||||
IMPLICIT_FUNC = ['IDENTIFIER', 'SUPER', ')', 'CALL_END', ']', 'INDEX_END', '@', 'THIS'];
|
||||
IMPLICIT_CALL = ['IDENTIFIER', 'NUMBER', 'STRING', 'JS', 'REGEX', 'NEW', 'PARAM_START', 'CLASS', 'IF', 'TRY', 'SWITCH', 'THIS', 'BOOL', 'UNARY', 'SUPER', '@', '->', '=>', '[', '(', '{', '--', '++'];
|
||||
IMPLICIT_UNSPACED_CALL = ['+', '-'];
|
||||
IMPLICIT_BLOCK = ['->', '=>', '{', '[', ','];
|
||||
IMPLICIT_END = ['POST_IF', 'FOR', 'WHILE', 'UNTIL', 'WHEN', 'BY', 'LOOP', 'TERMINATOR'];
|
||||
SINGLE_LINERS = ['ELSE', '->', '=>', 'TRY', 'FINALLY', 'THEN'];
|
||||
SINGLE_CLOSERS = ['TERMINATOR', 'CATCH', 'FINALLY', 'ELSE', 'OUTDENT', 'LEADING_WHEN'];
|
||||
LINEBREAKS = ['TERMINATOR', 'INDENT', 'OUTDENT'];
|
||||
}).call(this);
|
||||
120
bin/node_modules/coffee-script/lib/scope.js
generated
vendored
120
bin/node_modules/coffee-script/lib/scope.js
generated
vendored
@@ -1,120 +0,0 @@
|
||||
(function() {
|
||||
var Scope, extend, last, _ref;
|
||||
_ref = require('./helpers'), extend = _ref.extend, last = _ref.last;
|
||||
exports.Scope = Scope = (function() {
|
||||
Scope.root = null;
|
||||
function Scope(parent, expressions, method) {
|
||||
this.parent = parent;
|
||||
this.expressions = expressions;
|
||||
this.method = method;
|
||||
this.variables = [
|
||||
{
|
||||
name: 'arguments',
|
||||
type: 'arguments'
|
||||
}
|
||||
];
|
||||
this.positions = {};
|
||||
if (!this.parent) {
|
||||
Scope.root = this;
|
||||
}
|
||||
}
|
||||
Scope.prototype.add = function(name, type, immediate) {
|
||||
var pos;
|
||||
if (this.shared && !immediate) {
|
||||
return this.parent.add(name, type, immediate);
|
||||
}
|
||||
if (typeof (pos = this.positions[name]) === 'number') {
|
||||
return this.variables[pos].type = type;
|
||||
} else {
|
||||
return this.positions[name] = this.variables.push({
|
||||
name: name,
|
||||
type: type
|
||||
}) - 1;
|
||||
}
|
||||
};
|
||||
Scope.prototype.find = function(name, options) {
|
||||
if (this.check(name, options)) {
|
||||
return true;
|
||||
}
|
||||
this.add(name, 'var');
|
||||
return false;
|
||||
};
|
||||
Scope.prototype.parameter = function(name) {
|
||||
if (this.shared && this.parent.check(name, true)) {
|
||||
return;
|
||||
}
|
||||
return this.add(name, 'param');
|
||||
};
|
||||
Scope.prototype.check = function(name, immediate) {
|
||||
var found, _ref2;
|
||||
found = !!this.type(name);
|
||||
if (found || immediate) {
|
||||
return found;
|
||||
}
|
||||
return !!((_ref2 = this.parent) != null ? _ref2.check(name) : void 0);
|
||||
};
|
||||
Scope.prototype.temporary = function(name, index) {
|
||||
if (name.length > 1) {
|
||||
return '_' + name + (index > 1 ? index : '');
|
||||
} else {
|
||||
return '_' + (index + parseInt(name, 36)).toString(36).replace(/\d/g, 'a');
|
||||
}
|
||||
};
|
||||
Scope.prototype.type = function(name) {
|
||||
var v, _i, _len, _ref2;
|
||||
_ref2 = this.variables;
|
||||
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
||||
v = _ref2[_i];
|
||||
if (v.name === name) {
|
||||
return v.type;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
Scope.prototype.freeVariable = function(type) {
|
||||
var index, temp;
|
||||
index = 0;
|
||||
while (this.check((temp = this.temporary(type, index)))) {
|
||||
index++;
|
||||
}
|
||||
this.add(temp, 'var', true);
|
||||
return temp;
|
||||
};
|
||||
Scope.prototype.assign = function(name, value) {
|
||||
this.add(name, {
|
||||
value: value,
|
||||
assigned: true
|
||||
});
|
||||
return this.hasAssignments = true;
|
||||
};
|
||||
Scope.prototype.hasDeclarations = function() {
|
||||
return !!this.declaredVariables().length;
|
||||
};
|
||||
Scope.prototype.declaredVariables = function() {
|
||||
var realVars, tempVars, v, _i, _len, _ref2;
|
||||
realVars = [];
|
||||
tempVars = [];
|
||||
_ref2 = this.variables;
|
||||
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
||||
v = _ref2[_i];
|
||||
if (v.type === 'var') {
|
||||
(v.name.charAt(0) === '_' ? tempVars : realVars).push(v.name);
|
||||
}
|
||||
}
|
||||
return realVars.sort().concat(tempVars.sort());
|
||||
};
|
||||
Scope.prototype.assignedVariables = function() {
|
||||
var v, _i, _len, _ref2, _results;
|
||||
_ref2 = this.variables;
|
||||
_results = [];
|
||||
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
||||
v = _ref2[_i];
|
||||
if (v.type.assigned) {
|
||||
_results.push("" + v.name + " = " + v.type.value);
|
||||
}
|
||||
}
|
||||
return _results;
|
||||
};
|
||||
return Scope;
|
||||
})();
|
||||
}).call(this);
|
||||
27
bin/node_modules/coffee-script/package.json
generated
vendored
27
bin/node_modules/coffee-script/package.json
generated
vendored
@@ -1,27 +0,0 @@
|
||||
{
|
||||
"name": "coffee-script",
|
||||
"description": "Unfancy JavaScript",
|
||||
"keywords": ["javascript", "language", "coffeescript", "compiler"],
|
||||
"author": "Jeremy Ashkenas",
|
||||
"version": "1.1.2",
|
||||
"licenses": [{
|
||||
"type": "MIT",
|
||||
"url": "http://github.com/jashkenas/coffee-script/raw/master/LICENSE"
|
||||
}],
|
||||
"engines": {
|
||||
"node": ">=0.2.5"
|
||||
},
|
||||
"directories" : {
|
||||
"lib" : "./lib"
|
||||
},
|
||||
"main" : "./lib/coffee-script",
|
||||
"bin": {
|
||||
"coffee": "./bin/coffee",
|
||||
"cake": "./bin/cake"
|
||||
},
|
||||
"homepage": "http://coffeescript.org",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/jashkenas/coffee-script.git"
|
||||
}
|
||||
}
|
||||
5
bin/node_modules/nodeunit/.gitignore
generated
vendored
5
bin/node_modules/nodeunit/.gitignore
generated
vendored
@@ -1,5 +0,0 @@
|
||||
dist
|
||||
stamp-build
|
||||
*~
|
||||
gmon.out
|
||||
v8.log
|
||||
3
bin/node_modules/nodeunit/.npmignore
generated
vendored
3
bin/node_modules/nodeunit/.npmignore
generated
vendored
@@ -1,3 +0,0 @@
|
||||
dist
|
||||
stamp-build
|
||||
test/fixtures/dir2
|
||||
60
bin/node_modules/nodeunit/CONTRIBUTORS.md
generated
vendored
60
bin/node_modules/nodeunit/CONTRIBUTORS.md
generated
vendored
@@ -1,60 +0,0 @@
|
||||
Nodeunit contributors (sorted alphabeticaly)
|
||||
============================================
|
||||
|
||||
* **[Alex Gorbatchev](https://github.com/alexgorbatchev)**
|
||||
|
||||
* Deeper default object inspection
|
||||
* Timeout to ensure flushing of console output (default reporter)
|
||||
|
||||
* **[Alex Wolfe](https://github.com/alexkwolfe)**
|
||||
|
||||
* HTML test reporter
|
||||
|
||||
* **[Caolan McMahon](https://github.com/caolan)**
|
||||
|
||||
* Author and maintainer
|
||||
* Most features develpopment
|
||||
|
||||
* **[Carl Fürstenberg](https://github.com/azatoth)**
|
||||
|
||||
* Debian-friendly Makefile, supports both 'node' and 'nodejs' executables
|
||||
* Sandbox utility
|
||||
* Minimal test reporter
|
||||
|
||||
* **[Gerad Suyderhoud](https://github.com/gerad)**
|
||||
|
||||
* First comand-line tool
|
||||
|
||||
* **[Kadir Pekel](https://github.com/coffeemate)**
|
||||
|
||||
* Improvements to default test reporter
|
||||
* HTTP test utility
|
||||
|
||||
* **[Matthias Lübken](https://github.com/luebken)**
|
||||
|
||||
* Utility functions for tracking incomplete tests on exit
|
||||
|
||||
* **[Oleg Efimov](https://github.com/Sannis)**
|
||||
|
||||
* Adding 'make lint' and fixing nodelint errors
|
||||
* Option parsing, --help text and config file support
|
||||
* Reporters option for command-line tool
|
||||
|
||||
* **[Orlando Vazquez](https://github.com/orlandov)**
|
||||
|
||||
* Added jUnit XML reporter
|
||||
|
||||
* **[Ryan Dahl](https://github.com/ry)**
|
||||
|
||||
* Add package.json
|
||||
|
||||
* **[Sam Stephenson](https://github.com/sstephenson)**
|
||||
|
||||
* Coffee-script support
|
||||
|
||||
* **[Thomas Mayfield](https://github.com/thegreatape)**
|
||||
|
||||
* Async setUp and tearDown support for testCase
|
||||
|
||||
**[Full contributors list](https://github.com/caolan/nodeunit/contributors).**
|
||||
|
||||
126
bin/node_modules/nodeunit/Makefile
generated
vendored
126
bin/node_modules/nodeunit/Makefile
generated
vendored
@@ -1,126 +0,0 @@
|
||||
PACKAGE = nodeunit
|
||||
NODEJS = $(if $(shell test -f /usr/bin/nodejs && echo "true"),nodejs,node)
|
||||
|
||||
PREFIX ?= /usr/local
|
||||
BINDIR ?= $(PREFIX)/bin
|
||||
DATADIR ?= $(PREFIX)/share
|
||||
MANDIR ?= $(PREFIX)/share/man
|
||||
LIBDIR ?= $(PREFIX)/lib
|
||||
NODEJSLIBDIR ?= $(LIBDIR)/$(NODEJS)
|
||||
|
||||
BUILDDIR = dist
|
||||
|
||||
DOCS = $(shell find doc -name '*.md' \
|
||||
|sed 's|.md|.1|g' \
|
||||
|sed 's|doc/|man1/|g' \
|
||||
)
|
||||
|
||||
|
||||
$(shell if [ ! -d $(BUILDDIR) ]; then mkdir $(BUILDDIR); fi)
|
||||
|
||||
all: build doc
|
||||
|
||||
browser:
|
||||
# super hacky build script for browser version!
|
||||
mkdir -p $(BUILDDIR)/browser
|
||||
rm -rf $(BUILDDIR)/browser/*
|
||||
# build browser version of nodeunit.js
|
||||
cat share/license.js >> $(BUILDDIR)/browser/nodeunit.js
|
||||
echo "nodeunit = (function(){" >> $(BUILDDIR)/browser/nodeunit.js
|
||||
cat deps/json2.js >> $(BUILDDIR)/browser/nodeunit.js
|
||||
# make assert global
|
||||
echo "var assert = this.assert = {};" >> $(BUILDDIR)/browser/nodeunit.js
|
||||
echo "var types = {};" >> $(BUILDDIR)/browser/nodeunit.js
|
||||
echo "var core = {};" >> $(BUILDDIR)/browser/nodeunit.js
|
||||
echo "var nodeunit = {};" >> $(BUILDDIR)/browser/nodeunit.js
|
||||
echo "var reporter = {};" >> $(BUILDDIR)/browser/nodeunit.js
|
||||
cat deps/async.js >> $(BUILDDIR)/browser/nodeunit.js
|
||||
echo "(function(exports){" >> $(BUILDDIR)/browser/nodeunit.js
|
||||
cat lib/assert.js >> $(BUILDDIR)/browser/nodeunit.js
|
||||
echo "})(assert);" >> $(BUILDDIR)/browser/nodeunit.js
|
||||
echo "(function(exports){" >> $(BUILDDIR)/browser/nodeunit.js
|
||||
cat lib/types.js >> $(BUILDDIR)/browser/nodeunit.js
|
||||
echo "})(types);" >> $(BUILDDIR)/browser/nodeunit.js
|
||||
echo "(function(exports){" >> $(BUILDDIR)/browser/nodeunit.js
|
||||
cat lib/core.js >> $(BUILDDIR)/browser/nodeunit.js
|
||||
echo "})(core);" >> $(BUILDDIR)/browser/nodeunit.js
|
||||
echo "(function(exports){" >> $(BUILDDIR)/browser/nodeunit.js
|
||||
cat lib/reporters/browser.js >> $(BUILDDIR)/browser/nodeunit.js
|
||||
echo "})(reporter);" >> $(BUILDDIR)/browser/nodeunit.js
|
||||
echo "nodeunit = core;" >> $(BUILDDIR)/browser/nodeunit.js
|
||||
echo "nodeunit.assert = assert;" >> $(BUILDDIR)/browser/nodeunit.js
|
||||
echo "nodeunit.reporter = reporter;" >> $(BUILDDIR)/browser/nodeunit.js
|
||||
echo "nodeunit.run = reporter.run;" >> $(BUILDDIR)/browser/nodeunit.js
|
||||
echo "return nodeunit; })();" >> $(BUILDDIR)/browser/nodeunit.js
|
||||
sed -i "/\@REMOVE_LINE_FOR_BROWSER/d" $(BUILDDIR)/browser/nodeunit.js
|
||||
# copy nodeunit.css
|
||||
cp share/nodeunit.css $(BUILDDIR)/browser/nodeunit.css
|
||||
# create nodeunit.min.js
|
||||
uglifyjs $(BUILDDIR)/browser/nodeunit.js > $(BUILDDIR)/browser/nodeunit.min.js
|
||||
# create test scripts
|
||||
mkdir -p $(BUILDDIR)/browser/test
|
||||
cp test/test.html $(BUILDDIR)/browser/test/test.html
|
||||
# test-base.js
|
||||
echo "(function (exports) {" > $(BUILDDIR)/browser/test/test-base.js
|
||||
cat test/test-base.js >> $(BUILDDIR)/browser/test/test-base.js
|
||||
echo "})(this.test_base = {});" >> $(BUILDDIR)/browser/test/test-base.js
|
||||
sed -i "/\@REMOVE_LINE_FOR_BROWSER/d" $(BUILDDIR)/browser/test/test-base.js
|
||||
# test-runmodule.js
|
||||
echo "(function (exports) {" > $(BUILDDIR)/browser/test/test-runmodule.js
|
||||
cat test/test-runmodule.js >> $(BUILDDIR)/browser/test/test-runmodule.js
|
||||
echo "})(this.test_runmodule = {});" >> $(BUILDDIR)/browser/test/test-runmodule.js
|
||||
sed -i "/\@REMOVE_LINE_FOR_BROWSER/d" $(BUILDDIR)/browser/test/test-runmodule.js
|
||||
# test-runtest.js
|
||||
echo "(function (exports) {" > $(BUILDDIR)/browser/test/test-runtest.js
|
||||
cat test/test-runtest.js >> $(BUILDDIR)/browser/test/test-runtest.js
|
||||
echo "})(this.test_runtest = {});" >> $(BUILDDIR)/browser/test/test-runtest.js
|
||||
sed -i "/\@REMOVE_LINE_FOR_BROWSER/d" $(BUILDDIR)/browser/test/test-runtest.js
|
||||
# test-testcase.js
|
||||
echo "(function (exports) {" > $(BUILDDIR)/browser/test/test-testcase.js
|
||||
cat test/test-testcase.js >> $(BUILDDIR)/browser/test/test-testcase.js
|
||||
echo "})(this.test_testcase = {});" >> $(BUILDDIR)/browser/test/test-testcase.js
|
||||
sed -i "/\@REMOVE_LINE_FOR_BROWSER/d" $(BUILDDIR)/browser/test/test-testcase.js
|
||||
# copy nodeunit.js to dist/browser/test to make it easier for me to host and
|
||||
# run on windows VMs with IE
|
||||
cp $(BUILDDIR)/browser/nodeunit.js $(BUILDDIR)/browser/test/nodeunit.js
|
||||
cp $(BUILDDIR)/browser/nodeunit.css $(BUILDDIR)/browser/test/nodeunit.css
|
||||
|
||||
build: stamp-build
|
||||
|
||||
stamp-build: $(wildcard deps/* lib/*.js)
|
||||
touch $@;
|
||||
mkdir -p $(BUILDDIR)/nodeunit
|
||||
cp -R bin deps index.js lib package.json $(BUILDDIR)/nodeunit
|
||||
printf '#!/bin/sh\n$(NODEJS) $(NODEJSLIBDIR)/$(PACKAGE)/bin/nodeunit $$@' > $(BUILDDIR)/nodeunit.sh
|
||||
|
||||
test:
|
||||
$(NODEJS) ./bin/nodeunit test
|
||||
|
||||
install: build
|
||||
install -d $(NODEJSLIBDIR)
|
||||
cp -a $(BUILDDIR)/nodeunit $(NODEJSLIBDIR)
|
||||
install -m 0755 $(BUILDDIR)/nodeunit.sh $(BINDIR)/nodeunit
|
||||
install -d $(MANDIR)/man1/
|
||||
cp -a man1/nodeunit.1 $(MANDIR)/man1/
|
||||
|
||||
uninstall:
|
||||
rm -rf $(NODEJSLIBDIR)/nodeunit $(NODEJSLIBDIR)/nodeunit.js $(BINDIR)/nodeunit
|
||||
rm -rf $(MANDIR)/man1/nodeunit.1
|
||||
|
||||
clean:
|
||||
rm -rf $(BUILDDIR) stamp-build
|
||||
|
||||
lint:
|
||||
nodelint --config nodelint.cfg ./index.js ./bin/nodeunit ./bin/nodeunit.json ./lib/*.js ./lib/reporters/*.js ./test/*.js
|
||||
|
||||
doc: man1 $(DOCS)
|
||||
@true
|
||||
|
||||
man1:
|
||||
@if ! test -d man1 ; then mkdir -p man1 ; fi
|
||||
|
||||
# use `npm install ronn` for this to work.
|
||||
man1/%.1: doc/%.md
|
||||
ronn --roff $< > $@
|
||||
|
||||
.PHONY: browser test install uninstall build all
|
||||
432
bin/node_modules/nodeunit/README.md
generated
vendored
432
bin/node_modules/nodeunit/README.md
generated
vendored
@@ -1,432 +0,0 @@
|
||||
Nodeunit
|
||||
========
|
||||
|
||||
Simple syntax, powerful tools. Nodeunit provides easy async unit testing for
|
||||
node.js and the browser.
|
||||
|
||||
* Simple to use
|
||||
* Just export the tests from a module
|
||||
* Works with node.js and in the browser.
|
||||
* Helps you avoid common pitfalls when testing asynchronous code
|
||||
* Easy to add test cases with setUp and tearDown functions if you wish
|
||||
* Flexible reporters for custom output, built-in support for HTML and jUnit XML
|
||||
* Allows the use of mocks and stubs
|
||||
|
||||
__Contributors__
|
||||
|
||||
* [alexgorbatchev](https://github.com/alexgorbatchev)
|
||||
* [alexkwolfe](https://github.com/alexkwolfe)
|
||||
* [azatoth](https://github.com/azatoth)
|
||||
* [coffeemate](https://github.com/coffeemate)
|
||||
* [luebken](https://github.com/luebken)
|
||||
* [orlandov](https://github.com/orlandov)
|
||||
* [Sannis](https://github.com/Sannis)
|
||||
* [sstephenson](https://github.com/sstephenson)
|
||||
* [thegreatape](https://github.com/thegreatape)
|
||||
* and thanks to [cjohansen](https://github.com/cjohansen) for input and advice
|
||||
on implementing setUp and tearDown functions. See
|
||||
[cjohansen's fork](https://github.com/cjohansen/nodeunit).
|
||||
|
||||
Also, check out gerad's [nodeunit-dsl](https://github.com/gerad/nodeunit-dsl)
|
||||
project, which implements a 'pretty dsl on top of nodeunit'.
|
||||
|
||||
More contributor information can be found in the
|
||||
[CONTRIBUTORS.md](https://github.com/caolan/nodeunit/blob/master/CONTRIBUTORS.md)
|
||||
file.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
Here is an example unit test module:
|
||||
|
||||
exports.testSomething = function(test){
|
||||
test.expect(1);
|
||||
test.ok(true, "this assertion should pass");
|
||||
test.done();
|
||||
};
|
||||
|
||||
exports.testSomethingElse = function(test){
|
||||
test.ok(false, "this assertion should fail");
|
||||
test.done();
|
||||
};
|
||||
|
||||
When run using the included test runner, this will output the following:
|
||||
|
||||
<img src="https://github.com/caolan/nodeunit/raw/master/img/example_fail.png" />
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
There are two options for installing nodeunit:
|
||||
|
||||
1. Clone / download nodeunit from [github](https://github.com/caolan/nodeunit),
|
||||
then:
|
||||
|
||||
make && sudo make install
|
||||
|
||||
2. Install via npm:
|
||||
|
||||
npm install nodeunit
|
||||
|
||||
API Documentation
|
||||
-----------------
|
||||
|
||||
Nodeunit uses the functions available in the node.js
|
||||
[assert module](http://nodejs.org/docs/v0.4.2/api/assert.html):
|
||||
|
||||
* __ok(value, [message])__ - Tests if value is a true value.
|
||||
* __equal(actual, expected, [message])__ - Tests shallow, coercive equality
|
||||
with the equal comparison operator ( == ).
|
||||
* __notEqual(actual, expected, [message])__ - Tests shallow, coercive
|
||||
non-equality with the not equal comparison operator ( != ).
|
||||
* __deepEqual(actual, expected, [message])__ - Tests for deep equality.
|
||||
* __notDeepEqual(actual, expected, [message])__ - Tests for any deep
|
||||
inequality.
|
||||
* __strictEqual(actual, expected, [message])__ - Tests strict equality, as
|
||||
determined by the strict equality operator ( === )
|
||||
* __notStrictEqual(actual, expected, [message])__ - Tests strict non-equality,
|
||||
as determined by the strict not equal operator ( !== )
|
||||
* __throws(block, [error], [message])__ - Expects block to throw an error.
|
||||
* __doesNotThrow(block, [error], [message])__ - Expects block not to throw an
|
||||
error.
|
||||
* __ifError(value)__ - Tests if value is not a false value, throws if it is a
|
||||
true value. Useful when testing the first argument, error in callbacks.
|
||||
|
||||
Nodeunit also provides the following functions within tests:
|
||||
|
||||
* __expect(amount)__ - Specify how many assertions are expected to run within a
|
||||
test. Very useful for ensuring that all your callbacks and assertions are
|
||||
run.
|
||||
* __done()__ - Finish the current test function, and move on to the next. ALL
|
||||
tests should call this!
|
||||
|
||||
Nodeunit aims to be simple and easy to learn. This is achieved through using
|
||||
existing structures (such as node.js modules) to maximum effect, and reducing
|
||||
the API where possible, to make it easier to digest.
|
||||
|
||||
Tests are simply exported from a module, but they are still run in the order
|
||||
they are defined.
|
||||
|
||||
__Note:__ Users of old nodeunit versions may remember using ok, equals and same
|
||||
in the style of qunit, instead of the assert functions above. These functions
|
||||
still exist for backwards compatibility, and are simply aliases to their assert
|
||||
module counterparts.
|
||||
|
||||
|
||||
Asynchronous Testing
|
||||
--------------------
|
||||
|
||||
When testing asynchronous code, there are a number of sharp edges to watch out
|
||||
for. Thankfully, nodeunit is designed to help you avoid as many of these
|
||||
pitfalls as possible. For the most part, testing asynchronous code in nodeunit
|
||||
_just works_.
|
||||
|
||||
|
||||
### Tests run in series
|
||||
|
||||
While running tests in parallel seems like a good idea for speeding up your
|
||||
test suite, in practice I've found it means writing much more complicated
|
||||
tests. Because of node's module cache, running tests in parallel means mocking
|
||||
and stubbing is pretty much impossible. One of the nicest things about testing
|
||||
in javascript is the ease of doing stubs:
|
||||
|
||||
var _readFile = fs.readFile;
|
||||
fs.readFile = function(path, callback){
|
||||
// its a stub!
|
||||
};
|
||||
// test function that uses fs.readFile
|
||||
|
||||
// we're done
|
||||
fs.readFile = _readFile;
|
||||
|
||||
You cannot do this when running tests in parallel. In order to keep testing as
|
||||
simple as possible, nodeunit avoids it. Thankfully, most unit-test suites run
|
||||
fast anyway.
|
||||
|
||||
|
||||
### Explicit ending of tests
|
||||
|
||||
When testing async code its important that tests end at the correct point, not
|
||||
just after a given number of assertions. Otherwise your tests can run short,
|
||||
ending before all assertions have completed. Its important to detect too
|
||||
many assertions as well as too few. Combining explicit ending of tests with
|
||||
an expected number of assertions helps to avoid false test passes, so be sure
|
||||
to use the test.expect() method at the start of your test functions, and
|
||||
test.done() when finished.
|
||||
|
||||
|
||||
Groups, setUp and tearDown
|
||||
--------------------------
|
||||
|
||||
Nodeunit allows the nesting of test functions:
|
||||
|
||||
exports.test1 = function (test) {
|
||||
...
|
||||
}
|
||||
|
||||
exports.group = {
|
||||
test2: function (test) {
|
||||
...
|
||||
},
|
||||
test3: function (test) {
|
||||
...
|
||||
}
|
||||
}
|
||||
|
||||
This would be run as:
|
||||
|
||||
test1
|
||||
group - test2
|
||||
group - test3
|
||||
|
||||
Using these groups its possible to add setUp and tearDown functions to your
|
||||
tests. Nodeunit has a utility function called testCase which allows you to
|
||||
define a setUp function, which is run before each test, and a tearDown
|
||||
function, which is run after each test calls test.done():
|
||||
|
||||
var testCase = require('nodeunit').testCase;
|
||||
|
||||
module.exports = testCase({
|
||||
setUp: function (callback) {
|
||||
this.foo = 'bar';
|
||||
callback();
|
||||
},
|
||||
tearDown: function (callback) {
|
||||
// clean up
|
||||
callback();
|
||||
},
|
||||
test1: function (test) {
|
||||
test.equals(this.foo, 'bar');
|
||||
test.done();
|
||||
}
|
||||
});
|
||||
|
||||
In this way, its possible to have multiple groups of tests in a module, each
|
||||
group with its own setUp and tearDown functions.
|
||||
|
||||
|
||||
Running Tests
|
||||
-------------
|
||||
|
||||
Nodeunit comes with a basic command-line test runner, which can be installed
|
||||
using 'sudo make install'. Example usage:
|
||||
|
||||
nodeunit testmodule1.js testfolder [...]
|
||||
|
||||
The default test reporter uses color output, because I think that's more fun :) I
|
||||
intend to add a no-color option in future. To give you a feeling of the fun you'll
|
||||
be having writing tests, lets fix the example at the start of the README:
|
||||
|
||||
<img src="https://github.com/caolan/nodeunit/raw/master/img/example_pass.png" />
|
||||
|
||||
Ahhh, Doesn't that feel better?
|
||||
|
||||
When using the included test runner, it will exit using the failed number of
|
||||
assertions as the exit code. Exiting with 0 when all tests pass.
|
||||
|
||||
|
||||
### Command-line Options
|
||||
|
||||
* __--reporter FILE__ - you can set the test reporter to a custom module or
|
||||
on of the modules in nodeunit/lib/reporters, when omitted, the default test runner
|
||||
is used.
|
||||
* __--list-reporters__ - list available build-in reporters.
|
||||
* __--config FILE__ - load config options from a JSON file, allows
|
||||
the customisation of color schemes for the default test reporter etc. See
|
||||
bin/nodeunit.json for current available options.
|
||||
* __--version__ or __-v__ - report nodeunit version
|
||||
* __--help__ - show nodeunit help
|
||||
|
||||
|
||||
Running tests in the browser
|
||||
----------------------------
|
||||
|
||||
Nodeunit tests can also be run inside the browser. For example usage, see
|
||||
the examples/browser folder. The basic syntax is as follows:
|
||||
|
||||
__test.html__
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>Example Test Suite</title>
|
||||
<link rel="stylesheet" href="nodeunit.css" type="text/css" />
|
||||
<script src="nodeunit.js"></script>
|
||||
<script src="suite1.js"></script>
|
||||
<script src="suite2.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="nodeunit-header>Example Test Suite</h1>
|
||||
<script>
|
||||
nodeunit.run({
|
||||
'Suite One': suite1,
|
||||
'Suite Two': suite2
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Here, suite1 and suite2 are just object literals containing test functions or
|
||||
groups, as would be returned if you did require('test-suite') in node.js:
|
||||
|
||||
__suite1.js__
|
||||
|
||||
this.suite1 = {
|
||||
'example test': function (test) {
|
||||
test.ok(true, 'everything is ok');
|
||||
test.done();
|
||||
}
|
||||
};
|
||||
|
||||
If you wish to use a commonjs format for your test suites (using exports), it is
|
||||
up to you to define the commonjs tools for the browser. There are a number of
|
||||
alternatives and its important it fits with your existing code, which is
|
||||
why nodeunit does not currently provide this out of the box.
|
||||
|
||||
In the example above, the tests will run when the page is loaded.
|
||||
|
||||
The browser-version of nodeunit.js is created in dist/browser when you do, 'make
|
||||
browser'. You'll need [UglifyJS](https://github.com/mishoo/UglifyJS) installed in
|
||||
order for it to automatically create nodeunit.min.js.
|
||||
|
||||
|
||||
Adding nodeunit to Your Projects
|
||||
--------------------------------
|
||||
|
||||
If you don't want people to have to install the nodeunit command-line tool,
|
||||
you'll want to create a script that runs the tests for your project with the
|
||||
correct require paths set up. Here's an example test script, with a deps
|
||||
directory containing the projects dependencies:
|
||||
|
||||
#!/usr/bin/env node
|
||||
require.paths.unshift(__dirname + '/deps');
|
||||
|
||||
var reporter = require('nodeunit').reporters.default;
|
||||
reporter.run(['test']);
|
||||
|
||||
If you're using git, you might find it useful to include nodeunit as a
|
||||
submodule. Using submodules makes it easy for developers to download nodeunit
|
||||
and run your test suite, without cluttering up your repository with
|
||||
the source code. To add nodeunit as a git submodule do the following:
|
||||
|
||||
git submodule add git://github.com/caolan/nodeunit.git deps/nodeunit
|
||||
|
||||
This will add nodeunit to the deps folder of your project. Now, when cloning
|
||||
the repository, nodeunit can be downloaded by doing the following:
|
||||
|
||||
git submodule init
|
||||
git submodule update
|
||||
|
||||
Let's update the test script above with a helpful hint on how to get nodeunit,
|
||||
if its missing:
|
||||
|
||||
#!/usr/bin/env node
|
||||
|
||||
require.paths.unshift(__dirname + '/deps');
|
||||
|
||||
try {
|
||||
var reporter = require('nodeunit').reporters.default;
|
||||
}
|
||||
catch(e) {
|
||||
console.log("Cannot find nodeunit module.");
|
||||
console.log("You can download submodules for this project by doing:");
|
||||
console.log("");
|
||||
console.log(" git submodule init");
|
||||
console.log(" git submodule update");
|
||||
console.log("");
|
||||
process.exit();
|
||||
}
|
||||
|
||||
process.chdir(__dirname);
|
||||
reporter.run(['test']);
|
||||
|
||||
Now if someone attempts to run your test suite without nodeunit installed they
|
||||
will be prompted to download the submodules for your project.
|
||||
|
||||
|
||||
Built-in Test Reporters
|
||||
-----------------------
|
||||
|
||||
* __default__ - The standard reporter seen in the nodeunit screenshots
|
||||
* __minimal__ - Pretty, minimal output, shows errors and progress only
|
||||
* __html__ - Outputs a HTML report to stdout
|
||||
* __junit__ - Creates jUnit compatible XML reports, which can be used with
|
||||
continuous integration tools such as [Hudson](http://hudson-ci.org/).
|
||||
|
||||
|
||||
Writing a Test Reporter
|
||||
---------------------
|
||||
|
||||
Nodeunit exports runTest(fn, options), runModule(mod, options) and
|
||||
runFiles(paths, options). You'll most likely want to run test suites from
|
||||
files, which can be done using the latter function. The _options_ argument can
|
||||
contain callbacks which run during testing. Nodeunit provides the following
|
||||
callbacks:
|
||||
|
||||
* __moduleStart(name)__ - called before a module is tested
|
||||
* __moduleDone(name, assertions)__ - called once all test functions within the
|
||||
module have completed (see assertions object reference below)
|
||||
ALL tests within the module
|
||||
* __testStart(name)__ - called before a test function is run
|
||||
* __testDone(name, assertions)__ - called once a test function has completed
|
||||
(by calling test.done())
|
||||
* __log(assertion)__ - called whenever an assertion is made (see assertion
|
||||
object reference below)
|
||||
* __done(assertions)__ - called after all tests/modules are complete
|
||||
|
||||
The __assertion__ object:
|
||||
|
||||
* __passed()__ - did the assertion pass?
|
||||
* __failed()__ - did the assertion fail?
|
||||
* __error__ - the AssertionError if the assertion failed
|
||||
* __method__ - the nodeunit assertion method used (ok, same, equals...)
|
||||
* __message__ - the message the assertion method was called with (optional)
|
||||
|
||||
The __assertionList__ object:
|
||||
|
||||
* An array-like object with the following new attributes:
|
||||
* __failures()__ - the number of assertions which failed
|
||||
* __duration__ - the time taken for the test to complete in msecs
|
||||
|
||||
For a reference implementation of a test reporter, see lib/reporters/default.js in
|
||||
the nodeunit project directory.
|
||||
|
||||
|
||||
Sandbox utility
|
||||
---------------
|
||||
|
||||
This is a function which evaluates JavaScript files in a sandbox and returns the
|
||||
context. The sandbox function can be used for testing client-side code or private
|
||||
un-exported functions within a module.
|
||||
|
||||
var sandbox = require('nodeunit').utils.sandbox;
|
||||
var example = sandbox('example.js');
|
||||
|
||||
__sandbox(files, sandbox)__ - Evaluates JavaScript files in a sandbox, returning
|
||||
the context. The first argument can either be a single filename or an array of
|
||||
filenames. If multiple filenames are given their contents are concatenated before
|
||||
evalution. The second argument is an optional context to use for the sandbox.
|
||||
|
||||
|
||||
Running the nodeunit Tests
|
||||
--------------------------
|
||||
|
||||
The tests for nodeunit are written using nodeunit itself as the test framework.
|
||||
However, the module test-base.js first does some basic tests using the assert
|
||||
module to ensure that test functions are actually run, and a basic level of
|
||||
nodeunit functionality is available.
|
||||
|
||||
To run the nodeunit tests do:
|
||||
|
||||
make test
|
||||
|
||||
__Note:__ There was a bug in node v0.2.0 causing the tests to hang, upgrading
|
||||
to v0.2.1 fixes this.
|
||||
|
||||
|
||||
Contributing
|
||||
------------
|
||||
|
||||
Contributions to the project are most welcome, so feel free to fork and improve.
|
||||
When submitting a pull request, please run 'make lint' first to ensure
|
||||
we're following a consistent coding style.
|
||||
|
||||
120
bin/node_modules/nodeunit/bin/nodeunit
generated
vendored
120
bin/node_modules/nodeunit/bin/nodeunit
generated
vendored
@@ -1,120 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
var
|
||||
fs = require('fs'),
|
||||
path = require('path');
|
||||
|
||||
// TODO: remove this when https://github.com/joyent/node/pull/1312
|
||||
// lands in core.
|
||||
//
|
||||
// Until then, use console.log from npm (https://gist.github.com/1077544)
|
||||
require('../deps/console.log');
|
||||
|
||||
require.paths.push(process.cwd());
|
||||
var args = process.ARGV.slice(2);
|
||||
|
||||
var files = [];
|
||||
|
||||
var testrunner,
|
||||
config_file,
|
||||
config_param_found = false,
|
||||
output_param_found = false,
|
||||
reporter_file = 'default',
|
||||
reporter_param_found = false,
|
||||
testspec_param_found = false;
|
||||
|
||||
var usage = "Usage: nodeunit [options] testmodule1.js testfolder [...] \n" +
|
||||
"Options:\n\n" +
|
||||
" --config FILE the path to a JSON file with options\n" +
|
||||
" --reporter FILE optional path to a reporter file to customize the output\n" +
|
||||
" --list-reporters list available build-in reporters\n" +
|
||||
" -t name, specify a test to run\n" +
|
||||
" -h, --help display this help and exit\n" +
|
||||
" -v, --version output version information and exit";
|
||||
|
||||
|
||||
// load default options
|
||||
var content = fs.readFileSync(__dirname + '/nodeunit.json', 'utf8');
|
||||
var options = JSON.parse(content);
|
||||
|
||||
// a very basic pseudo --options parser
|
||||
args.forEach(function (arg) {
|
||||
if (arg.slice(0, 9) === "--config=") {
|
||||
config_file = arg.slice(9);
|
||||
} else if (arg === '--config') {
|
||||
config_param_found = true;
|
||||
} else if (config_param_found) {
|
||||
config_file = arg;
|
||||
config_param_found = false;
|
||||
} else if (arg.slice(0, 9) === "--output=") {
|
||||
options.output = arg.slice(9);
|
||||
} else if (arg === '--output') {
|
||||
output_param_found = true;
|
||||
} else if (output_param_found) {
|
||||
options.output = arg;
|
||||
output_param_found = false;
|
||||
} else if (arg.slice(0, 11) === "--reporter=") {
|
||||
reporter_file = arg.slice(11);
|
||||
} else if (arg === '--reporter') {
|
||||
reporter_param_found = true;
|
||||
} else if (reporter_param_found) {
|
||||
reporter_file = arg;
|
||||
reporter_param_found = false;
|
||||
} else if (arg === '-t') {
|
||||
testspec_param_found = true;
|
||||
} else if (testspec_param_found) {
|
||||
options.testspec = arg;
|
||||
testspec_param_found = false;
|
||||
} else if (arg === '--list-reporters') {
|
||||
var reporters = fs.readdirSync(__dirname + '/../lib/reporters');
|
||||
reporters = reporters.filter(function (reporter_file) {
|
||||
return (/\.js$/).test(reporter_file);
|
||||
}).map(function (reporter_file) {
|
||||
return reporter_file.replace(/\.js$/, '');
|
||||
}).filter(function (reporter_file) {
|
||||
return reporter_file !== 'index';
|
||||
});
|
||||
console.log('Build-in reporters: ');
|
||||
reporters.forEach(function (reporter_file) {
|
||||
var reporter = require('../lib/reporters/' + reporter_file);
|
||||
console.log(' * ' + reporter_file + (reporter.info ? ': ' + reporter.info : ''));
|
||||
});
|
||||
process.exit(0);
|
||||
} else if ((arg === '-v') || (arg === '--version')) {
|
||||
var content = fs.readFileSync(__dirname + '/../package.json', 'utf8');
|
||||
var pkg = JSON.parse(content);
|
||||
console.log(pkg.version);
|
||||
process.exit(0);
|
||||
} else if ((arg === '-h') || (arg === '--help')) {
|
||||
console.log(usage);
|
||||
process.exit(0);
|
||||
} else {
|
||||
files.push(arg);
|
||||
}
|
||||
});
|
||||
|
||||
if (files.length === 0) {
|
||||
console.log('Files required.');
|
||||
console.log(usage);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (config_file) {
|
||||
content = fs.readFileSync(config_file, 'utf8');
|
||||
var custom_options = JSON.parse(content);
|
||||
|
||||
for (var option in custom_options) {
|
||||
if (typeof option === 'string') {
|
||||
options[option] = custom_options[option];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var builtin_reporters = require(__dirname + '/../lib/reporters');
|
||||
if (reporter_file in builtin_reporters) {
|
||||
testrunner = builtin_reporters[reporter_file];
|
||||
}
|
||||
else {
|
||||
testrunner = require(reporter_file);
|
||||
}
|
||||
testrunner.run(files, options);
|
||||
10
bin/node_modules/nodeunit/bin/nodeunit.json
generated
vendored
10
bin/node_modules/nodeunit/bin/nodeunit.json
generated
vendored
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"error_prefix": "\u001B[31m",
|
||||
"error_suffix": "\u001B[39m",
|
||||
"ok_prefix": "\u001B[32m",
|
||||
"ok_suffix": "\u001B[39m",
|
||||
"bold_prefix": "\u001B[1m",
|
||||
"bold_suffix": "\u001B[22m",
|
||||
"assertion_prefix": "\u001B[35m",
|
||||
"assertion_suffix": "\u001B[39m"
|
||||
}
|
||||
623
bin/node_modules/nodeunit/deps/async.js
generated
vendored
623
bin/node_modules/nodeunit/deps/async.js
generated
vendored
@@ -1,623 +0,0 @@
|
||||
/*global setTimeout: false, console: false */
|
||||
(function () {
|
||||
|
||||
var async = {};
|
||||
|
||||
// global on the server, window in the browser
|
||||
var root = this,
|
||||
previous_async = root.async;
|
||||
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
module.exports = async;
|
||||
}
|
||||
else {
|
||||
root.async = async;
|
||||
}
|
||||
|
||||
async.noConflict = function () {
|
||||
root.async = previous_async;
|
||||
return async;
|
||||
};
|
||||
|
||||
//// cross-browser compatiblity functions ////
|
||||
|
||||
var _forEach = function (arr, iterator) {
|
||||
if (arr.forEach) {
|
||||
return arr.forEach(iterator);
|
||||
}
|
||||
for (var i = 0; i < arr.length; i += 1) {
|
||||
iterator(arr[i], i, arr);
|
||||
}
|
||||
};
|
||||
|
||||
var _map = function (arr, iterator) {
|
||||
if (arr.map) {
|
||||
return arr.map(iterator);
|
||||
}
|
||||
var results = [];
|
||||
_forEach(arr, function (x, i, a) {
|
||||
results.push(iterator(x, i, a));
|
||||
});
|
||||
return results;
|
||||
};
|
||||
|
||||
var _reduce = function (arr, iterator, memo) {
|
||||
if (arr.reduce) {
|
||||
return arr.reduce(iterator, memo);
|
||||
}
|
||||
_forEach(arr, function (x, i, a) {
|
||||
memo = iterator(memo, x, i, a);
|
||||
});
|
||||
return memo;
|
||||
};
|
||||
|
||||
var _keys = function (obj) {
|
||||
if (Object.keys) {
|
||||
return Object.keys(obj);
|
||||
}
|
||||
var keys = [];
|
||||
for (var k in obj) {
|
||||
if (obj.hasOwnProperty(k)) {
|
||||
keys.push(k);
|
||||
}
|
||||
}
|
||||
return keys;
|
||||
};
|
||||
|
||||
var _indexOf = function (arr, item) {
|
||||
if (arr.indexOf) {
|
||||
return arr.indexOf(item);
|
||||
}
|
||||
for (var i = 0; i < arr.length; i += 1) {
|
||||
if (arr[i] === item) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
|
||||
//// exported async module functions ////
|
||||
|
||||
//// nextTick implementation with browser-compatible fallback ////
|
||||
if (typeof process === 'undefined' || !(process.nextTick)) {
|
||||
async.nextTick = function (fn) {
|
||||
setTimeout(fn, 0);
|
||||
};
|
||||
}
|
||||
else {
|
||||
async.nextTick = process.nextTick;
|
||||
}
|
||||
|
||||
async.forEach = function (arr, iterator, callback) {
|
||||
if (!arr.length) {
|
||||
return callback();
|
||||
}
|
||||
var completed = 0;
|
||||
_forEach(arr, function (x) {
|
||||
iterator(x, function (err) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
callback = function () {};
|
||||
}
|
||||
else {
|
||||
completed += 1;
|
||||
if (completed === arr.length) {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
async.forEachSeries = function (arr, iterator, callback) {
|
||||
if (!arr.length) {
|
||||
return callback();
|
||||
}
|
||||
var completed = 0;
|
||||
var iterate = function () {
|
||||
iterator(arr[completed], function (err) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
callback = function () {};
|
||||
}
|
||||
else {
|
||||
completed += 1;
|
||||
if (completed === arr.length) {
|
||||
callback();
|
||||
}
|
||||
else {
|
||||
iterate();
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
iterate();
|
||||
};
|
||||
|
||||
|
||||
var doParallel = function (fn) {
|
||||
return function () {
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
return fn.apply(null, [async.forEach].concat(args));
|
||||
};
|
||||
};
|
||||
var doSeries = function (fn) {
|
||||
return function () {
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
return fn.apply(null, [async.forEachSeries].concat(args));
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
var _asyncMap = function (eachfn, arr, iterator, callback) {
|
||||
var results = [];
|
||||
arr = _map(arr, function (x, i) {
|
||||
return {index: i, value: x};
|
||||
});
|
||||
eachfn(arr, function (x, callback) {
|
||||
iterator(x.value, function (err, v) {
|
||||
results[x.index] = v;
|
||||
callback(err);
|
||||
});
|
||||
}, function (err) {
|
||||
callback(err, results);
|
||||
});
|
||||
};
|
||||
async.map = doParallel(_asyncMap);
|
||||
async.mapSeries = doSeries(_asyncMap);
|
||||
|
||||
|
||||
// reduce only has a series version, as doing reduce in parallel won't
|
||||
// work in many situations.
|
||||
async.reduce = function (arr, memo, iterator, callback) {
|
||||
async.forEachSeries(arr, function (x, callback) {
|
||||
iterator(memo, x, function (err, v) {
|
||||
memo = v;
|
||||
callback(err);
|
||||
});
|
||||
}, function (err) {
|
||||
callback(err, memo);
|
||||
});
|
||||
};
|
||||
// inject alias
|
||||
async.inject = async.reduce;
|
||||
// foldl alias
|
||||
async.foldl = async.reduce;
|
||||
|
||||
async.reduceRight = function (arr, memo, iterator, callback) {
|
||||
var reversed = _map(arr, function (x) {
|
||||
return x;
|
||||
}).reverse();
|
||||
async.reduce(reversed, memo, iterator, callback);
|
||||
};
|
||||
// foldr alias
|
||||
async.foldr = async.reduceRight;
|
||||
|
||||
var _filter = function (eachfn, arr, iterator, callback) {
|
||||
var results = [];
|
||||
arr = _map(arr, function (x, i) {
|
||||
return {index: i, value: x};
|
||||
});
|
||||
eachfn(arr, function (x, callback) {
|
||||
iterator(x.value, function (v) {
|
||||
if (v) {
|
||||
results.push(x);
|
||||
}
|
||||
callback();
|
||||
});
|
||||
}, function (err) {
|
||||
callback(_map(results.sort(function (a, b) {
|
||||
return a.index - b.index;
|
||||
}), function (x) {
|
||||
return x.value;
|
||||
}));
|
||||
});
|
||||
};
|
||||
async.filter = doParallel(_filter);
|
||||
async.filterSeries = doSeries(_filter);
|
||||
// select alias
|
||||
async.select = async.filter;
|
||||
async.selectSeries = async.filterSeries;
|
||||
|
||||
var _reject = function (eachfn, arr, iterator, callback) {
|
||||
var results = [];
|
||||
arr = _map(arr, function (x, i) {
|
||||
return {index: i, value: x};
|
||||
});
|
||||
eachfn(arr, function (x, callback) {
|
||||
iterator(x.value, function (v) {
|
||||
if (!v) {
|
||||
results.push(x);
|
||||
}
|
||||
callback();
|
||||
});
|
||||
}, function (err) {
|
||||
callback(_map(results.sort(function (a, b) {
|
||||
return a.index - b.index;
|
||||
}), function (x) {
|
||||
return x.value;
|
||||
}));
|
||||
});
|
||||
};
|
||||
async.reject = doParallel(_reject);
|
||||
async.rejectSeries = doSeries(_reject);
|
||||
|
||||
var _detect = function (eachfn, arr, iterator, main_callback) {
|
||||
eachfn(arr, function (x, callback) {
|
||||
iterator(x, function (result) {
|
||||
if (result) {
|
||||
main_callback(x);
|
||||
}
|
||||
else {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
}, function (err) {
|
||||
main_callback();
|
||||
});
|
||||
};
|
||||
async.detect = doParallel(_detect);
|
||||
async.detectSeries = doSeries(_detect);
|
||||
|
||||
async.some = function (arr, iterator, main_callback) {
|
||||
async.forEach(arr, function (x, callback) {
|
||||
iterator(x, function (v) {
|
||||
if (v) {
|
||||
main_callback(true);
|
||||
main_callback = function () {};
|
||||
}
|
||||
callback();
|
||||
});
|
||||
}, function (err) {
|
||||
main_callback(false);
|
||||
});
|
||||
};
|
||||
// any alias
|
||||
async.any = async.some;
|
||||
|
||||
async.every = function (arr, iterator, main_callback) {
|
||||
async.forEach(arr, function (x, callback) {
|
||||
iterator(x, function (v) {
|
||||
if (!v) {
|
||||
main_callback(false);
|
||||
main_callback = function () {};
|
||||
}
|
||||
callback();
|
||||
});
|
||||
}, function (err) {
|
||||
main_callback(true);
|
||||
});
|
||||
};
|
||||
// all alias
|
||||
async.all = async.every;
|
||||
|
||||
async.sortBy = function (arr, iterator, callback) {
|
||||
async.map(arr, function (x, callback) {
|
||||
iterator(x, function (err, criteria) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
}
|
||||
else {
|
||||
callback(null, {value: x, criteria: criteria});
|
||||
}
|
||||
});
|
||||
}, function (err, results) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
else {
|
||||
var fn = function (left, right) {
|
||||
var a = left.criteria, b = right.criteria;
|
||||
return a < b ? -1 : a > b ? 1 : 0;
|
||||
};
|
||||
callback(null, _map(results.sort(fn), function (x) {
|
||||
return x.value;
|
||||
}));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
async.auto = function (tasks, callback) {
|
||||
callback = callback || function () {};
|
||||
var keys = _keys(tasks);
|
||||
if (!keys.length) {
|
||||
return callback(null);
|
||||
}
|
||||
|
||||
var completed = [];
|
||||
|
||||
var listeners = [];
|
||||
var addListener = function (fn) {
|
||||
listeners.unshift(fn);
|
||||
};
|
||||
var removeListener = function (fn) {
|
||||
for (var i = 0; i < listeners.length; i += 1) {
|
||||
if (listeners[i] === fn) {
|
||||
listeners.splice(i, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
var taskComplete = function () {
|
||||
_forEach(listeners, function (fn) {
|
||||
fn();
|
||||
});
|
||||
};
|
||||
|
||||
addListener(function () {
|
||||
if (completed.length === keys.length) {
|
||||
callback(null);
|
||||
}
|
||||
});
|
||||
|
||||
_forEach(keys, function (k) {
|
||||
var task = (tasks[k] instanceof Function) ? [tasks[k]]: tasks[k];
|
||||
var taskCallback = function (err) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
// stop subsequent errors hitting callback multiple times
|
||||
callback = function () {};
|
||||
}
|
||||
else {
|
||||
completed.push(k);
|
||||
taskComplete();
|
||||
}
|
||||
};
|
||||
var requires = task.slice(0, Math.abs(task.length - 1)) || [];
|
||||
var ready = function () {
|
||||
return _reduce(requires, function (a, x) {
|
||||
return (a && _indexOf(completed, x) !== -1);
|
||||
}, true);
|
||||
};
|
||||
if (ready()) {
|
||||
task[task.length - 1](taskCallback);
|
||||
}
|
||||
else {
|
||||
var listener = function () {
|
||||
if (ready()) {
|
||||
removeListener(listener);
|
||||
task[task.length - 1](taskCallback);
|
||||
}
|
||||
};
|
||||
addListener(listener);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
async.waterfall = function (tasks, callback) {
|
||||
if (!tasks.length) {
|
||||
return callback();
|
||||
}
|
||||
callback = callback || function () {};
|
||||
var wrapIterator = function (iterator) {
|
||||
return function (err) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
callback = function () {};
|
||||
}
|
||||
else {
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
var next = iterator.next();
|
||||
if (next) {
|
||||
args.push(wrapIterator(next));
|
||||
}
|
||||
else {
|
||||
args.push(callback);
|
||||
}
|
||||
async.nextTick(function () {
|
||||
iterator.apply(null, args);
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
wrapIterator(async.iterator(tasks))();
|
||||
};
|
||||
|
||||
async.parallel = function (tasks, callback) {
|
||||
callback = callback || function () {};
|
||||
if (tasks.constructor === Array) {
|
||||
async.map(tasks, function (fn, callback) {
|
||||
if (fn) {
|
||||
fn(function (err) {
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
if (args.length <= 1) {
|
||||
args = args[0];
|
||||
}
|
||||
callback.call(null, err, args || null);
|
||||
});
|
||||
}
|
||||
}, callback);
|
||||
}
|
||||
else {
|
||||
var results = {};
|
||||
async.forEach(_keys(tasks), function (k, callback) {
|
||||
tasks[k](function (err) {
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
if (args.length <= 1) {
|
||||
args = args[0];
|
||||
}
|
||||
results[k] = args;
|
||||
callback(err);
|
||||
});
|
||||
}, function (err) {
|
||||
callback(err, results);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
async.series = function (tasks, callback) {
|
||||
callback = callback || function () {};
|
||||
if (tasks.constructor === Array) {
|
||||
async.mapSeries(tasks, function (fn, callback) {
|
||||
if (fn) {
|
||||
fn(function (err) {
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
if (args.length <= 1) {
|
||||
args = args[0];
|
||||
}
|
||||
callback.call(null, err, args || null);
|
||||
});
|
||||
}
|
||||
}, callback);
|
||||
}
|
||||
else {
|
||||
var results = {};
|
||||
async.forEachSeries(_keys(tasks), function (k, callback) {
|
||||
tasks[k](function (err) {
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
if (args.length <= 1) {
|
||||
args = args[0];
|
||||
}
|
||||
results[k] = args;
|
||||
callback(err);
|
||||
});
|
||||
}, function (err) {
|
||||
callback(err, results);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
async.iterator = function (tasks) {
|
||||
var makeCallback = function (index) {
|
||||
var fn = function () {
|
||||
if (tasks.length) {
|
||||
tasks[index].apply(null, arguments);
|
||||
}
|
||||
return fn.next();
|
||||
};
|
||||
fn.next = function () {
|
||||
return (index < tasks.length - 1) ? makeCallback(index + 1): null;
|
||||
};
|
||||
return fn;
|
||||
};
|
||||
return makeCallback(0);
|
||||
};
|
||||
|
||||
async.apply = function (fn) {
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
return function () {
|
||||
return fn.apply(
|
||||
null, args.concat(Array.prototype.slice.call(arguments))
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
var _concat = function (eachfn, arr, fn, callback) {
|
||||
var r = [];
|
||||
eachfn(arr, function (x, cb) {
|
||||
fn(x, function (err, y) {
|
||||
r = r.concat(y || []);
|
||||
cb(err);
|
||||
});
|
||||
}, function (err) {
|
||||
callback(err, r);
|
||||
});
|
||||
};
|
||||
async.concat = doParallel(_concat);
|
||||
async.concatSeries = doSeries(_concat);
|
||||
|
||||
async.whilst = function (test, iterator, callback) {
|
||||
if (test()) {
|
||||
iterator(function (err) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
async.whilst(test, iterator, callback);
|
||||
});
|
||||
}
|
||||
else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
async.until = function (test, iterator, callback) {
|
||||
if (!test()) {
|
||||
iterator(function (err) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
async.until(test, iterator, callback);
|
||||
});
|
||||
}
|
||||
else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
async.queue = function (worker, concurrency) {
|
||||
var workers = 0;
|
||||
var tasks = [];
|
||||
var q = {
|
||||
concurrency: concurrency,
|
||||
push: function (data, callback) {
|
||||
tasks.push({data: data, callback: callback});
|
||||
async.nextTick(q.process);
|
||||
},
|
||||
process: function () {
|
||||
if (workers < q.concurrency && tasks.length) {
|
||||
var task = tasks.splice(0, 1)[0];
|
||||
workers += 1;
|
||||
worker(task.data, function () {
|
||||
workers -= 1;
|
||||
if (task.callback) {
|
||||
task.callback.apply(task, arguments);
|
||||
}
|
||||
q.process();
|
||||
});
|
||||
}
|
||||
},
|
||||
length: function () {
|
||||
return tasks.length;
|
||||
}
|
||||
};
|
||||
return q;
|
||||
};
|
||||
|
||||
var _console_fn = function (name) {
|
||||
return function (fn) {
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
fn.apply(null, args.concat([function (err) {
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
if (typeof console !== 'undefined') {
|
||||
if (err) {
|
||||
if (console.error) {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
else if (console[name]) {
|
||||
_forEach(args, function (x) {
|
||||
console[name](x);
|
||||
});
|
||||
}
|
||||
}
|
||||
}]));
|
||||
};
|
||||
};
|
||||
async.log = _console_fn('log');
|
||||
async.dir = _console_fn('dir');
|
||||
/*async.info = _console_fn('info');
|
||||
async.warn = _console_fn('warn');
|
||||
async.error = _console_fn('error');*/
|
||||
|
||||
async.memoize = function (fn, hasher) {
|
||||
var memo = {};
|
||||
hasher = hasher || function (x) {
|
||||
return x;
|
||||
};
|
||||
return function () {
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
var callback = args.pop();
|
||||
var key = hasher.apply(null, args);
|
||||
if (key in memo) {
|
||||
callback.apply(null, memo[key]);
|
||||
}
|
||||
else {
|
||||
fn.apply(null, args.concat([function () {
|
||||
memo[key] = arguments;
|
||||
callback.apply(null, arguments);
|
||||
}]));
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
}());
|
||||
55
bin/node_modules/nodeunit/deps/console.log.js
generated
vendored
55
bin/node_modules/nodeunit/deps/console.log.js
generated
vendored
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
A console.log that won't leave you hanging when node exits
|
||||
90% of this file was ripped from node.js
|
||||
|
||||
License: see: https://github.com/joyent/node/blob/master/lib/console.js
|
||||
*/
|
||||
|
||||
// console object
|
||||
var formatRegExp = /%[sdj]/g;
|
||||
function format(f) {
|
||||
var util = require('util');
|
||||
|
||||
if (typeof f !== 'string') {
|
||||
var objects = [];
|
||||
for (var i = 0; i < arguments.length; i++) {
|
||||
objects.push(util.inspect(arguments[i]));
|
||||
}
|
||||
return objects.join(' ');
|
||||
}
|
||||
|
||||
|
||||
var i = 1;
|
||||
var args = arguments;
|
||||
var str = String(f).replace(formatRegExp, function(x) {
|
||||
switch (x) {
|
||||
case '%s': return String(args[i++]);
|
||||
case '%d': return Number(args[i++]);
|
||||
case '%j': return JSON.stringify(args[i++]);
|
||||
default:
|
||||
return x;
|
||||
}
|
||||
});
|
||||
for (var len = args.length, x = args[i]; i < len; x = args[++i]) {
|
||||
if (x === null || typeof x !== 'object') {
|
||||
str += ' ' + x;
|
||||
} else {
|
||||
str += ' ' + util.inspect(x);
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
console.log = function() {
|
||||
var res = process.stdout.write(format.apply(this, arguments) + '\n');
|
||||
|
||||
// this is the first time stdout got backed up
|
||||
if (!res && !process.stdout.pendingWrite) {
|
||||
process.stdout.pendingWrite = true;
|
||||
|
||||
// magic sauce: keep node alive until stdout has flushed
|
||||
process.stdout.once('drain', function () {
|
||||
process.stdout.draining = false;
|
||||
});
|
||||
}
|
||||
};
|
||||
125
bin/node_modules/nodeunit/deps/ejs.js
generated
vendored
125
bin/node_modules/nodeunit/deps/ejs.js
generated
vendored
@@ -1,125 +0,0 @@
|
||||
|
||||
/*!
|
||||
* EJS
|
||||
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var sys = require('sys');
|
||||
|
||||
/**
|
||||
* Library version.
|
||||
*/
|
||||
|
||||
exports.version = '0.0.3';
|
||||
|
||||
/**
|
||||
* Intermediate js cache.
|
||||
*
|
||||
* @type Object
|
||||
*/
|
||||
|
||||
var cache = {};
|
||||
|
||||
/**
|
||||
* Clear intermediate js cache.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.clearCache = function(){
|
||||
cache = {};
|
||||
};
|
||||
|
||||
/**
|
||||
* Escape the given string of `html`.
|
||||
*
|
||||
* @param {String} html
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function escape(html){
|
||||
return String(html)
|
||||
.replace(/&(?!\w+;)/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/"/g, '"');
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the given `str` of ejs, returning the function body.
|
||||
*
|
||||
* @param {String} str
|
||||
* @return {String}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
var parse = exports.parse = function(str){
|
||||
return 'var buf = [];\n'
|
||||
+ "with (locals) {\nbuf.push('"
|
||||
+ String(str)
|
||||
.replace(/[\r\t]/g, " ")
|
||||
.replace(/\n/g, "\\n")
|
||||
.split("<%").join("\t")
|
||||
.replace(/((^|%>)[^\t]*)'/g, "$1\r")
|
||||
.replace(/\t=(.*?)%>/g, "', escape($1) ,'")
|
||||
.replace(/\t-(.*?)%>/g, "', $1 ,'")
|
||||
.split("\t").join("');")
|
||||
.split("%>").join("buf.push('")
|
||||
.split("\r").join("\\'")
|
||||
+ "');\n}\nreturn buf.join('');";
|
||||
};
|
||||
|
||||
/**
|
||||
* Compile the given `str` of ejs into a `Function`.
|
||||
*
|
||||
* @param {String} str
|
||||
* @param {Object} options
|
||||
* @return {Function}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
var compile = exports.compile = function(str, options){
|
||||
if (options.debug) sys.puts(parse(str));
|
||||
return new Function('locals, escape', parse(str));
|
||||
};
|
||||
|
||||
/**
|
||||
* Render the given `str` of ejs.
|
||||
*
|
||||
* Options:
|
||||
*
|
||||
* - `locals` Local variables object
|
||||
* - `cache` Compiled functions are cached, requires `filename`
|
||||
* - `filename` Used by `cache` to key caches
|
||||
* - `context|scope` Function execution context
|
||||
* - `debug` Output generated function body
|
||||
*
|
||||
* @param {String} str
|
||||
* @param {Object} options
|
||||
* @return {String}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.render = function(str, options){
|
||||
var fn,
|
||||
options = options || {};
|
||||
if (options.cache) {
|
||||
if (options.filename) {
|
||||
fn = cache[options.filename] = compile(str, options);
|
||||
} else {
|
||||
throw new Error('"cache" option requires "filename".');
|
||||
}
|
||||
} else {
|
||||
fn = compile(str, options);
|
||||
}
|
||||
return fn.call(
|
||||
options.context || options.scope,
|
||||
options.locals || {},
|
||||
escape);
|
||||
};
|
||||
483
bin/node_modules/nodeunit/deps/json2.js
generated
vendored
483
bin/node_modules/nodeunit/deps/json2.js
generated
vendored
@@ -1,483 +0,0 @@
|
||||
/*
|
||||
http://www.JSON.org/json2.js
|
||||
2010-11-17
|
||||
|
||||
Public Domain.
|
||||
|
||||
NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
|
||||
|
||||
See http://www.JSON.org/js.html
|
||||
|
||||
|
||||
This code should be minified before deployment.
|
||||
See http://javascript.crockford.com/jsmin.html
|
||||
|
||||
USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
|
||||
NOT CONTROL.
|
||||
|
||||
|
||||
This file creates a global JSON object containing two methods: stringify
|
||||
and parse.
|
||||
|
||||
JSON.stringify(value, replacer, space)
|
||||
value any JavaScript value, usually an object or array.
|
||||
|
||||
replacer an optional parameter that determines how object
|
||||
values are stringified for objects. It can be a
|
||||
function or an array of strings.
|
||||
|
||||
space an optional parameter that specifies the indentation
|
||||
of nested structures. If it is omitted, the text will
|
||||
be packed without extra whitespace. If it is a number,
|
||||
it will specify the number of spaces to indent at each
|
||||
level. If it is a string (such as '\t' or ' '),
|
||||
it contains the characters used to indent at each level.
|
||||
|
||||
This method produces a JSON text from a JavaScript value.
|
||||
|
||||
When an object value is found, if the object contains a toJSON
|
||||
method, its toJSON method will be called and the result will be
|
||||
stringified. A toJSON method does not serialize: it returns the
|
||||
value represented by the name/value pair that should be serialized,
|
||||
or undefined if nothing should be serialized. The toJSON method
|
||||
will be passed the key associated with the value, and this will be
|
||||
bound to the value
|
||||
|
||||
For example, this would serialize Dates as ISO strings.
|
||||
|
||||
Date.prototype.toJSON = function (key) {
|
||||
function f(n) {
|
||||
// Format integers to have at least two digits.
|
||||
return n < 10 ? '0' + n : n;
|
||||
}
|
||||
|
||||
return this.getUTCFullYear() + '-' +
|
||||
f(this.getUTCMonth() + 1) + '-' +
|
||||
f(this.getUTCDate()) + 'T' +
|
||||
f(this.getUTCHours()) + ':' +
|
||||
f(this.getUTCMinutes()) + ':' +
|
||||
f(this.getUTCSeconds()) + 'Z';
|
||||
};
|
||||
|
||||
You can provide an optional replacer method. It will be passed the
|
||||
key and value of each member, with this bound to the containing
|
||||
object. The value that is returned from your method will be
|
||||
serialized. If your method returns undefined, then the member will
|
||||
be excluded from the serialization.
|
||||
|
||||
If the replacer parameter is an array of strings, then it will be
|
||||
used to select the members to be serialized. It filters the results
|
||||
such that only members with keys listed in the replacer array are
|
||||
stringified.
|
||||
|
||||
Values that do not have JSON representations, such as undefined or
|
||||
functions, will not be serialized. Such values in objects will be
|
||||
dropped; in arrays they will be replaced with null. You can use
|
||||
a replacer function to replace those with JSON values.
|
||||
JSON.stringify(undefined) returns undefined.
|
||||
|
||||
The optional space parameter produces a stringification of the
|
||||
value that is filled with line breaks and indentation to make it
|
||||
easier to read.
|
||||
|
||||
If the space parameter is a non-empty string, then that string will
|
||||
be used for indentation. If the space parameter is a number, then
|
||||
the indentation will be that many spaces.
|
||||
|
||||
Example:
|
||||
|
||||
text = JSON.stringify(['e', {pluribus: 'unum'}]);
|
||||
// text is '["e",{"pluribus":"unum"}]'
|
||||
|
||||
|
||||
text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
|
||||
// text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
|
||||
|
||||
text = JSON.stringify([new Date()], function (key, value) {
|
||||
return this[key] instanceof Date ?
|
||||
'Date(' + this[key] + ')' : value;
|
||||
});
|
||||
// text is '["Date(---current time---)"]'
|
||||
|
||||
|
||||
JSON.parse(text, reviver)
|
||||
This method parses a JSON text to produce an object or array.
|
||||
It can throw a SyntaxError exception.
|
||||
|
||||
The optional reviver parameter is a function that can filter and
|
||||
transform the results. It receives each of the keys and values,
|
||||
and its return value is used instead of the original value.
|
||||
If it returns what it received, then the structure is not modified.
|
||||
If it returns undefined then the member is deleted.
|
||||
|
||||
Example:
|
||||
|
||||
// Parse the text. Values that look like ISO date strings will
|
||||
// be converted to Date objects.
|
||||
|
||||
myData = JSON.parse(text, function (key, value) {
|
||||
var a;
|
||||
if (typeof value === 'string') {
|
||||
a =
|
||||
/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
|
||||
if (a) {
|
||||
return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
|
||||
+a[5], +a[6]));
|
||||
}
|
||||
}
|
||||
return value;
|
||||
});
|
||||
|
||||
myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
|
||||
var d;
|
||||
if (typeof value === 'string' &&
|
||||
value.slice(0, 5) === 'Date(' &&
|
||||
value.slice(-1) === ')') {
|
||||
d = new Date(value.slice(5, -1));
|
||||
if (d) {
|
||||
return d;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
});
|
||||
|
||||
|
||||
This is a reference implementation. You are free to copy, modify, or
|
||||
redistribute.
|
||||
*/
|
||||
|
||||
/*jslint evil: true, strict: false, regexp: false */
|
||||
|
||||
/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
|
||||
call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
|
||||
getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
|
||||
lastIndex, length, parse, prototype, push, replace, slice, stringify,
|
||||
test, toJSON, toString, valueOf
|
||||
*/
|
||||
|
||||
|
||||
// Create a JSON object only if one does not already exist. We create the
|
||||
// methods in a closure to avoid creating global variables.
|
||||
|
||||
if (!this.JSON) {
|
||||
this.JSON = {};
|
||||
}
|
||||
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
function f(n) {
|
||||
// Format integers to have at least two digits.
|
||||
return n < 10 ? '0' + n : n;
|
||||
}
|
||||
|
||||
if (typeof Date.prototype.toJSON !== 'function') {
|
||||
|
||||
Date.prototype.toJSON = function (key) {
|
||||
|
||||
return isFinite(this.valueOf()) ?
|
||||
this.getUTCFullYear() + '-' +
|
||||
f(this.getUTCMonth() + 1) + '-' +
|
||||
f(this.getUTCDate()) + 'T' +
|
||||
f(this.getUTCHours()) + ':' +
|
||||
f(this.getUTCMinutes()) + ':' +
|
||||
f(this.getUTCSeconds()) + 'Z' : null;
|
||||
};
|
||||
|
||||
String.prototype.toJSON =
|
||||
Number.prototype.toJSON =
|
||||
Boolean.prototype.toJSON = function (key) {
|
||||
return this.valueOf();
|
||||
};
|
||||
}
|
||||
|
||||
var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
|
||||
escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
|
||||
gap,
|
||||
indent,
|
||||
meta = { // table of character substitutions
|
||||
'\b': '\\b',
|
||||
'\t': '\\t',
|
||||
'\n': '\\n',
|
||||
'\f': '\\f',
|
||||
'\r': '\\r',
|
||||
'"' : '\\"',
|
||||
'\\': '\\\\'
|
||||
},
|
||||
rep;
|
||||
|
||||
|
||||
function quote(string) {
|
||||
|
||||
// If the string contains no control characters, no quote characters, and no
|
||||
// backslash characters, then we can safely slap some quotes around it.
|
||||
// Otherwise we must also replace the offending characters with safe escape
|
||||
// sequences.
|
||||
|
||||
escapable.lastIndex = 0;
|
||||
return escapable.test(string) ?
|
||||
'"' + string.replace(escapable, function (a) {
|
||||
var c = meta[a];
|
||||
return typeof c === 'string' ? c :
|
||||
'\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
|
||||
}) + '"' :
|
||||
'"' + string + '"';
|
||||
}
|
||||
|
||||
|
||||
function str(key, holder) {
|
||||
|
||||
// Produce a string from holder[key].
|
||||
|
||||
var i, // The loop counter.
|
||||
k, // The member key.
|
||||
v, // The member value.
|
||||
length,
|
||||
mind = gap,
|
||||
partial,
|
||||
value = holder[key];
|
||||
|
||||
// If the value has a toJSON method, call it to obtain a replacement value.
|
||||
|
||||
if (value && typeof value === 'object' &&
|
||||
typeof value.toJSON === 'function') {
|
||||
value = value.toJSON(key);
|
||||
}
|
||||
|
||||
// If we were called with a replacer function, then call the replacer to
|
||||
// obtain a replacement value.
|
||||
|
||||
if (typeof rep === 'function') {
|
||||
value = rep.call(holder, key, value);
|
||||
}
|
||||
|
||||
// What happens next depends on the value's type.
|
||||
|
||||
switch (typeof value) {
|
||||
case 'string':
|
||||
return quote(value);
|
||||
|
||||
case 'number':
|
||||
|
||||
// JSON numbers must be finite. Encode non-finite numbers as null.
|
||||
|
||||
return isFinite(value) ? String(value) : 'null';
|
||||
|
||||
case 'boolean':
|
||||
case 'null':
|
||||
|
||||
// If the value is a boolean or null, convert it to a string. Note:
|
||||
// typeof null does not produce 'null'. The case is included here in
|
||||
// the remote chance that this gets fixed someday.
|
||||
|
||||
return String(value);
|
||||
|
||||
// If the type is 'object', we might be dealing with an object or an array or
|
||||
// null.
|
||||
|
||||
case 'object':
|
||||
|
||||
// Due to a specification blunder in ECMAScript, typeof null is 'object',
|
||||
// so watch out for that case.
|
||||
|
||||
if (!value) {
|
||||
return 'null';
|
||||
}
|
||||
|
||||
// Make an array to hold the partial results of stringifying this object value.
|
||||
|
||||
gap += indent;
|
||||
partial = [];
|
||||
|
||||
// Is the value an array?
|
||||
|
||||
if (Object.prototype.toString.apply(value) === '[object Array]') {
|
||||
|
||||
// The value is an array. Stringify every element. Use null as a placeholder
|
||||
// for non-JSON values.
|
||||
|
||||
length = value.length;
|
||||
for (i = 0; i < length; i += 1) {
|
||||
partial[i] = str(i, value) || 'null';
|
||||
}
|
||||
|
||||
// Join all of the elements together, separated with commas, and wrap them in
|
||||
// brackets.
|
||||
|
||||
v = partial.length === 0 ? '[]' :
|
||||
gap ? '[\n' + gap +
|
||||
partial.join(',\n' + gap) + '\n' +
|
||||
mind + ']' :
|
||||
'[' + partial.join(',') + ']';
|
||||
gap = mind;
|
||||
return v;
|
||||
}
|
||||
|
||||
// If the replacer is an array, use it to select the members to be stringified.
|
||||
|
||||
if (rep && typeof rep === 'object') {
|
||||
length = rep.length;
|
||||
for (i = 0; i < length; i += 1) {
|
||||
k = rep[i];
|
||||
if (typeof k === 'string') {
|
||||
v = str(k, value);
|
||||
if (v) {
|
||||
partial.push(quote(k) + (gap ? ': ' : ':') + v);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
// Otherwise, iterate through all of the keys in the object.
|
||||
|
||||
for (k in value) {
|
||||
if (Object.hasOwnProperty.call(value, k)) {
|
||||
v = str(k, value);
|
||||
if (v) {
|
||||
partial.push(quote(k) + (gap ? ': ' : ':') + v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Join all of the member texts together, separated with commas,
|
||||
// and wrap them in braces.
|
||||
|
||||
v = partial.length === 0 ? '{}' :
|
||||
gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
|
||||
mind + '}' : '{' + partial.join(',') + '}';
|
||||
gap = mind;
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
// If the JSON object does not yet have a stringify method, give it one.
|
||||
|
||||
if (typeof JSON.stringify !== 'function') {
|
||||
JSON.stringify = function (value, replacer, space) {
|
||||
|
||||
// The stringify method takes a value and an optional replacer, and an optional
|
||||
// space parameter, and returns a JSON text. The replacer can be a function
|
||||
// that can replace values, or an array of strings that will select the keys.
|
||||
// A default replacer method can be provided. Use of the space parameter can
|
||||
// produce text that is more easily readable.
|
||||
|
||||
var i;
|
||||
gap = '';
|
||||
indent = '';
|
||||
|
||||
// If the space parameter is a number, make an indent string containing that
|
||||
// many spaces.
|
||||
|
||||
if (typeof space === 'number') {
|
||||
for (i = 0; i < space; i += 1) {
|
||||
indent += ' ';
|
||||
}
|
||||
|
||||
// If the space parameter is a string, it will be used as the indent string.
|
||||
|
||||
} else if (typeof space === 'string') {
|
||||
indent = space;
|
||||
}
|
||||
|
||||
// If there is a replacer, it must be a function or an array.
|
||||
// Otherwise, throw an error.
|
||||
|
||||
rep = replacer;
|
||||
if (replacer && typeof replacer !== 'function' &&
|
||||
(typeof replacer !== 'object' ||
|
||||
typeof replacer.length !== 'number')) {
|
||||
throw new Error('JSON.stringify');
|
||||
}
|
||||
|
||||
// Make a fake root object containing our value under the key of ''.
|
||||
// Return the result of stringifying the value.
|
||||
|
||||
return str('', {'': value});
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// If the JSON object does not yet have a parse method, give it one.
|
||||
|
||||
if (typeof JSON.parse !== 'function') {
|
||||
JSON.parse = function (text, reviver) {
|
||||
|
||||
// The parse method takes a text and an optional reviver function, and returns
|
||||
// a JavaScript value if the text is a valid JSON text.
|
||||
|
||||
var j;
|
||||
|
||||
function walk(holder, key) {
|
||||
|
||||
// The walk method is used to recursively walk the resulting structure so
|
||||
// that modifications can be made.
|
||||
|
||||
var k, v, value = holder[key];
|
||||
if (value && typeof value === 'object') {
|
||||
for (k in value) {
|
||||
if (Object.hasOwnProperty.call(value, k)) {
|
||||
v = walk(value, k);
|
||||
if (v !== undefined) {
|
||||
value[k] = v;
|
||||
} else {
|
||||
delete value[k];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return reviver.call(holder, key, value);
|
||||
}
|
||||
|
||||
|
||||
// Parsing happens in four stages. In the first stage, we replace certain
|
||||
// Unicode characters with escape sequences. JavaScript handles many characters
|
||||
// incorrectly, either silently deleting them, or treating them as line endings.
|
||||
|
||||
text = String(text);
|
||||
cx.lastIndex = 0;
|
||||
if (cx.test(text)) {
|
||||
text = text.replace(cx, function (a) {
|
||||
return '\\u' +
|
||||
('0000' + a.charCodeAt(0).toString(16)).slice(-4);
|
||||
});
|
||||
}
|
||||
|
||||
// In the second stage, we run the text against regular expressions that look
|
||||
// for non-JSON patterns. We are especially concerned with '()' and 'new'
|
||||
// because they can cause invocation, and '=' because it can cause mutation.
|
||||
// But just to be safe, we want to reject all unexpected forms.
|
||||
|
||||
// We split the second stage into 4 regexp operations in order to work around
|
||||
// crippling inefficiencies in IE's and Safari's regexp engines. First we
|
||||
// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
|
||||
// replace all simple value tokens with ']' characters. Third, we delete all
|
||||
// open brackets that follow a colon or comma or that begin the text. Finally,
|
||||
// we look to see that the remaining characters are only whitespace or ']' or
|
||||
// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
|
||||
|
||||
if (/^[\],:{}\s]*$/
|
||||
.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
|
||||
.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
|
||||
.replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
|
||||
|
||||
// In the third stage we use the eval function to compile the text into a
|
||||
// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
|
||||
// in JavaScript: it can begin a block or an object literal. We wrap the text
|
||||
// in parens to eliminate the ambiguity.
|
||||
|
||||
j = eval('(' + text + ')');
|
||||
|
||||
// In the optional fourth stage, we recursively walk the new structure, passing
|
||||
// each name/value pair to a reviver function for possible transformation.
|
||||
|
||||
return typeof reviver === 'function' ?
|
||||
walk({'': j}, '') : j;
|
||||
}
|
||||
|
||||
// If the text is not JSON parseable, then a SyntaxError is thrown.
|
||||
|
||||
throw new SyntaxError('JSON.parse');
|
||||
};
|
||||
}
|
||||
}());
|
||||
60
bin/node_modules/nodeunit/doc/nodeunit.md
generated
vendored
60
bin/node_modules/nodeunit/doc/nodeunit.md
generated
vendored
@@ -1,60 +0,0 @@
|
||||
nodeunit(1) -- simple node.js unit testing tool
|
||||
===============================================
|
||||
|
||||
## SYNOPSIS
|
||||
|
||||
nodeunit [options] <file-or-directory> [<file-or-directory> ...]
|
||||
|
||||
## DESCRIPTION
|
||||
|
||||
Nodeunit is a simple unit testing tool based on the node.js assert module.
|
||||
|
||||
* Simple to use
|
||||
* Just export the tests from a module
|
||||
* Helps you avoid common pitfalls when testing asynchronous code
|
||||
* Easy to add test cases with setUp and tearDown functions if you wish
|
||||
* Allows the use of mocks and stubs
|
||||
|
||||
## OPTIONS
|
||||
|
||||
__--config FILE__:
|
||||
Load config options from a JSON file, allows the customisation
|
||||
of color schemes for the default test reporter etc.
|
||||
See bin/nodeunit.json for current available options.
|
||||
|
||||
__--reporter FILE__:
|
||||
You can set the test reporter to a custom module or on of the modules
|
||||
in nodeunit/lib/reporters, when omitted, the default test runner is used.
|
||||
|
||||
__--list-reporters__:
|
||||
List available build-in reporters.
|
||||
|
||||
__-h__, __--help__:
|
||||
Display the help and exit.
|
||||
|
||||
__-v__, __--version__:
|
||||
Output version information and exit.
|
||||
|
||||
__<file-or-directory>__:
|
||||
You can run nodeunit on specific files or on all *\*.js* files inside
|
||||
a directory.
|
||||
|
||||
## AUTHORS
|
||||
|
||||
Written by Caolan McMahon and other nodeunit contributors.
|
||||
Contributors list: <http://github.com/caolan/nodeunit/contributors>.
|
||||
|
||||
## REPORTING BUGS
|
||||
|
||||
Report nodeunit bugs to <http://github.com/caolan/nodeunit/issues>.
|
||||
|
||||
## COPYRIGHT
|
||||
|
||||
Copyright © 2010 Caolan McMahon.
|
||||
Nodeunit has been released under the MIT license:
|
||||
<http://github.com/caolan/nodeunit/raw/master/LICENSE>.
|
||||
|
||||
## SEE ALSO
|
||||
|
||||
node(1)
|
||||
|
||||
1757
bin/node_modules/nodeunit/examples/browser/nodeunit.js
generated
vendored
1757
bin/node_modules/nodeunit/examples/browser/nodeunit.js
generated
vendored
File diff suppressed because it is too large
Load Diff
12
bin/node_modules/nodeunit/examples/browser/suite1.js
generated
vendored
12
bin/node_modules/nodeunit/examples/browser/suite1.js
generated
vendored
@@ -1,12 +0,0 @@
|
||||
this.suite1 = {
|
||||
'test one': function (test) {
|
||||
test.ok(true, 'everythings ok');
|
||||
setTimeout(function () {
|
||||
test.done();
|
||||
}, 10);
|
||||
},
|
||||
'apples and oranges': function (test) {
|
||||
test.equal('apples', 'oranges', 'comparing apples and oranges');
|
||||
test.done();
|
||||
}
|
||||
};
|
||||
13
bin/node_modules/nodeunit/examples/browser/suite2.js
generated
vendored
13
bin/node_modules/nodeunit/examples/browser/suite2.js
generated
vendored
@@ -1,13 +0,0 @@
|
||||
this.suite2 = {
|
||||
'another test': function (test) {
|
||||
setTimeout(function () {
|
||||
// lots of assertions
|
||||
test.ok(true, 'everythings ok');
|
||||
test.ok(true, 'everythings ok');
|
||||
test.ok(true, 'everythings ok');
|
||||
test.ok(true, 'everythings ok');
|
||||
test.ok(true, 'everythings ok');
|
||||
test.done();
|
||||
}, 10);
|
||||
}
|
||||
};
|
||||
16
bin/node_modules/nodeunit/examples/browser/test.html
generated
vendored
16
bin/node_modules/nodeunit/examples/browser/test.html
generated
vendored
@@ -1,16 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Example tests</title>
|
||||
<script src="nodeunit.js"></script>
|
||||
<script src="suite1.js"></script>
|
||||
<script src="suite2.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
nodeunit.run({
|
||||
'suite1': suite1,
|
||||
'suite2': suite2
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
BIN
bin/node_modules/nodeunit/img/example_fail.png
generated
vendored
BIN
bin/node_modules/nodeunit/img/example_fail.png
generated
vendored
Binary file not shown.
|
Before Width: | Height: | Size: 38 KiB |
BIN
bin/node_modules/nodeunit/img/example_pass.png
generated
vendored
BIN
bin/node_modules/nodeunit/img/example_pass.png
generated
vendored
Binary file not shown.
|
Before Width: | Height: | Size: 14 KiB |
3
bin/node_modules/nodeunit/index.js
generated
vendored
3
bin/node_modules/nodeunit/index.js
generated
vendored
@@ -1,3 +0,0 @@
|
||||
// This file is just added for convenience so this repository can be
|
||||
// directly checked out into a project's deps folder
|
||||
module.exports = require('./lib/nodeunit');
|
||||
316
bin/node_modules/nodeunit/lib/assert.js
generated
vendored
316
bin/node_modules/nodeunit/lib/assert.js
generated
vendored
@@ -1,316 +0,0 @@
|
||||
/**
|
||||
* This file is based on the node.js assert module, but with some small
|
||||
* changes for browser-compatibility
|
||||
* THIS FILE SHOULD BE BROWSER-COMPATIBLE JS!
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Added for browser compatibility
|
||||
*/
|
||||
|
||||
var _keys = function(obj){
|
||||
if(Object.keys) return Object.keys(obj);
|
||||
var keys = [];
|
||||
for(var k in obj){
|
||||
if(obj.hasOwnProperty(k)) keys.push(k);
|
||||
}
|
||||
return keys;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// http://wiki.commonjs.org/wiki/Unit_Testing/1.0
|
||||
//
|
||||
// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8!
|
||||
//
|
||||
// Originally from narwhal.js (http://narwhaljs.org)
|
||||
// Copyright (c) 2009 Thomas Robinson <280north.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the 'Software'), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
var pSlice = Array.prototype.slice;
|
||||
|
||||
// 1. The assert module provides functions that throw
|
||||
// AssertionError's when particular conditions are not met. The
|
||||
// assert module must conform to the following interface.
|
||||
|
||||
var assert = exports;
|
||||
|
||||
// 2. The AssertionError is defined in assert.
|
||||
// new assert.AssertionError({message: message, actual: actual, expected: expected})
|
||||
|
||||
assert.AssertionError = function AssertionError (options) {
|
||||
this.name = "AssertionError";
|
||||
this.message = options.message;
|
||||
this.actual = options.actual;
|
||||
this.expected = options.expected;
|
||||
this.operator = options.operator;
|
||||
var stackStartFunction = options.stackStartFunction || fail;
|
||||
|
||||
if (Error.captureStackTrace) {
|
||||
Error.captureStackTrace(this, stackStartFunction);
|
||||
}
|
||||
};
|
||||
// code from util.inherits in node
|
||||
assert.AssertionError.super_ = Error;
|
||||
|
||||
|
||||
// EDITED FOR BROWSER COMPATIBILITY: replaced Object.create call
|
||||
// TODO: test what effect this may have
|
||||
var ctor = function () { this.constructor = assert.AssertionError; };
|
||||
ctor.prototype = Error.prototype;
|
||||
assert.AssertionError.prototype = new ctor();
|
||||
|
||||
|
||||
assert.AssertionError.prototype.toString = function() {
|
||||
if (this.message) {
|
||||
return [this.name+":", this.message].join(' ');
|
||||
} else {
|
||||
return [ this.name+":"
|
||||
, JSON.stringify(this.expected )
|
||||
, this.operator
|
||||
, JSON.stringify(this.actual)
|
||||
].join(" ");
|
||||
}
|
||||
};
|
||||
|
||||
// assert.AssertionError instanceof Error
|
||||
|
||||
assert.AssertionError.__proto__ = Error.prototype;
|
||||
|
||||
// At present only the three keys mentioned above are used and
|
||||
// understood by the spec. Implementations or sub modules can pass
|
||||
// other keys to the AssertionError's constructor - they will be
|
||||
// ignored.
|
||||
|
||||
// 3. All of the following functions must throw an AssertionError
|
||||
// when a corresponding condition is not met, with a message that
|
||||
// may be undefined if not provided. All assertion methods provide
|
||||
// both the actual and expected values to the assertion error for
|
||||
// display purposes.
|
||||
|
||||
function fail(actual, expected, message, operator, stackStartFunction) {
|
||||
throw new assert.AssertionError({
|
||||
message: message,
|
||||
actual: actual,
|
||||
expected: expected,
|
||||
operator: operator,
|
||||
stackStartFunction: stackStartFunction
|
||||
});
|
||||
}
|
||||
|
||||
// EXTENSION! allows for well behaved errors defined elsewhere.
|
||||
assert.fail = fail;
|
||||
|
||||
// 4. Pure assertion tests whether a value is truthy, as determined
|
||||
// by !!guard.
|
||||
// assert.ok(guard, message_opt);
|
||||
// This statement is equivalent to assert.equal(true, guard,
|
||||
// message_opt);. To test strictly for the value true, use
|
||||
// assert.strictEqual(true, guard, message_opt);.
|
||||
|
||||
assert.ok = function ok(value, message) {
|
||||
if (!!!value) fail(value, true, message, "==", assert.ok);
|
||||
};
|
||||
|
||||
// 5. The equality assertion tests shallow, coercive equality with
|
||||
// ==.
|
||||
// assert.equal(actual, expected, message_opt);
|
||||
|
||||
assert.equal = function equal(actual, expected, message) {
|
||||
if (actual != expected) fail(actual, expected, message, "==", assert.equal);
|
||||
};
|
||||
|
||||
// 6. The non-equality assertion tests for whether two objects are not equal
|
||||
// with != assert.notEqual(actual, expected, message_opt);
|
||||
|
||||
assert.notEqual = function notEqual(actual, expected, message) {
|
||||
if (actual == expected) {
|
||||
fail(actual, expected, message, "!=", assert.notEqual);
|
||||
}
|
||||
};
|
||||
|
||||
// 7. The equivalence assertion tests a deep equality relation.
|
||||
// assert.deepEqual(actual, expected, message_opt);
|
||||
|
||||
assert.deepEqual = function deepEqual(actual, expected, message) {
|
||||
if (!_deepEqual(actual, expected)) {
|
||||
fail(actual, expected, message, "deepEqual", assert.deepEqual);
|
||||
}
|
||||
};
|
||||
|
||||
function _deepEqual(actual, expected) {
|
||||
// 7.1. All identical values are equivalent, as determined by ===.
|
||||
if (actual === expected) {
|
||||
return true;
|
||||
// 7.2. If the expected value is a Date object, the actual value is
|
||||
// equivalent if it is also a Date object that refers to the same time.
|
||||
} else if (actual instanceof Date && expected instanceof Date) {
|
||||
return actual.getTime() === expected.getTime();
|
||||
|
||||
// 7.3. Other pairs that do not both pass typeof value == "object",
|
||||
// equivalence is determined by ==.
|
||||
} else if (typeof actual != 'object' && typeof expected != 'object') {
|
||||
return actual == expected;
|
||||
|
||||
// 7.4. For all other Object pairs, including Array objects, equivalence is
|
||||
// determined by having the same number of owned properties (as verified
|
||||
// with Object.prototype.hasOwnProperty.call), the same set of keys
|
||||
// (although not necessarily the same order), equivalent values for every
|
||||
// corresponding key, and an identical "prototype" property. Note: this
|
||||
// accounts for both named and indexed properties on Arrays.
|
||||
} else {
|
||||
return objEquiv(actual, expected);
|
||||
}
|
||||
}
|
||||
|
||||
function isUndefinedOrNull (value) {
|
||||
return value === null || value === undefined;
|
||||
}
|
||||
|
||||
function isArguments (object) {
|
||||
return Object.prototype.toString.call(object) == '[object Arguments]';
|
||||
}
|
||||
|
||||
function objEquiv (a, b) {
|
||||
if (isUndefinedOrNull(a) || isUndefinedOrNull(b))
|
||||
return false;
|
||||
// an identical "prototype" property.
|
||||
if (a.prototype !== b.prototype) return false;
|
||||
//~~~I've managed to break Object.keys through screwy arguments passing.
|
||||
// Converting to array solves the problem.
|
||||
if (isArguments(a)) {
|
||||
if (!isArguments(b)) {
|
||||
return false;
|
||||
}
|
||||
a = pSlice.call(a);
|
||||
b = pSlice.call(b);
|
||||
return _deepEqual(a, b);
|
||||
}
|
||||
try{
|
||||
var ka = _keys(a),
|
||||
kb = _keys(b),
|
||||
key, i;
|
||||
} catch (e) {//happens when one is a string literal and the other isn't
|
||||
return false;
|
||||
}
|
||||
// having the same number of owned properties (keys incorporates hasOwnProperty)
|
||||
if (ka.length != kb.length)
|
||||
return false;
|
||||
//the same set of keys (although not necessarily the same order),
|
||||
ka.sort();
|
||||
kb.sort();
|
||||
//~~~cheap key test
|
||||
for (i = ka.length - 1; i >= 0; i--) {
|
||||
if (ka[i] != kb[i])
|
||||
return false;
|
||||
}
|
||||
//equivalent values for every corresponding key, and
|
||||
//~~~possibly expensive deep test
|
||||
for (i = ka.length - 1; i >= 0; i--) {
|
||||
key = ka[i];
|
||||
if (!_deepEqual(a[key], b[key] ))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// 8. The non-equivalence assertion tests for any deep inequality.
|
||||
// assert.notDeepEqual(actual, expected, message_opt);
|
||||
|
||||
assert.notDeepEqual = function notDeepEqual(actual, expected, message) {
|
||||
if (_deepEqual(actual, expected)) {
|
||||
fail(actual, expected, message, "notDeepEqual", assert.notDeepEqual);
|
||||
}
|
||||
};
|
||||
|
||||
// 9. The strict equality assertion tests strict equality, as determined by ===.
|
||||
// assert.strictEqual(actual, expected, message_opt);
|
||||
|
||||
assert.strictEqual = function strictEqual(actual, expected, message) {
|
||||
if (actual !== expected) {
|
||||
fail(actual, expected, message, "===", assert.strictEqual);
|
||||
}
|
||||
};
|
||||
|
||||
// 10. The strict non-equality assertion tests for strict inequality, as determined by !==.
|
||||
// assert.notStrictEqual(actual, expected, message_opt);
|
||||
|
||||
assert.notStrictEqual = function notStrictEqual(actual, expected, message) {
|
||||
if (actual === expected) {
|
||||
fail(actual, expected, message, "!==", assert.notStrictEqual);
|
||||
}
|
||||
};
|
||||
|
||||
function _throws (shouldThrow, block, err, message) {
|
||||
var exception = null,
|
||||
threw = false,
|
||||
typematters = true;
|
||||
|
||||
message = message || "";
|
||||
|
||||
//handle optional arguments
|
||||
if (arguments.length == 3) {
|
||||
if (typeof(err) == "string") {
|
||||
message = err;
|
||||
typematters = false;
|
||||
}
|
||||
} else if (arguments.length == 2) {
|
||||
typematters = false;
|
||||
}
|
||||
|
||||
try {
|
||||
block();
|
||||
} catch (e) {
|
||||
threw = true;
|
||||
exception = e;
|
||||
}
|
||||
|
||||
if (shouldThrow && !threw) {
|
||||
fail( "Missing expected exception"
|
||||
+ (err && err.name ? " ("+err.name+")." : '.')
|
||||
+ (message ? " " + message : "")
|
||||
);
|
||||
}
|
||||
if (!shouldThrow && threw && typematters && exception instanceof err) {
|
||||
fail( "Got unwanted exception"
|
||||
+ (err && err.name ? " ("+err.name+")." : '.')
|
||||
+ (message ? " " + message : "")
|
||||
);
|
||||
}
|
||||
if ((shouldThrow && threw && typematters && !(exception instanceof err)) ||
|
||||
(!shouldThrow && threw)) {
|
||||
throw exception;
|
||||
}
|
||||
};
|
||||
|
||||
// 11. Expected to throw an error:
|
||||
// assert.throws(block, Error_opt, message_opt);
|
||||
|
||||
assert.throws = function(block, /*optional*/error, /*optional*/message) {
|
||||
_throws.apply(this, [true].concat(pSlice.call(arguments)));
|
||||
};
|
||||
|
||||
// EXTENSION! This is annoying to write outside this module.
|
||||
assert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) {
|
||||
_throws.apply(this, [false].concat(pSlice.call(arguments)));
|
||||
};
|
||||
|
||||
assert.ifError = function (err) { if (err) {throw err;}};
|
||||
260
bin/node_modules/nodeunit/lib/core.js
generated
vendored
260
bin/node_modules/nodeunit/lib/core.js
generated
vendored
@@ -1,260 +0,0 @@
|
||||
/*!
|
||||
* Nodeunit
|
||||
* Copyright (c) 2010 Caolan McMahon
|
||||
* MIT Licensed
|
||||
*
|
||||
* THIS FILE SHOULD BE BROWSER-COMPATIBLE JS!
|
||||
* You can use @REMOVE_LINE_FOR_BROWSER to remove code from the browser build.
|
||||
* Only code on that line will be removed, its mostly to avoid requiring code
|
||||
* that is node specific
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module dependencies
|
||||
*/
|
||||
|
||||
var async = require('../deps/async'), //@REMOVE_LINE_FOR_BROWSER
|
||||
types = require('./types'); //@REMOVE_LINE_FOR_BROWSER
|
||||
|
||||
|
||||
/**
|
||||
* Added for browser compatibility
|
||||
*/
|
||||
|
||||
var _keys = function(obj){
|
||||
if(Object.keys) return Object.keys(obj);
|
||||
var keys = [];
|
||||
for(var k in obj){
|
||||
if(obj.hasOwnProperty(k)) keys.push(k);
|
||||
}
|
||||
return keys;
|
||||
};
|
||||
|
||||
|
||||
var _copy = function(obj){
|
||||
var nobj = Object();
|
||||
var keys = _keys(obj);
|
||||
for (var i = 0; i < keys.length; i++){
|
||||
nobj[keys[i]] = obj[keys[i]];
|
||||
}
|
||||
return nobj;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Runs a test function (fn) from a loaded module. After the test function
|
||||
* calls test.done(), the callback is executed with an assertionList as its
|
||||
* second argument.
|
||||
*
|
||||
* @param {String} name
|
||||
* @param {Function} fn
|
||||
* @param {Object} opt
|
||||
* @param {Function} callback
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.runTest = function (name, fn, opt, callback) {
|
||||
var options = types.options(opt);
|
||||
|
||||
options.testStart(name);
|
||||
var start = new Date().getTime();
|
||||
var test = types.test(name, start, options, callback);
|
||||
|
||||
try {
|
||||
fn(test);
|
||||
}
|
||||
catch (e) {
|
||||
test.done(e);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Takes an object containing test functions or other test suites as properties
|
||||
* and runs each in series. After all tests have completed, the callback is
|
||||
* called with a list of all assertions as the second argument.
|
||||
*
|
||||
* If a name is passed to this function it is prepended to all test and suite
|
||||
* names that run within it.
|
||||
*
|
||||
* @param {String} name
|
||||
* @param {Object} suite
|
||||
* @param {Object} opt
|
||||
* @param {Function} callback
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.runSuite = function (name, suite, opt, callback) {
|
||||
var keys = _keys(suite);
|
||||
|
||||
async.concatSeries(keys, function (k, cb) {
|
||||
var prop = suite[k], _name;
|
||||
|
||||
_name = name ? [].concat(name, k) : [k];
|
||||
|
||||
_name.toString = function () {
|
||||
// fallback for old one
|
||||
return this.join(' - ');
|
||||
};
|
||||
|
||||
if (typeof prop === 'function') {
|
||||
if (!opt.testspec || _name.indexOf(opt.testspec) != -1){
|
||||
if (opt.moduleStart)
|
||||
opt.moduleStart();
|
||||
exports.runTest(_name, suite[k], opt, cb);
|
||||
} else
|
||||
return cb();
|
||||
}
|
||||
else {
|
||||
exports.runSuite(_name, suite[k], opt, cb);
|
||||
}
|
||||
}, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* Run each exported test function or test suite from a loaded module.
|
||||
*
|
||||
* @param {String} name
|
||||
* @param {Object} mod
|
||||
* @param {Object} opt
|
||||
* @param {Function} callback
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.runModule = function (name, mod, opt, callback) {
|
||||
var options = _copy(types.options(opt));
|
||||
|
||||
var _run = false;
|
||||
var _moduleStart = options.moduleStart;
|
||||
function run_once(){
|
||||
if (!_run){
|
||||
_run = true;
|
||||
_moduleStart(name);
|
||||
}
|
||||
}
|
||||
options.moduleStart = run_once;
|
||||
|
||||
var start = new Date().getTime();
|
||||
|
||||
exports.runSuite(null, mod, options, function (err, a_list) {
|
||||
var end = new Date().getTime();
|
||||
var assertion_list = types.assertionList(a_list, end - start);
|
||||
options.moduleDone(name, assertion_list);
|
||||
callback(null, a_list);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Treats an object literal as a list of modules keyed by name. Runs each
|
||||
* module and finished with calling 'done'. You can think of this as a browser
|
||||
* safe alternative to runFiles in the nodeunit module.
|
||||
*
|
||||
* @param {Object} modules
|
||||
* @param {Object} opt
|
||||
* @api public
|
||||
*/
|
||||
|
||||
// TODO: add proper unit tests for this function
|
||||
exports.runModules = function (modules, opt) {
|
||||
var all_assertions = [];
|
||||
var options = types.options(opt);
|
||||
var start = new Date().getTime();
|
||||
|
||||
async.concatSeries(_keys(modules), function (k, cb) {
|
||||
exports.runModule(k, modules[k], options, cb);
|
||||
},
|
||||
function (err, all_assertions) {
|
||||
var end = new Date().getTime();
|
||||
options.done(types.assertionList(all_assertions, end - start));
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Wraps a test function with setUp and tearDown functions.
|
||||
* Used by testCase.
|
||||
*
|
||||
* @param {Function} setUp
|
||||
* @param {Function} tearDown
|
||||
* @param {Function} fn
|
||||
* @api private
|
||||
*/
|
||||
|
||||
var wrapTest = function (setUp, tearDown, fn) {
|
||||
return function (test) {
|
||||
var context = {};
|
||||
if (tearDown) {
|
||||
var done = test.done;
|
||||
test.done = function (err) {
|
||||
try {
|
||||
tearDown.call(context, function (err2) {
|
||||
if (err && err2) {
|
||||
test._assertion_list.push(
|
||||
types.assertion({error: err})
|
||||
);
|
||||
return done(err2);
|
||||
}
|
||||
done(err || err2);
|
||||
});
|
||||
}
|
||||
catch (e) {
|
||||
done(e);
|
||||
}
|
||||
};
|
||||
}
|
||||
if (setUp) {
|
||||
setUp.call(context, function (err) {
|
||||
if (err) {
|
||||
return test.done(err);
|
||||
}
|
||||
fn.call(context, test);
|
||||
});
|
||||
}
|
||||
else {
|
||||
fn.call(context, test);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Wraps a group of tests with setUp and tearDown functions.
|
||||
* Used by testCase.
|
||||
*
|
||||
* @param {Function} setUp
|
||||
* @param {Function} tearDown
|
||||
* @param {Object} group
|
||||
* @api private
|
||||
*/
|
||||
|
||||
var wrapGroup = function (setUp, tearDown, group) {
|
||||
var tests = {};
|
||||
var keys = _keys(group);
|
||||
for (var i=0; i<keys.length; i++) {
|
||||
var k = keys[i];
|
||||
if (typeof group[k] === 'function') {
|
||||
tests[k] = wrapTest(setUp, tearDown, group[k]);
|
||||
}
|
||||
else if (typeof group[k] === 'object') {
|
||||
tests[k] = wrapGroup(setUp, tearDown, group[k]);
|
||||
}
|
||||
}
|
||||
return tests;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Utility for wrapping a suite of test functions with setUp and tearDown
|
||||
* functions.
|
||||
*
|
||||
* @param {Object} suite
|
||||
* @return {Object}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.testCase = function (suite) {
|
||||
var setUp = suite.setUp;
|
||||
var tearDown = suite.tearDown;
|
||||
delete suite.setUp;
|
||||
delete suite.tearDown;
|
||||
return wrapGroup(setUp, tearDown, suite);
|
||||
};
|
||||
82
bin/node_modules/nodeunit/lib/nodeunit.js
generated
vendored
82
bin/node_modules/nodeunit/lib/nodeunit.js
generated
vendored
@@ -1,82 +0,0 @@
|
||||
/*!
|
||||
* Nodeunit
|
||||
* Copyright (c) 2010 Caolan McMahon
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module dependencies
|
||||
*/
|
||||
|
||||
var async = require('../deps/async'),
|
||||
types = require('./types'),
|
||||
utils = require('./utils'),
|
||||
core = require('./core'),
|
||||
reporters = require('./reporters'),
|
||||
assert = require('./assert'),
|
||||
path = require('path');
|
||||
|
||||
|
||||
/**
|
||||
* Export sub-modules.
|
||||
*/
|
||||
|
||||
exports.types = types;
|
||||
exports.utils = utils;
|
||||
exports.reporters = reporters;
|
||||
exports.assert = assert;
|
||||
|
||||
// backwards compatibility
|
||||
exports.testrunner = {
|
||||
run: function () {
|
||||
console.log(
|
||||
'WARNING: nodeunit.testrunner is going to be deprecated, please ' +
|
||||
'use nodeunit.reporters.default instead!'
|
||||
);
|
||||
return reporters['default'].run.apply(this, arguments);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Export all core functions
|
||||
*/
|
||||
|
||||
for (var k in core) {
|
||||
exports[k] = core[k];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Load modules from paths array and run all exported tests in series. If a path
|
||||
* is a directory, load all supported file types inside it as modules. This only
|
||||
* reads 1 level deep in the directory and does not recurse through
|
||||
* sub-directories.
|
||||
*
|
||||
* @param {Array} paths
|
||||
* @param {Object} opt
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.runFiles = function (paths, opt) {
|
||||
var all_assertions = [];
|
||||
var options = types.options(opt);
|
||||
var start = new Date().getTime();
|
||||
|
||||
if (!paths.length) {
|
||||
return options.done(types.assertionList(all_assertions));
|
||||
}
|
||||
|
||||
utils.modulePaths(paths, function (err, files) {
|
||||
if (err) throw err;
|
||||
async.concatSeries(files, function (file, cb) {
|
||||
var name = path.basename(file);
|
||||
exports.runModule(name, require(file), options, cb);
|
||||
},
|
||||
function (err, all_assertions) {
|
||||
var end = new Date().getTime();
|
||||
options.done(types.assertionList(all_assertions, end - start));
|
||||
});
|
||||
});
|
||||
|
||||
};
|
||||
119
bin/node_modules/nodeunit/lib/reporters/browser.js
generated
vendored
119
bin/node_modules/nodeunit/lib/reporters/browser.js
generated
vendored
@@ -1,119 +0,0 @@
|
||||
/*!
|
||||
* Nodeunit
|
||||
* Copyright (c) 2010 Caolan McMahon
|
||||
* MIT Licensed
|
||||
*
|
||||
* THIS FILE SHOULD BE BROWSER-COMPATIBLE JS!
|
||||
* You can use @REMOVE_LINE_FOR_BROWSER to remove code from the browser build.
|
||||
* Only code on that line will be removed, its mostly to avoid requiring code
|
||||
* that is node specific
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* NOTE: this test runner is not listed in index.js because it cannot be
|
||||
* used with the command-line tool, only inside the browser.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Reporter info string
|
||||
*/
|
||||
|
||||
exports.info = "Browser-based test reporter";
|
||||
|
||||
|
||||
/**
|
||||
* Run all tests within each module, reporting the results
|
||||
*
|
||||
* @param {Array} files
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.run = function (modules, options) {
|
||||
var start = new Date().getTime();
|
||||
|
||||
function setText(el, txt) {
|
||||
if ('innerText' in el) {
|
||||
el.innerText = txt;
|
||||
}
|
||||
else if ('textContent' in el){
|
||||
el.textContent = txt;
|
||||
}
|
||||
}
|
||||
|
||||
function getOrCreate(tag, id) {
|
||||
var el = document.getElementById(id);
|
||||
if (!el) {
|
||||
el = document.createElement(tag);
|
||||
el.id = id;
|
||||
document.body.appendChild(el);
|
||||
}
|
||||
return el;
|
||||
};
|
||||
|
||||
var header = getOrCreate('h1', 'nodeunit-header');
|
||||
var banner = getOrCreate('h2', 'nodeunit-banner');
|
||||
var userAgent = getOrCreate('h2', 'nodeunit-userAgent');
|
||||
var tests = getOrCreate('ol', 'nodeunit-tests');
|
||||
var result = getOrCreate('p', 'nodeunit-testresult');
|
||||
|
||||
setText(userAgent, navigator.userAgent);
|
||||
|
||||
nodeunit.runModules(modules, {
|
||||
moduleStart: function (name) {
|
||||
/*var mheading = document.createElement('h2');
|
||||
mheading.innerText = name;
|
||||
results.appendChild(mheading);
|
||||
module = document.createElement('ol');
|
||||
results.appendChild(module);*/
|
||||
},
|
||||
testDone: function (name, assertions) {
|
||||
var test = document.createElement('li');
|
||||
var strong = document.createElement('strong');
|
||||
strong.innerHTML = name + ' <b style="color: black;">(' +
|
||||
'<b class="fail">' + assertions.failures() + '</b>, ' +
|
||||
'<b class="pass">' + assertions.passes() + '</b>, ' +
|
||||
assertions.length +
|
||||
')</b>';
|
||||
test.className = assertions.failures() ? 'fail': 'pass';
|
||||
test.appendChild(strong);
|
||||
|
||||
var aList = document.createElement('ol');
|
||||
aList.style.display = 'none';
|
||||
test.onclick = function () {
|
||||
var d = aList.style.display;
|
||||
aList.style.display = (d == 'none') ? 'block': 'none';
|
||||
};
|
||||
for (var i=0; i<assertions.length; i++) {
|
||||
var li = document.createElement('li');
|
||||
var a = assertions[i];
|
||||
if (a.failed()) {
|
||||
li.innerHTML = (a.message || a.method || 'no message') +
|
||||
'<pre>' + (a.error.stack || a.error) + '</pre>';
|
||||
li.className = 'fail';
|
||||
}
|
||||
else {
|
||||
li.innerHTML = a.message || a.method || 'no message';
|
||||
li.className = 'pass';
|
||||
}
|
||||
aList.appendChild(li);
|
||||
}
|
||||
test.appendChild(aList);
|
||||
tests.appendChild(test);
|
||||
},
|
||||
done: function (assertions) {
|
||||
var end = new Date().getTime();
|
||||
var duration = end - start;
|
||||
|
||||
var failures = assertions.failures();
|
||||
banner.className = failures ? 'fail': 'pass';
|
||||
|
||||
result.innerHTML = 'Tests completed in ' + duration +
|
||||
' milliseconds.<br/><span class="passed">' +
|
||||
assertions.passes() + '</span> assertions of ' +
|
||||
'<span class="all">' + assertions.length + '<span> passed, ' +
|
||||
assertions.failures() + ' failed.';
|
||||
}
|
||||
});
|
||||
};
|
||||
123
bin/node_modules/nodeunit/lib/reporters/default.js
generated
vendored
123
bin/node_modules/nodeunit/lib/reporters/default.js
generated
vendored
@@ -1,123 +0,0 @@
|
||||
/*!
|
||||
* Nodeunit
|
||||
* Copyright (c) 2010 Caolan McMahon
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module dependencies
|
||||
*/
|
||||
|
||||
var nodeunit = require('../nodeunit'),
|
||||
utils = require('../utils'),
|
||||
fs = require('fs'),
|
||||
track = require('../track'),
|
||||
path = require('path');
|
||||
AssertionError = require('../assert').AssertionError;
|
||||
|
||||
/**
|
||||
* Reporter info string
|
||||
*/
|
||||
|
||||
exports.info = "Default tests reporter";
|
||||
|
||||
|
||||
/**
|
||||
* Run all tests within each module, reporting the results to the command-line.
|
||||
*
|
||||
* @param {Array} files
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.run = function (files, options) {
|
||||
|
||||
if (!options) {
|
||||
// load default options
|
||||
var content = fs.readFileSync(
|
||||
__dirname + '/../../bin/nodeunit.json', 'utf8'
|
||||
);
|
||||
options = JSON.parse(content);
|
||||
}
|
||||
|
||||
var error = function (str) {
|
||||
return options.error_prefix + str + options.error_suffix;
|
||||
};
|
||||
var ok = function (str) {
|
||||
return options.ok_prefix + str + options.ok_suffix;
|
||||
};
|
||||
var bold = function (str) {
|
||||
return options.bold_prefix + str + options.bold_suffix;
|
||||
};
|
||||
var assertion_message = function (str) {
|
||||
return options.assertion_prefix + str + options.assertion_suffix;
|
||||
};
|
||||
|
||||
var start = new Date().getTime();
|
||||
var paths = files.map(function (p) {
|
||||
return path.join(process.cwd(), p);
|
||||
});
|
||||
var tracker = track.createTracker(function (tracker) {
|
||||
if (tracker.unfinished()) {
|
||||
console.log('');
|
||||
console.log(error(bold(
|
||||
'FAILURES: Undone tests (or their setups/teardowns): '
|
||||
)));
|
||||
var names = tracker.names();
|
||||
for (var i = 0; i < names.length; i += 1) {
|
||||
console.log('- ' + names[i]);
|
||||
}
|
||||
console.log('');
|
||||
console.log('To fix this, make sure all tests call test.done()');
|
||||
process.reallyExit(tracker.unfinished());
|
||||
}
|
||||
});
|
||||
|
||||
nodeunit.runFiles(paths, {
|
||||
testspec: options.testspec,
|
||||
moduleStart: function (name) {
|
||||
console.log('\n' + bold(name));
|
||||
},
|
||||
testDone: function (name, assertions) {
|
||||
tracker.remove(name);
|
||||
|
||||
if (!assertions.failures()) {
|
||||
console.log('✔ ' + name);
|
||||
}
|
||||
else {
|
||||
console.log(error('✖ ' + name) + '\n');
|
||||
assertions.forEach(function (a) {
|
||||
if (a.failed()) {
|
||||
a = utils.betterErrors(a);
|
||||
if (a.error instanceof AssertionError && a.message) {
|
||||
console.log(
|
||||
'Assertion Message: ' +
|
||||
assertion_message(a.message)
|
||||
);
|
||||
}
|
||||
console.log(a.error.stack + '\n');
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
done: function (assertions, end) {
|
||||
var end = end || new Date().getTime();
|
||||
var duration = end - start;
|
||||
if (assertions.failures()) {
|
||||
console.log(
|
||||
'\n' + bold(error('FAILURES: ')) + assertions.failures() +
|
||||
'/' + assertions.length + ' assertions failed (' +
|
||||
assertions.duration + 'ms)'
|
||||
);
|
||||
}
|
||||
else {
|
||||
console.log(
|
||||
'\n' + bold(ok('OK: ')) + assertions.length +
|
||||
' assertions (' + assertions.duration + 'ms)'
|
||||
);
|
||||
}
|
||||
},
|
||||
testStart: function(name) {
|
||||
tracker.put(name);
|
||||
}
|
||||
});
|
||||
};
|
||||
107
bin/node_modules/nodeunit/lib/reporters/html.js
generated
vendored
107
bin/node_modules/nodeunit/lib/reporters/html.js
generated
vendored
@@ -1,107 +0,0 @@
|
||||
/*!
|
||||
* Nodeunit
|
||||
* Copyright (c) 2010 Caolan McMahon
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module dependencies
|
||||
*/
|
||||
|
||||
var nodeunit = require('../nodeunit'),
|
||||
utils = require('../utils'),
|
||||
fs = require('fs'),
|
||||
path = require('path'),
|
||||
AssertionError = require('assert').AssertionError;
|
||||
|
||||
/**
|
||||
* Reporter info string
|
||||
*/
|
||||
|
||||
exports.info = "Report tests result as HTML";
|
||||
|
||||
/**
|
||||
* Run all tests within each module, reporting the results to the command-line.
|
||||
*
|
||||
* @param {Array} files
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.run = function (files, options) {
|
||||
|
||||
var start = new Date().getTime();
|
||||
var paths = files.map(function (p) {
|
||||
return path.join(process.cwd(), p);
|
||||
});
|
||||
|
||||
console.log('<html>');
|
||||
console.log('<head>');
|
||||
console.log('<title></title>');
|
||||
console.log('<style type="text/css">');
|
||||
console.log('body { font: 12px Helvetica Neue }');
|
||||
console.log('h2 { margin:0 ; padding:0 }');
|
||||
console.log('pre { font: 11px Andale Mono; margin-left: 1em; padding-left: 1em; margin-top:0; font-size:smaller;}');
|
||||
console.log('.assertion_message { margin-left: 1em; }');
|
||||
console.log(' ol {' +
|
||||
' list-style: none;' +
|
||||
' margin-left: 1em;' +
|
||||
' padding-left: 1em;' +
|
||||
' text-indent: -1em;' +
|
||||
'}');
|
||||
console.log(' ol li.pass:before { content: "\\2714 \\0020"; }');
|
||||
console.log(' ol li.fail:before { content: "\\2716 \\0020"; }');
|
||||
console.log('</style>');
|
||||
console.log('</head>');
|
||||
console.log('<body>');
|
||||
nodeunit.runFiles(paths, {
|
||||
testspec: options.testspec,
|
||||
moduleStart: function (name) {
|
||||
console.log('<h2>' + name + '</h2>');
|
||||
console.log('<ol>');
|
||||
},
|
||||
testDone: function (name, assertions) {
|
||||
if (!assertions.failures()) {
|
||||
console.log('<li class="pass">' + name + '</li>');
|
||||
}
|
||||
else {
|
||||
console.log('<li class="fail">' + name);
|
||||
assertions.forEach(function (a) {
|
||||
if (a.failed()) {
|
||||
a = utils.betterErrors(a);
|
||||
if (a.error instanceof AssertionError && a.message) {
|
||||
console.log('<div class="assertion_message">' +
|
||||
'Assertion Message: ' + a.message +
|
||||
'</div>');
|
||||
}
|
||||
console.log('<pre>');
|
||||
console.log(a.error.stack);
|
||||
console.log('</pre>');
|
||||
}
|
||||
});
|
||||
console.log('</li>');
|
||||
}
|
||||
},
|
||||
moduleDone: function () {
|
||||
console.log('</ol>');
|
||||
},
|
||||
done: function (assertions) {
|
||||
var end = new Date().getTime();
|
||||
var duration = end - start;
|
||||
if (assertions.failures()) {
|
||||
console.log(
|
||||
'<h3>FAILURES: ' + assertions.failures() +
|
||||
'/' + assertions.length + ' assertions failed (' +
|
||||
assertions.duration + 'ms)</h3>'
|
||||
);
|
||||
}
|
||||
else {
|
||||
console.log(
|
||||
'<h3>OK: ' + assertions.length +
|
||||
' assertions (' + assertions.duration + 'ms)</h3>'
|
||||
);
|
||||
}
|
||||
console.log('</body>');
|
||||
}
|
||||
});
|
||||
|
||||
};
|
||||
9
bin/node_modules/nodeunit/lib/reporters/index.js
generated
vendored
9
bin/node_modules/nodeunit/lib/reporters/index.js
generated
vendored
@@ -1,9 +0,0 @@
|
||||
module.exports = {
|
||||
'junit': require('./junit'),
|
||||
'default': require('./default'),
|
||||
'skip_passed': require('./skip_passed'),
|
||||
'minimal': require('./minimal'),
|
||||
'html': require('./html')
|
||||
// browser test reporter is not listed because it cannot be used
|
||||
// with the command line tool, only inside a browser.
|
||||
};
|
||||
183
bin/node_modules/nodeunit/lib/reporters/junit.js
generated
vendored
183
bin/node_modules/nodeunit/lib/reporters/junit.js
generated
vendored
@@ -1,183 +0,0 @@
|
||||
/*!
|
||||
* Nodeunit
|
||||
* Copyright (c) 2010 Caolan McMahon
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module dependencies
|
||||
*/
|
||||
|
||||
var nodeunit = require('../nodeunit'),
|
||||
utils = require('../utils'),
|
||||
fs = require('fs'),
|
||||
path = require('path'),
|
||||
async = require('../../deps/async'),
|
||||
AssertionError = require('assert').AssertionError,
|
||||
child_process = require('child_process'),
|
||||
ejs = require('../../deps/ejs');
|
||||
|
||||
|
||||
/**
|
||||
* Reporter info string
|
||||
*/
|
||||
|
||||
exports.info = "jUnit XML test reports";
|
||||
|
||||
|
||||
/**
|
||||
* Ensures a directory exists using mkdir -p.
|
||||
*
|
||||
* @param {String} path
|
||||
* @param {Function} callback
|
||||
* @api private
|
||||
*/
|
||||
|
||||
var ensureDir = function (path, callback) {
|
||||
var mkdir = child_process.spawn('mkdir', ['-p', path]);
|
||||
mkdir.on('error', function (err) {
|
||||
callback(err);
|
||||
callback = function(){};
|
||||
});
|
||||
mkdir.on('exit', function (code) {
|
||||
if (code === 0) callback();
|
||||
else callback(new Error('mkdir exited with code: ' + code));
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns absolute version of a path. Relative paths are interpreted
|
||||
* relative to process.cwd() or the cwd parameter. Paths that are already
|
||||
* absolute are returned unaltered.
|
||||
*
|
||||
* @param {String} p
|
||||
* @param {String} cwd
|
||||
* @return {String}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
var abspath = function (p, /*optional*/cwd) {
|
||||
if (p[0] === '/') return p;
|
||||
cwd = cwd || process.cwd();
|
||||
return path.normalize(path.join(cwd, p));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Run all tests within each module, reporting the results to the command-line,
|
||||
* then writes out junit-compatible xml documents.
|
||||
*
|
||||
* @param {Array} files
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.run = function (files, opts, callback) {
|
||||
if (!opts.output) {
|
||||
console.error(
|
||||
'Error: No output directory defined.\n' +
|
||||
'\tEither add an "output" property to your nodeunit.json config ' +
|
||||
'file, or\n\tuse the --output command line option.'
|
||||
);
|
||||
return;
|
||||
}
|
||||
opts.output = abspath(opts.output);
|
||||
var error = function (str) {
|
||||
return opts.error_prefix + str + opts.error_suffix;
|
||||
};
|
||||
var ok = function (str) {
|
||||
return opts.ok_prefix + str + opts.ok_suffix;
|
||||
};
|
||||
var bold = function (str) {
|
||||
return opts.bold_prefix + str + opts.bold_suffix;
|
||||
};
|
||||
|
||||
var start = new Date().getTime();
|
||||
var paths = files.map(function (p) {
|
||||
return path.join(process.cwd(), p);
|
||||
});
|
||||
|
||||
var modules = {}
|
||||
var curModule;
|
||||
|
||||
nodeunit.runFiles(paths, {
|
||||
testspec: opts.testspec,
|
||||
moduleStart: function (name) {
|
||||
curModule = {
|
||||
errorCount: 0,
|
||||
failureCount: 0,
|
||||
tests: 0,
|
||||
testcases: [],
|
||||
name: name
|
||||
};
|
||||
modules[name] = curModule;
|
||||
},
|
||||
testDone: function (name, assertions) {
|
||||
var testcase = {name: name};
|
||||
for (var i=0; i<assertions.length; i++) {
|
||||
var a = assertions[i];
|
||||
if (a.failed()) {
|
||||
a = utils.betterErrors(a);
|
||||
testcase.failure = {
|
||||
message: a.message,
|
||||
backtrace: a.error.stack
|
||||
};
|
||||
|
||||
if (a.error instanceof AssertionError) {
|
||||
curModule.failureCount++;
|
||||
}
|
||||
else {
|
||||
curModule.errorCount++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
curModule.tests++;
|
||||
curModule.testcases.push(testcase);
|
||||
},
|
||||
done: function (assertions) {
|
||||
var end = new Date().getTime();
|
||||
var duration = end - start;
|
||||
|
||||
ensureDir(opts.output, function (err) {
|
||||
var tmpl = __dirname + "/../../share/junit.xml.ejs";
|
||||
fs.readFile(tmpl, function (err, data) {
|
||||
if (err) throw err;
|
||||
var tmpl = data.toString();
|
||||
|
||||
async.forEach(Object.keys(modules), function (k, cb) {
|
||||
var module = modules[k];
|
||||
var rendered = ejs.render(tmpl, {
|
||||
locals: {suites: [module]}
|
||||
});
|
||||
var filename = path.join(
|
||||
opts.output,
|
||||
module.name + '.xml'
|
||||
);
|
||||
console.log('Writing ' + filename);
|
||||
fs.writeFile(filename, rendered, cb);
|
||||
},
|
||||
function (err) {
|
||||
if (err) throw err;
|
||||
else if (assertions.failures()) {
|
||||
console.log(
|
||||
'\n' + bold(error('FAILURES: ')) +
|
||||
assertions.failures() + '/' +
|
||||
assertions.length + ' assertions failed (' +
|
||||
assertions.duration + 'ms)'
|
||||
);
|
||||
}
|
||||
else {
|
||||
console.log(
|
||||
'\n' + bold(ok('OK: ')) + assertions.length +
|
||||
' assertions (' + assertions.duration + 'ms)'
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
112
bin/node_modules/nodeunit/lib/reporters/minimal.js
generated
vendored
112
bin/node_modules/nodeunit/lib/reporters/minimal.js
generated
vendored
@@ -1,112 +0,0 @@
|
||||
/*!
|
||||
* Nodeunit
|
||||
* Copyright (c) 2010 Caolan McMahon
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module dependencies
|
||||
*/
|
||||
|
||||
var nodeunit = require('../nodeunit'),
|
||||
utils = require('../utils'),
|
||||
fs = require('fs'),
|
||||
path = require('path'),
|
||||
AssertionError = require('assert').AssertionError;
|
||||
|
||||
/**
|
||||
* Reporter info string
|
||||
*/
|
||||
|
||||
exports.info = "Pretty minimal output";
|
||||
|
||||
/**
|
||||
* Run all tests within each module, reporting the results to the command-line.
|
||||
*
|
||||
* @param {Array} files
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.run = function (files, options) {
|
||||
|
||||
if (!options) {
|
||||
// load default options
|
||||
var content = fs.readFileSync(
|
||||
__dirname + '/../../bin/nodeunit.json', 'utf8'
|
||||
);
|
||||
options = JSON.parse(content);
|
||||
}
|
||||
|
||||
var red = function (str) {
|
||||
return options.error_prefix + str + options.error_suffix;
|
||||
};
|
||||
var green = function (str) {
|
||||
return options.ok_prefix + str + options.ok_suffix;
|
||||
};
|
||||
var magenta = function (str) {
|
||||
return options.assertion_prefix + str + options.assertion_suffix;
|
||||
};
|
||||
var bold = function (str) {
|
||||
return options.bold_prefix + str + options.bold_suffix;
|
||||
};
|
||||
|
||||
var start = new Date().getTime();
|
||||
var paths = files.map(function (p) {
|
||||
return path.join(process.cwd(), p);
|
||||
});
|
||||
|
||||
nodeunit.runFiles(paths, {
|
||||
testspec: options.testspec,
|
||||
moduleStart: function (name) {
|
||||
process.stdout.write(bold(name) + ': ');
|
||||
},
|
||||
moduleDone: function (name, assertions) {
|
||||
console.log('');
|
||||
if (assertions.failures()) {
|
||||
assertions.forEach(function (a) {
|
||||
if (a.failed()) {
|
||||
a = utils.betterErrors(a);
|
||||
if (a.error instanceof AssertionError && a.message) {
|
||||
console.log(
|
||||
'Assertion in test ' + bold(a.testname) + ': ' +
|
||||
magenta(a.message)
|
||||
);
|
||||
}
|
||||
console.log(a.error.stack + '\n');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
},
|
||||
testStart: function () {
|
||||
},
|
||||
testDone: function (name, assertions) {
|
||||
if (!assertions.failures()) {
|
||||
process.stdout.write('.');
|
||||
}
|
||||
else {
|
||||
process.stdout.write(red('F'));
|
||||
assertions.forEach(function (assertion) {
|
||||
assertion.testname = name;
|
||||
});
|
||||
}
|
||||
},
|
||||
done: function (assertions) {
|
||||
var end = new Date().getTime();
|
||||
var duration = end - start;
|
||||
if (assertions.failures()) {
|
||||
console.log(
|
||||
'\n' + bold(red('FAILURES: ')) + assertions.failures() +
|
||||
'/' + assertions.length + ' assertions failed (' +
|
||||
assertions.duration + 'ms)'
|
||||
);
|
||||
}
|
||||
else {
|
||||
console.log(
|
||||
'\n' + bold(green('OK: ')) + assertions.length +
|
||||
' assertions (' + assertions.duration + 'ms)'
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
105
bin/node_modules/nodeunit/lib/reporters/skip_passed.js
generated
vendored
105
bin/node_modules/nodeunit/lib/reporters/skip_passed.js
generated
vendored
@@ -1,105 +0,0 @@
|
||||
/*!
|
||||
* Nodeunit
|
||||
* Copyright (c) 2010 Caolan McMahon
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module dependencies
|
||||
*/
|
||||
|
||||
var nodeunit = require('../nodeunit'),
|
||||
utils = require('../utils'),
|
||||
fs = require('fs'),
|
||||
path = require('path'),
|
||||
AssertionError = require('assert').AssertionError;
|
||||
|
||||
/**
|
||||
* Reporter info string
|
||||
*/
|
||||
|
||||
exports.info = "Skip passed tests output";
|
||||
|
||||
/**
|
||||
* Run all tests within each module, reporting the results to the command-line.
|
||||
*
|
||||
* @param {Array} files
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.run = function (files, options) {
|
||||
|
||||
if (!options) {
|
||||
// load default options
|
||||
var content = fs.readFileSync(
|
||||
__dirname + '/../../bin/nodeunit.json', 'utf8'
|
||||
);
|
||||
options = JSON.parse(content);
|
||||
}
|
||||
|
||||
var error = function (str) {
|
||||
return options.error_prefix + str + options.error_suffix;
|
||||
};
|
||||
var ok = function (str) {
|
||||
return options.ok_prefix + str + options.ok_suffix;
|
||||
};
|
||||
var bold = function (str) {
|
||||
return options.bold_prefix + str + options.bold_suffix;
|
||||
};
|
||||
var assertion_message = function (str) {
|
||||
return options.assertion_prefix + str + options.assertion_suffix;
|
||||
};
|
||||
|
||||
var start = new Date().getTime();
|
||||
var paths = files.map(function (p) {
|
||||
return path.join(process.cwd(), p);
|
||||
});
|
||||
|
||||
nodeunit.runFiles(paths, {
|
||||
testspec: options.testspec,
|
||||
moduleStart: function (name) {
|
||||
console.log('\n' + bold(name));
|
||||
},
|
||||
testDone: function (name, assertions) {
|
||||
if (assertions.failures()) {
|
||||
console.log(error('✖ ' + name) + '\n');
|
||||
assertions.forEach(function (a) {
|
||||
if (a.failed()) {
|
||||
a = utils.betterErrors(a);
|
||||
if (a.error instanceof AssertionError && a.message) {
|
||||
console.log(
|
||||
'Assertion Message: ' + assertion_message(a.message)
|
||||
);
|
||||
}
|
||||
console.log(a.error.stack + '\n');
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
moduleDone: function (name, assertions) {
|
||||
if (!assertions.failures()) {
|
||||
console.log('✔ all tests passed');
|
||||
}
|
||||
else {
|
||||
console.log(error('✖ some tests failed'));
|
||||
}
|
||||
},
|
||||
done: function (assertions) {
|
||||
var end = new Date().getTime();
|
||||
var duration = end - start;
|
||||
if (assertions.failures()) {
|
||||
console.log(
|
||||
'\n' + bold(error('FAILURES: ')) + assertions.failures() +
|
||||
'/' + assertions.length + ' assertions failed (' +
|
||||
assertions.duration + 'ms)'
|
||||
);
|
||||
}
|
||||
else {
|
||||
console.log(
|
||||
'\n' + bold(ok('OK: ')) + assertions.length +
|
||||
' assertions (' + assertions.duration + 'ms)'
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
48
bin/node_modules/nodeunit/lib/track.js
generated
vendored
48
bin/node_modules/nodeunit/lib/track.js
generated
vendored
@@ -1,48 +0,0 @@
|
||||
/*!
|
||||
* Simple util module to track tests. Adds a process.exit hook to print
|
||||
* the undone tests.
|
||||
*/
|
||||
|
||||
|
||||
exports.createTracker = function (on_exit) {
|
||||
var names = {};
|
||||
var tracker = {
|
||||
names: function () {
|
||||
var arr = [];
|
||||
for (var k in names) {
|
||||
if (names.hasOwnProperty(k)) {
|
||||
arr.push(k);
|
||||
}
|
||||
}
|
||||
return arr;
|
||||
},
|
||||
unfinished: function () {
|
||||
return tracker.names().length;
|
||||
},
|
||||
put: function (testname) {
|
||||
names[testname] = testname;
|
||||
},
|
||||
remove: function (testname) {
|
||||
delete names[testname];
|
||||
}
|
||||
};
|
||||
|
||||
process.on('exit', function() {
|
||||
on_exit = on_exit || exports.default_on_exit;
|
||||
on_exit(tracker);
|
||||
});
|
||||
|
||||
return tracker;
|
||||
};
|
||||
|
||||
exports.default_on_exit = function (tracker) {
|
||||
if (tracker.unfinished()) {
|
||||
console.log('');
|
||||
console.log('Undone tests (or their setups/teardowns): ');
|
||||
var names = tracker.names();
|
||||
for (var i = 0; i < names.length; i += 1) {
|
||||
console.log(names[i]);
|
||||
}
|
||||
process.reallyExit(tracker.unfinished());
|
||||
}
|
||||
};
|
||||
187
bin/node_modules/nodeunit/lib/types.js
generated
vendored
187
bin/node_modules/nodeunit/lib/types.js
generated
vendored
@@ -1,187 +0,0 @@
|
||||
/*!
|
||||
* Nodeunit
|
||||
* Copyright (c) 2010 Caolan McMahon
|
||||
* MIT Licensed
|
||||
*
|
||||
* THIS FILE SHOULD BE BROWSER-COMPATIBLE JS!
|
||||
* You can use @REMOVE_LINE_FOR_BROWSER to remove code from the browser build.
|
||||
* Only code on that line will be removed, its mostly to avoid requiring code
|
||||
* that is node specific
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module dependencies
|
||||
*/
|
||||
|
||||
var assert = require('./assert'), //@REMOVE_LINE_FOR_BROWSER
|
||||
async = require('../deps/async'); //@REMOVE_LINE_FOR_BROWSER
|
||||
|
||||
|
||||
/**
|
||||
* Creates assertion objects representing the result of an assert call.
|
||||
* Accepts an object or AssertionError as its argument.
|
||||
*
|
||||
* @param {object} obj
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.assertion = function (obj) {
|
||||
return {
|
||||
method: obj.method || '',
|
||||
message: obj.message || (obj.error && obj.error.message) || '',
|
||||
error: obj.error,
|
||||
passed: function () {
|
||||
return !this.error;
|
||||
},
|
||||
failed: function () {
|
||||
return Boolean(this.error);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates an assertion list object representing a group of assertions.
|
||||
* Accepts an array of assertion objects.
|
||||
*
|
||||
* @param {Array} arr
|
||||
* @param {Number} duration
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.assertionList = function (arr, duration) {
|
||||
var that = arr || [];
|
||||
that.failures = function () {
|
||||
var failures = 0;
|
||||
for (var i=0; i<this.length; i++) {
|
||||
if (this[i].failed()) failures++;
|
||||
}
|
||||
return failures;
|
||||
};
|
||||
that.passes = function () {
|
||||
return that.length - that.failures();
|
||||
};
|
||||
that.duration = duration || 0;
|
||||
return that;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a wrapper function for assert module methods. Executes a callback
|
||||
* after the it's complete with an assertion object representing the result.
|
||||
*
|
||||
* @param {Function} callback
|
||||
* @api private
|
||||
*/
|
||||
|
||||
var assertWrapper = function (callback) {
|
||||
return function (new_method, assert_method, arity) {
|
||||
return function () {
|
||||
var message = arguments[arity-1];
|
||||
var a = exports.assertion({method: new_method, message: message});
|
||||
try {
|
||||
assert[assert_method].apply(null, arguments);
|
||||
}
|
||||
catch (e) {
|
||||
a.error = e;
|
||||
}
|
||||
callback(a);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates the 'test' object that gets passed to every test function.
|
||||
* Accepts the name of the test function as its first argument, followed by
|
||||
* the start time in ms, the options object and a callback function.
|
||||
*
|
||||
* @param {String} name
|
||||
* @param {Number} start
|
||||
* @param {Object} options
|
||||
* @param {Function} callback
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.test = function (name, start, options, callback) {
|
||||
var expecting;
|
||||
var a_list = [];
|
||||
|
||||
var wrapAssert = assertWrapper(function (a) {
|
||||
a_list.push(a);
|
||||
if (options.log) {
|
||||
async.nextTick(function () {
|
||||
options.log(a);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
var test = {
|
||||
done: function (err) {
|
||||
if (expecting !== undefined && expecting !== a_list.length) {
|
||||
var e = new Error(
|
||||
'Expected ' + expecting + ' assertions, ' +
|
||||
a_list.length + ' ran'
|
||||
);
|
||||
var a1 = exports.assertion({method: 'expect', error: e});
|
||||
a_list.push(a1);
|
||||
if (options.log) {
|
||||
async.nextTick(function () {
|
||||
options.log(a1);
|
||||
});
|
||||
}
|
||||
}
|
||||
if (err) {
|
||||
var a2 = exports.assertion({error: err});
|
||||
a_list.push(a2);
|
||||
if (options.log) {
|
||||
async.nextTick(function () {
|
||||
options.log(a2);
|
||||
});
|
||||
}
|
||||
}
|
||||
var end = new Date().getTime();
|
||||
async.nextTick(function () {
|
||||
var assertion_list = exports.assertionList(a_list, end - start);
|
||||
options.testDone(name, assertion_list);
|
||||
callback(null, a_list);
|
||||
});
|
||||
},
|
||||
ok: wrapAssert('ok', 'ok', 2),
|
||||
same: wrapAssert('same', 'deepEqual', 3),
|
||||
equals: wrapAssert('equals', 'equal', 3),
|
||||
expect: function (num) {
|
||||
expecting = num;
|
||||
},
|
||||
_assertion_list: a_list
|
||||
};
|
||||
// add all functions from the assert module
|
||||
for (var k in assert) {
|
||||
if (assert.hasOwnProperty(k)) {
|
||||
test[k] = wrapAssert(k, k, assert[k].length);
|
||||
}
|
||||
}
|
||||
return test;
|
||||
};
|
||||
|
||||
/**
|
||||
* Ensures an options object has all callbacks, adding empty callback functions
|
||||
* if any are missing.
|
||||
*
|
||||
* @param {Object} opt
|
||||
* @return {Object}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.options = function (opt) {
|
||||
var optionalCallback = function (name) {
|
||||
opt[name] = opt[name] || function () {};
|
||||
};
|
||||
|
||||
optionalCallback('moduleStart');
|
||||
optionalCallback('moduleDone');
|
||||
optionalCallback('testStart');
|
||||
optionalCallback('testDone');
|
||||
//optionalCallback('log');
|
||||
|
||||
// 'done' callback is not optional.
|
||||
|
||||
return opt;
|
||||
};
|
||||
209
bin/node_modules/nodeunit/lib/utils.js
generated
vendored
209
bin/node_modules/nodeunit/lib/utils.js
generated
vendored
@@ -1,209 +0,0 @@
|
||||
/*!
|
||||
* Nodeunit
|
||||
* Copyright (c) 2010 Caolan McMahon
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module dependencies
|
||||
*/
|
||||
|
||||
var async = require('../deps/async'),
|
||||
fs = require('fs'),
|
||||
util = require('util'),
|
||||
Script = process.binding('evals').Script,
|
||||
http = require('http');
|
||||
|
||||
|
||||
/**
|
||||
* Detect if coffee-script is available and search for .coffee as an
|
||||
* extension in modulePaths if it is.
|
||||
*/
|
||||
|
||||
var extensionPattern;
|
||||
try {
|
||||
require('coffee-script');
|
||||
extensionPattern = /\.(?:js|coffee)$/;
|
||||
}
|
||||
catch (e) {
|
||||
extensionPattern = /\.js$/;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Finds all modules at each path in an array, If a path is a directory, it
|
||||
* returns all supported file types inside it. This only reads 1 level deep in
|
||||
* the directory and does not recurse through sub-directories.
|
||||
*
|
||||
* The extension (.js, .coffee etc) is stripped from the filenames so they can
|
||||
* simply be require()'ed.
|
||||
*
|
||||
* @param {Array} paths
|
||||
* @param {Function} callback
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.modulePaths = function (paths, callback) {
|
||||
async.concat(paths, function (p, cb) {
|
||||
fs.stat(p, function (err, stats) {
|
||||
if (err) {
|
||||
return cb(err);
|
||||
}
|
||||
if (stats.isFile()) {
|
||||
return cb(null, [p]);
|
||||
}
|
||||
if (stats.isDirectory()) {
|
||||
fs.readdir(p, function (err, files) {
|
||||
if (err) {
|
||||
return cb(err);
|
||||
}
|
||||
|
||||
// filter out any filenames with unsupported extensions
|
||||
var modules = files.filter(function (filename) {
|
||||
return extensionPattern.exec(filename);
|
||||
});
|
||||
|
||||
// remove extension from module name and prepend the
|
||||
// directory path
|
||||
var fullpaths = modules.map(function (filename) {
|
||||
var mod_name = filename.replace(extensionPattern, '');
|
||||
return [p, mod_name].join('/');
|
||||
});
|
||||
|
||||
// sort filenames here, because Array.map changes order
|
||||
fullpaths.sort();
|
||||
|
||||
cb(null, fullpaths);
|
||||
});
|
||||
}
|
||||
});
|
||||
}, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* Evaluates JavaScript files in a sandbox, returning the context. The first
|
||||
* argument can either be a single filename or an array of filenames. If
|
||||
* multiple filenames are given their contents are concatenated before
|
||||
* evalution. The second argument is an optional context to use for the sandbox.
|
||||
*
|
||||
* @param files
|
||||
* @param {Object} sandbox
|
||||
* @return {Object}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.sandbox = function (files, /*optional*/sandbox) {
|
||||
var source, script, result;
|
||||
if (!(files instanceof Array)) {
|
||||
files = [files];
|
||||
}
|
||||
source = files.map(function (file) {
|
||||
return fs.readFileSync(file, 'utf8');
|
||||
}).join('');
|
||||
|
||||
if (!sandbox) {
|
||||
sandbox = {};
|
||||
}
|
||||
script = new Script(source);
|
||||
result = script.runInNewContext(sandbox);
|
||||
return sandbox;
|
||||
};
|
||||
|
||||
/**
|
||||
* Provides a http request, response testing environment.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* var httputil = require('nodeunit').utils.httputil
|
||||
* exports.testSomething = function(test) {
|
||||
* httputil(function (req, resp) {
|
||||
* resp.writeHead(200, {});
|
||||
* resp.end('test data');
|
||||
* },
|
||||
* function(server, client) {
|
||||
* client.fetch('GET', '/', {}, function(resp) {
|
||||
* test.equal('test data', resp.body);
|
||||
* server.close();
|
||||
* test.done();
|
||||
* })
|
||||
* });
|
||||
* };
|
||||
*
|
||||
* @param {Function} cgi
|
||||
* @param {Function} envReady
|
||||
* @api public
|
||||
*/
|
||||
exports.httputil = function (cgi, envReady) {
|
||||
var hostname = process.env.HOSTNAME || 'localhost';
|
||||
var port = process.env.PORT || 3000;
|
||||
|
||||
var server = http.createServer(cgi);
|
||||
server.listen(port, hostname);
|
||||
|
||||
var client = http.createClient(port, hostname);
|
||||
client.fetch = function (method, path, headers, respReady) {
|
||||
var request = this.request(method, path, headers);
|
||||
request.end();
|
||||
request.on('response', function (response) {
|
||||
response.setEncoding('utf8');
|
||||
response.on('data', function (chunk) {
|
||||
if (response.body) {
|
||||
response.body += chunk;
|
||||
} else {
|
||||
response.body = chunk;
|
||||
}
|
||||
});
|
||||
response.on('end', function () {
|
||||
if (response.headers['content-type'] === 'application/json') {
|
||||
response.bodyAsObject = JSON.parse(response.body);
|
||||
}
|
||||
respReady(response);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
process.nextTick(function () {
|
||||
if (envReady && typeof envReady === 'function') {
|
||||
envReady(server, client);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Improves formatting of AssertionError messages to make deepEqual etc more
|
||||
* readable.
|
||||
*
|
||||
* @param {Object} assertion
|
||||
* @return {Object}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.betterErrors = function (assertion) {
|
||||
if (!assertion.error) return;
|
||||
|
||||
var e = assertion.error;
|
||||
// deepEqual error message is a bit sucky, lets improve it!
|
||||
// e.actual and e.expected could be null or undefined, so
|
||||
// using getOwnPropertyDescriptor to see if they exist:
|
||||
if (Object.getOwnPropertyDescriptor(e, 'actual') &&
|
||||
Object.getOwnPropertyDescriptor(e, 'expected')) {
|
||||
|
||||
// alexgorbatchev 2010-10-22 :: Added a bit of depth to inspection
|
||||
var actual = util.inspect(e.actual, false, 10).replace(/\n$/, '');
|
||||
var expected = util.inspect(e.expected, false, 10).replace(/\n$/, '');
|
||||
var multiline = (
|
||||
actual.indexOf('\n') !== -1 ||
|
||||
expected.indexOf('\n') !== -1
|
||||
);
|
||||
var spacing = (multiline ? '\n' : ' ');
|
||||
e._message = e.message;
|
||||
e.stack = (
|
||||
e.name + ':' + spacing +
|
||||
actual + spacing + e.operator + spacing +
|
||||
expected + '\n' +
|
||||
e.stack.split('\n').slice(1).join('\n')
|
||||
);
|
||||
}
|
||||
return assertion;
|
||||
};
|
||||
95
bin/node_modules/nodeunit/man1/nodeunit.1
generated
vendored
95
bin/node_modules/nodeunit/man1/nodeunit.1
generated
vendored
@@ -1,95 +0,0 @@
|
||||
.\" Generated with Ronnjs/v0.1
|
||||
.\" http://github.com/kapouer/ronnjs/
|
||||
.
|
||||
.TH "NODEUNIT" "1" "October 2010" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBnodeunit\fR \-\- simple node\.js unit testing tool
|
||||
.
|
||||
.SH "SYNOPSIS"
|
||||
.
|
||||
.nf
|
||||
nodeunit [options] <file\-or\-directory> [<file\-or\-directory> \.\.\.]
|
||||
.
|
||||
.fi
|
||||
.
|
||||
.SH "DESCRIPTION"
|
||||
Nodeunit is a simple unit testing tool based on the node\.js assert module\.
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
Simple to use
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
Just export the tests from a module
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
Helps you avoid common pitfalls when testing asynchronous code
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
Easy to add test cases with setUp and tearDown functions if you wish
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
Allows the use of mocks and stubs
|
||||
.
|
||||
.IP "" 0
|
||||
.
|
||||
.SH "OPTIONS"
|
||||
\fB\-\-config FILE\fR:
|
||||
.
|
||||
.br
|
||||
Load config options from a JSON file, allows the customisation
|
||||
of color schemes for the default test reporter etc\.
|
||||
See bin/nodeunit\.json for current available options\.
|
||||
.
|
||||
.P
|
||||
\fB\-\-reporter FILE\fR:
|
||||
.
|
||||
.br
|
||||
You can set the test reporter to a custom module or on of the modules
|
||||
in nodeunit/lib/reporters, when omitted, the default test runner is used\.
|
||||
.
|
||||
.P
|
||||
\fB\-\-list\-reporters\fR:
|
||||
.
|
||||
.br
|
||||
List available build\-in reporters\.
|
||||
.
|
||||
.P
|
||||
\fB\-h\fR, \fB\-\-help\fR:
|
||||
.
|
||||
.br
|
||||
Display the help and exit\.
|
||||
.
|
||||
.P
|
||||
\fB\-v\fR, \fB\-\-version\fR:
|
||||
.
|
||||
.br
|
||||
Output version information and exit\.
|
||||
.
|
||||
.P
|
||||
\fB<file\-or\-directory>\fR:
|
||||
You can run nodeunit on specific files or on all \fI*\.js\fR files inside
|
||||
.
|
||||
.br
|
||||
a directory\.
|
||||
.
|
||||
.SH "AUTHORS"
|
||||
Written by Caolan McMahon and other nodeunit contributors\.
|
||||
.
|
||||
.br
|
||||
Contributors list: \fIhttp://github\.com/caolan/nodeunit/contributors\fR\|\.
|
||||
.
|
||||
.SH "REPORTING BUGS"
|
||||
Report nodeunit bugs to \fIhttp://github\.com/caolan/nodeunit/issues\fR\|\.
|
||||
.
|
||||
.SH "COPYRIGHT"
|
||||
Copyright © 2010 Caolan McMahon\.
|
||||
.
|
||||
.br
|
||||
Nodeunit has been released under the MIT license:
|
||||
.
|
||||
.br
|
||||
\fIhttp://github\.com/caolan/nodeunit/raw/master/LICENSE\fR\|\.
|
||||
.
|
||||
.SH "SEE ALSO"
|
||||
node(1)
|
||||
4
bin/node_modules/nodeunit/nodelint.cfg
generated
vendored
4
bin/node_modules/nodeunit/nodelint.cfg
generated
vendored
@@ -1,4 +0,0 @@
|
||||
var options = {
|
||||
indent: 4,
|
||||
onevar: false
|
||||
};
|
||||
56
bin/node_modules/nodeunit/package.json
generated
vendored
56
bin/node_modules/nodeunit/package.json
generated
vendored
@@ -1,56 +0,0 @@
|
||||
{ "name": "nodeunit"
|
||||
, "description": "Easy unit testing for node.js and the browser."
|
||||
, "maintainers":
|
||||
[ { "name": "Caolan McMahon"
|
||||
, "web": "https://github.com/caolan"
|
||||
}
|
||||
]
|
||||
, "contributors" :
|
||||
[ { "name": "Alex Gorbatchev"
|
||||
, "web": "https://github.com/alexgorbatchev"
|
||||
}
|
||||
, { "name": "Alex Wolfe"
|
||||
, "web": "https://github.com/alexkwolfe"
|
||||
}
|
||||
, { "name": "Carl Fürstenberg"
|
||||
, "web": "https://github.com/azatoth"
|
||||
}
|
||||
, { "name": "Gerad Suyderhoud"
|
||||
, "web": "https://github.com/gerad"
|
||||
}
|
||||
, { "name": "Kadir Pekel"
|
||||
, "web": "https://github.com/coffeemate"
|
||||
}
|
||||
, { "name": "Oleg Efimov"
|
||||
, "web": "https://github.com/Sannis"
|
||||
}
|
||||
, { "name": "Orlando Vazquez"
|
||||
, "web": "https://github.com/orlandov"
|
||||
}
|
||||
, { "name": "Ryan Dahl"
|
||||
, "web": "https://github.com/ry"
|
||||
}
|
||||
, { "name": "Sam Stephenson"
|
||||
, "web": "https://github.com/sstephenson"
|
||||
}
|
||||
, { "name": "Thomas Mayfield"
|
||||
, "web": "https://github.com/thegreatape"
|
||||
}
|
||||
, { "name": "Elijah Insua <tmpvar@gmail.com>",
|
||||
"web": "http://tmpvar.com"
|
||||
}
|
||||
]
|
||||
, "version": "0.5.3"
|
||||
, "repository" :
|
||||
{ "type" : "git"
|
||||
, "url" : "http://github.com/caolan/nodeunit.git"
|
||||
}
|
||||
, "bugs" : { "web" : "http://github.com/caolan/nodeunit/issues" }
|
||||
, "licenses" :
|
||||
[ { "type" : "MIT"
|
||||
, "url" : "http://github.com/caolan/nodeunit/raw/master/LICENSE"
|
||||
}
|
||||
]
|
||||
, "directories" : { "lib": "./lib", "doc" : "./doc", "man" : "./man1" }
|
||||
, "bin" : { "nodeunit" : "./bin/nodeunit" }
|
||||
}
|
||||
19
bin/node_modules/nodeunit/share/junit.xml.ejs
generated
vendored
19
bin/node_modules/nodeunit/share/junit.xml.ejs
generated
vendored
@@ -1,19 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<% for (var i=0; i < suites.length; i++) { %>
|
||||
<% var suite=suites[i]; %>
|
||||
<testsuite name="<%= suite.name %>"
|
||||
errors="<%= suite.errorCount %>"
|
||||
failures="<%= suite.failureCount %>"
|
||||
tests="<%= suite.tests %>">
|
||||
<% for (var j=0; j < suite.testcases.length; j++) { %>
|
||||
<% var testcase=suites[i].testcases[j]; %>
|
||||
<testcase name="<%= testcase.name %>">
|
||||
<% if (testcase.failure) { %>
|
||||
<failure message="<%= testcase.failure.message %>">
|
||||
<% if (testcase.failure.backtrace) { %><%= testcase.failure.backtrace %><% } %>
|
||||
</failure>
|
||||
<% } %>
|
||||
</testcase>
|
||||
<% } %>
|
||||
</testsuite>
|
||||
<% } %>
|
||||
11
bin/node_modules/nodeunit/share/license.js
generated
vendored
11
bin/node_modules/nodeunit/share/license.js
generated
vendored
@@ -1,11 +0,0 @@
|
||||
/*!
|
||||
* Nodeunit
|
||||
* https://github.com/caolan/nodeunit
|
||||
* Copyright (c) 2010 Caolan McMahon
|
||||
* MIT Licensed
|
||||
*
|
||||
* json2.js
|
||||
* http://www.JSON.org/json2.js
|
||||
* Public Domain.
|
||||
* NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
|
||||
*/
|
||||
70
bin/node_modules/nodeunit/share/nodeunit.css
generated
vendored
70
bin/node_modules/nodeunit/share/nodeunit.css
generated
vendored
@@ -1,70 +0,0 @@
|
||||
/*!
|
||||
* Styles taken from qunit.css
|
||||
*/
|
||||
|
||||
h1#nodeunit-header, h1.nodeunit-header {
|
||||
padding: 15px;
|
||||
font-size: large;
|
||||
background-color: #06b;
|
||||
color: white;
|
||||
font-family: 'trebuchet ms', verdana, arial;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
h1#nodeunit-header a {
|
||||
color: white;
|
||||
}
|
||||
|
||||
h2#nodeunit-banner {
|
||||
height: 2em;
|
||||
border-bottom: 1px solid white;
|
||||
background-color: #eee;
|
||||
margin: 0;
|
||||
font-family: 'trebuchet ms', verdana, arial;
|
||||
}
|
||||
h2#nodeunit-banner.pass {
|
||||
background-color: green;
|
||||
}
|
||||
h2#nodeunit-banner.fail {
|
||||
background-color: red;
|
||||
}
|
||||
|
||||
h2#nodeunit-userAgent, h2.nodeunit-userAgent {
|
||||
padding: 10px;
|
||||
background-color: #eee;
|
||||
color: black;
|
||||
margin: 0;
|
||||
font-size: small;
|
||||
font-weight: normal;
|
||||
font-family: 'trebuchet ms', verdana, arial;
|
||||
font-size: 10pt;
|
||||
}
|
||||
|
||||
div#nodeunit-testrunner-toolbar {
|
||||
background: #eee;
|
||||
border-top: 1px solid black;
|
||||
padding: 10px;
|
||||
font-family: 'trebuchet ms', verdana, arial;
|
||||
margin: 0;
|
||||
font-size: 10pt;
|
||||
}
|
||||
|
||||
ol#nodeunit-tests {
|
||||
font-family: 'trebuchet ms', verdana, arial;
|
||||
font-size: 10pt;
|
||||
}
|
||||
ol#nodeunit-tests li strong {
|
||||
cursor:pointer;
|
||||
}
|
||||
ol#nodeunit-tests .pass {
|
||||
color: green;
|
||||
}
|
||||
ol#nodeunit-tests .fail {
|
||||
color: red;
|
||||
}
|
||||
|
||||
p#nodeunit-testresult {
|
||||
margin-left: 1em;
|
||||
font-size: 10pt;
|
||||
font-family: 'trebuchet ms', verdana, arial;
|
||||
}
|
||||
40
bin/node_modules/q/CONTRIBUTING.md
generated
vendored
Normal file
40
bin/node_modules/q/CONTRIBUTING.md
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
|
||||
For pull requests:
|
||||
|
||||
- Be consistent with prevalent style and design decisions.
|
||||
- Add a Jasmine spec to `specs/q-spec.js`.
|
||||
- Use `npm test` to avoid regressions.
|
||||
- Run tests in `q-spec/run.html` in as many supported browsers as you
|
||||
can find the will to deal with.
|
||||
- Do not build minified versions; we do this each release.
|
||||
- If you would be so kind, add a note to `CHANGES.md` in an
|
||||
appropriate section:
|
||||
|
||||
- `Next Major Version` if it introduces backward incompatibilities
|
||||
to code in the wild using documented features.
|
||||
- `Next Minor Version` if it adds a new feature.
|
||||
- `Next Patch Version` if it fixes a bug.
|
||||
|
||||
For releases:
|
||||
|
||||
- Run `npm test`.
|
||||
- Run tests in `q-spec/run.html` in a representative sample of every
|
||||
browser under the sun.
|
||||
- Run `npm run cover` and make sure you're happy with the results.
|
||||
- Run `npm run minify` and be sure to commit the resulting `q.min.js`.
|
||||
- Note the Gzipped size output by the previous command, and update
|
||||
`README.md` if it has changed to 1 significant digit.
|
||||
- Stash any local changes.
|
||||
- Update `CHANGES.md` to reflect all changes in the differences
|
||||
between `HEAD` and the previous tagged version. Give credit where
|
||||
credit is due.
|
||||
- Update `README.md` to address all new, non-experimental features.
|
||||
- Update the API reference on the Wiki to reflect all non-experimental
|
||||
features.
|
||||
- Use `npm version major|minor|patch` to update `package.json`,
|
||||
commit, and tag the new version.
|
||||
- Use `npm publish` to send up a new release.
|
||||
- Send an email to the q-continuum mailing list announcing the new
|
||||
release and the notes from the change log. This helps folks
|
||||
maintaining other package ecosystems.
|
||||
|
||||
16
bin/node_modules/nodeunit/LICENSE → bin/node_modules/q/LICENSE
generated
vendored
16
bin/node_modules/nodeunit/LICENSE → bin/node_modules/q/LICENSE
generated
vendored
@@ -1,10 +1,10 @@
|
||||
Copyright (c) 2010 Caolan McMahon
|
||||
|
||||
Copyright 2009–2012 Kristopher Michael Kowal. All rights reserved.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
of this software and associated documentation files (the "Software"), to
|
||||
deal in the Software without restriction, including without limitation the
|
||||
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
@@ -14,6 +14,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
IN THE SOFTWARE.
|
||||
813
bin/node_modules/q/README.md
generated
vendored
Normal file
813
bin/node_modules/q/README.md
generated
vendored
Normal file
@@ -0,0 +1,813 @@
|
||||
[](http://travis-ci.org/kriskowal/q)
|
||||
|
||||
<a href="http://promises-aplus.github.com/promises-spec">
|
||||
<img src="http://promises-aplus.github.com/promises-spec/assets/logo-small.png"
|
||||
align="right" alt="Promises/A+ logo" />
|
||||
</a>
|
||||
|
||||
If a function cannot return a value or throw an exception without
|
||||
blocking, it can return a promise instead. A promise is an object
|
||||
that represents the return value or the thrown exception that the
|
||||
function may eventually provide. A promise can also be used as a
|
||||
proxy for a [remote object][Q-Connection] to overcome latency.
|
||||
|
||||
[Q-Connection]: https://github.com/kriskowal/q-connection
|
||||
|
||||
On the first pass, promises can mitigate the “[Pyramid of
|
||||
Doom][POD]”: the situation where code marches to the right faster
|
||||
than it marches forward.
|
||||
|
||||
[POD]: http://calculist.org/blog/2011/12/14/why-coroutines-wont-work-on-the-web/
|
||||
|
||||
```javascript
|
||||
step1(function (value1) {
|
||||
step2(value1, function(value2) {
|
||||
step3(value2, function(value3) {
|
||||
step4(value3, function(value4) {
|
||||
// Do something with value4
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
With a promise library, you can flatten the pyramid.
|
||||
|
||||
```javascript
|
||||
Q.fcall(promisedStep1)
|
||||
.then(promisedStep2)
|
||||
.then(promisedStep3)
|
||||
.then(promisedStep4)
|
||||
.then(function (value4) {
|
||||
// Do something with value4
|
||||
})
|
||||
.catch(function (error) {
|
||||
// Handle any error from all above steps
|
||||
})
|
||||
.done();
|
||||
```
|
||||
|
||||
With this approach, you also get implicit error propagation, just like `try`,
|
||||
`catch`, and `finally`. An error in `promisedStep1` will flow all the way to
|
||||
the `catch` function, where it’s caught and handled. (Here `promisedStepN` is
|
||||
a version of `stepN` that returns a promise.)
|
||||
|
||||
The callback approach is called an “inversion of control”.
|
||||
A function that accepts a callback instead of a return value
|
||||
is saying, “Don’t call me, I’ll call you.”. Promises
|
||||
[un-invert][IOC] the inversion, cleanly separating the input
|
||||
arguments from control flow arguments. This simplifies the
|
||||
use and creation of API’s, particularly variadic,
|
||||
rest and spread arguments.
|
||||
|
||||
[IOC]: http://www.slideshare.net/domenicdenicola/callbacks-promises-and-coroutines-oh-my-the-evolution-of-asynchronicity-in-javascript
|
||||
|
||||
|
||||
## Getting Started
|
||||
|
||||
The Q module can be loaded as:
|
||||
|
||||
- A ``<script>`` tag (creating a ``Q`` global variable): ~2.5 KB minified and
|
||||
gzipped.
|
||||
- A Node.js and CommonJS module, available in [npm](https://npmjs.org/) as
|
||||
the [q](https://npmjs.org/package/q) package
|
||||
- An AMD module
|
||||
- A [component](https://github.com/component/component) as ``microjs/q``
|
||||
- Using [bower](http://bower.io/) as ``q``
|
||||
- Using [NuGet](http://nuget.org/) as [Q](https://nuget.org/packages/q)
|
||||
|
||||
Q can exchange promises with jQuery, Dojo, When.js, WinJS, and more.
|
||||
|
||||
## Resources
|
||||
|
||||
Our [wiki][] contains a number of useful resources, including:
|
||||
|
||||
- A method-by-method [Q API reference][reference].
|
||||
- A growing [examples gallery][examples], showing how Q can be used to make
|
||||
everything better. From XHR to database access to accessing the Flickr API,
|
||||
Q is there for you.
|
||||
- There are many libraries that produce and consume Q promises for everything
|
||||
from file system/database access or RPC to templating. For a list of some of
|
||||
the more popular ones, see [Libraries][].
|
||||
- If you want materials that introduce the promise concept generally, and the
|
||||
below tutorial isn't doing it for you, check out our collection of
|
||||
[presentations, blog posts, and podcasts][resources].
|
||||
- A guide for those [coming from jQuery's `$.Deferred`][jquery].
|
||||
|
||||
We'd also love to have you join the Q-Continuum [mailing list][].
|
||||
|
||||
[wiki]: https://github.com/kriskowal/q/wiki
|
||||
[reference]: https://github.com/kriskowal/q/wiki/API-Reference
|
||||
[examples]: https://github.com/kriskowal/q/wiki/Examples-Gallery
|
||||
[Libraries]: https://github.com/kriskowal/q/wiki/Libraries
|
||||
[resources]: https://github.com/kriskowal/q/wiki/General-Promise-Resources
|
||||
[jquery]: https://github.com/kriskowal/q/wiki/Coming-from-jQuery
|
||||
[mailing list]: https://groups.google.com/forum/#!forum/q-continuum
|
||||
|
||||
|
||||
## Tutorial
|
||||
|
||||
Promises have a ``then`` method, which you can use to get the eventual
|
||||
return value (fulfillment) or thrown exception (rejection).
|
||||
|
||||
```javascript
|
||||
promiseMeSomething()
|
||||
.then(function (value) {
|
||||
}, function (reason) {
|
||||
});
|
||||
```
|
||||
|
||||
If ``promiseMeSomething`` returns a promise that gets fulfilled later
|
||||
with a return value, the first function (the fulfillment handler) will be
|
||||
called with the value. However, if the ``promiseMeSomething`` function
|
||||
gets rejected later by a thrown exception, the second function (the
|
||||
rejection handler) will be called with the exception.
|
||||
|
||||
Note that resolution of a promise is always asynchronous: that is, the
|
||||
fulfillment or rejection handler will always be called in the next turn of the
|
||||
event loop (i.e. `process.nextTick` in Node). This gives you a nice
|
||||
guarantee when mentally tracing the flow of your code, namely that
|
||||
``then`` will always return before either handler is executed.
|
||||
|
||||
In this tutorial, we begin with how to consume and work with promises. We'll
|
||||
talk about how to create them, and thus create functions like
|
||||
`promiseMeSomething` that return promises, [below](#the-beginning).
|
||||
|
||||
|
||||
### Propagation
|
||||
|
||||
The ``then`` method returns a promise, which in this example, I’m
|
||||
assigning to ``outputPromise``.
|
||||
|
||||
```javascript
|
||||
var outputPromise = getInputPromise()
|
||||
.then(function (input) {
|
||||
}, function (reason) {
|
||||
});
|
||||
```
|
||||
|
||||
The ``outputPromise`` variable becomes a new promise for the return
|
||||
value of either handler. Since a function can only either return a
|
||||
value or throw an exception, only one handler will ever be called and it
|
||||
will be responsible for resolving ``outputPromise``.
|
||||
|
||||
- If you return a value in a handler, ``outputPromise`` will get
|
||||
fulfilled.
|
||||
|
||||
- If you throw an exception in a handler, ``outputPromise`` will get
|
||||
rejected.
|
||||
|
||||
- If you return a **promise** in a handler, ``outputPromise`` will
|
||||
“become” that promise. Being able to become a new promise is useful
|
||||
for managing delays, combining results, or recovering from errors.
|
||||
|
||||
If the ``getInputPromise()`` promise gets rejected and you omit the
|
||||
rejection handler, the **error** will go to ``outputPromise``:
|
||||
|
||||
```javascript
|
||||
var outputPromise = getInputPromise()
|
||||
.then(function (value) {
|
||||
});
|
||||
```
|
||||
|
||||
If the input promise gets fulfilled and you omit the fulfillment handler, the
|
||||
**value** will go to ``outputPromise``:
|
||||
|
||||
```javascript
|
||||
var outputPromise = getInputPromise()
|
||||
.then(null, function (error) {
|
||||
});
|
||||
```
|
||||
|
||||
Q promises provide a ``fail`` shorthand for ``then`` when you are only
|
||||
interested in handling the error:
|
||||
|
||||
```javascript
|
||||
var outputPromise = getInputPromise()
|
||||
.fail(function (error) {
|
||||
});
|
||||
```
|
||||
|
||||
If you are writing JavaScript for modern engines only or using
|
||||
CoffeeScript, you may use `catch` instead of `fail`.
|
||||
|
||||
Promises also have a ``fin`` function that is like a ``finally`` clause.
|
||||
The final handler gets called, with no arguments, when the promise
|
||||
returned by ``getInputPromise()`` either returns a value or throws an
|
||||
error. The value returned or error thrown by ``getInputPromise()``
|
||||
passes directly to ``outputPromise`` unless the final handler fails, and
|
||||
may be delayed if the final handler returns a promise.
|
||||
|
||||
```javascript
|
||||
var outputPromise = getInputPromise()
|
||||
.fin(function () {
|
||||
// close files, database connections, stop servers, conclude tests
|
||||
});
|
||||
```
|
||||
|
||||
- If the handler returns a value, the value is ignored
|
||||
- If the handler throws an error, the error passes to ``outputPromise``
|
||||
- If the handler returns a promise, ``outputPromise`` gets postponed. The
|
||||
eventual value or error has the same effect as an immediate return
|
||||
value or thrown error: a value would be ignored, an error would be
|
||||
forwarded.
|
||||
|
||||
If you are writing JavaScript for modern engines only or using
|
||||
CoffeeScript, you may use `finally` instead of `fin`.
|
||||
|
||||
### Chaining
|
||||
|
||||
There are two ways to chain promises. You can chain promises either
|
||||
inside or outside handlers. The next two examples are equivalent.
|
||||
|
||||
```javascript
|
||||
return getUsername()
|
||||
.then(function (username) {
|
||||
return getUser(username)
|
||||
.then(function (user) {
|
||||
// if we get here without an error,
|
||||
// the value returned here
|
||||
// or the exception thrown here
|
||||
// resolves the promise returned
|
||||
// by the first line
|
||||
})
|
||||
});
|
||||
```
|
||||
|
||||
```javascript
|
||||
return getUsername()
|
||||
.then(function (username) {
|
||||
return getUser(username);
|
||||
})
|
||||
.then(function (user) {
|
||||
// if we get here without an error,
|
||||
// the value returned here
|
||||
// or the exception thrown here
|
||||
// resolves the promise returned
|
||||
// by the first line
|
||||
});
|
||||
```
|
||||
|
||||
The only difference is nesting. It’s useful to nest handlers if you
|
||||
need to capture multiple input values in your closure.
|
||||
|
||||
```javascript
|
||||
function authenticate() {
|
||||
return getUsername()
|
||||
.then(function (username) {
|
||||
return getUser(username);
|
||||
})
|
||||
// chained because we will not need the user name in the next event
|
||||
.then(function (user) {
|
||||
return getPassword()
|
||||
// nested because we need both user and password next
|
||||
.then(function (password) {
|
||||
if (user.passwordHash !== hash(password)) {
|
||||
throw new Error("Can't authenticate");
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### Combination
|
||||
|
||||
You can turn an array of promises into a promise for the whole,
|
||||
fulfilled array using ``all``.
|
||||
|
||||
```javascript
|
||||
return Q.all([
|
||||
eventualAdd(2, 2),
|
||||
eventualAdd(10, 20)
|
||||
]);
|
||||
```
|
||||
|
||||
If you have a promise for an array, you can use ``spread`` as a
|
||||
replacement for ``then``. The ``spread`` function “spreads” the
|
||||
values over the arguments of the fulfillment handler. The rejection handler
|
||||
will get called at the first sign of failure. That is, whichever of
|
||||
the recived promises fails first gets handled by the rejection handler.
|
||||
|
||||
```javascript
|
||||
function eventualAdd(a, b) {
|
||||
return Q.spread([a, b], function (a, b) {
|
||||
return a + b;
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
But ``spread`` calls ``all`` initially, so you can skip it in chains.
|
||||
|
||||
```javascript
|
||||
return getUsername()
|
||||
.then(function (username) {
|
||||
return [username, getUser(username)];
|
||||
})
|
||||
.spread(function (username, user) {
|
||||
});
|
||||
```
|
||||
|
||||
The ``all`` function returns a promise for an array of values. When this
|
||||
promise is fulfilled, the array contains the fulfillment values of the original
|
||||
promises, in the same order as those promises. If one of the given promises
|
||||
is rejected, the returned promise is immediately rejected, not waiting for the
|
||||
rest of the batch. If you want to wait for all of the promises to either be
|
||||
fulfilled or rejected, you can use ``allSettled``.
|
||||
|
||||
```javascript
|
||||
Q.allSettled(promises)
|
||||
.then(function (results) {
|
||||
results.forEach(function (result) {
|
||||
if (result.state === "fulfilled") {
|
||||
var value = result.value;
|
||||
} else {
|
||||
var reason = result.reason;
|
||||
}
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
### Sequences
|
||||
|
||||
If you have a number of promise-producing functions that need
|
||||
to be run sequentially, you can of course do so manually:
|
||||
|
||||
```javascript
|
||||
return foo(initialVal).then(bar).then(baz).then(qux);
|
||||
```
|
||||
|
||||
However, if you want to run a dynamically constructed sequence of
|
||||
functions, you'll want something like this:
|
||||
|
||||
```javascript
|
||||
var funcs = [foo, bar, baz, qux];
|
||||
|
||||
var result = Q(initialVal);
|
||||
funcs.forEach(function (f) {
|
||||
result = result.then(f);
|
||||
});
|
||||
return result;
|
||||
```
|
||||
|
||||
You can make this slightly more compact using `reduce`:
|
||||
|
||||
```javascript
|
||||
return funcs.reduce(function (soFar, f) {
|
||||
return soFar.then(f);
|
||||
}, Q(initialVal));
|
||||
```
|
||||
|
||||
Or, you could use th ultra-compact version:
|
||||
|
||||
```javascript
|
||||
return funcs.reduce(Q.when, Q());
|
||||
```
|
||||
|
||||
### Handling Errors
|
||||
|
||||
One sometimes-unintuive aspect of promises is that if you throw an
|
||||
exception in the fulfillment handler, it will not be be caught by the error
|
||||
handler.
|
||||
|
||||
```javascript
|
||||
return foo()
|
||||
.then(function (value) {
|
||||
throw new Error("Can't bar.");
|
||||
}, function (error) {
|
||||
// We only get here if "foo" fails
|
||||
});
|
||||
```
|
||||
|
||||
To see why this is, consider the parallel between promises and
|
||||
``try``/``catch``. We are ``try``-ing to execute ``foo()``: the error
|
||||
handler represents a ``catch`` for ``foo()``, while the fulfillment handler
|
||||
represents code that happens *after* the ``try``/``catch`` block.
|
||||
That code then needs its own ``try``/``catch`` block.
|
||||
|
||||
In terms of promises, this means chaining your rejection handler:
|
||||
|
||||
```javascript
|
||||
return foo()
|
||||
.then(function (value) {
|
||||
throw new Error("Can't bar.");
|
||||
})
|
||||
.fail(function (error) {
|
||||
// We get here with either foo's error or bar's error
|
||||
});
|
||||
```
|
||||
|
||||
### Progress Notification
|
||||
|
||||
It's possible for promises to report their progress, e.g. for tasks that take a
|
||||
long time like a file upload. Not all promises will implement progress
|
||||
notifications, but for those that do, you can consume the progress values using
|
||||
a third parameter to ``then``:
|
||||
|
||||
```javascript
|
||||
return uploadFile()
|
||||
.then(function () {
|
||||
// Success uploading the file
|
||||
}, function (err) {
|
||||
// There was an error, and we get the reason for error
|
||||
}, function (progress) {
|
||||
// We get notified of the upload's progress as it is executed
|
||||
});
|
||||
```
|
||||
|
||||
Like `fail`, Q also provides a shorthand for progress callbacks
|
||||
called `progress`:
|
||||
|
||||
```javascript
|
||||
return uploadFile().progress(function (progress) {
|
||||
// We get notified of the upload's progress
|
||||
});
|
||||
```
|
||||
|
||||
### The End
|
||||
|
||||
When you get to the end of a chain of promises, you should either
|
||||
return the last promise or end the chain. Since handlers catch
|
||||
errors, it’s an unfortunate pattern that the exceptions can go
|
||||
unobserved.
|
||||
|
||||
So, either return it,
|
||||
|
||||
```javascript
|
||||
return foo()
|
||||
.then(function () {
|
||||
return "bar";
|
||||
});
|
||||
```
|
||||
|
||||
Or, end it.
|
||||
|
||||
```javascript
|
||||
foo()
|
||||
.then(function () {
|
||||
return "bar";
|
||||
})
|
||||
.done();
|
||||
```
|
||||
|
||||
Ending a promise chain makes sure that, if an error doesn’t get
|
||||
handled before the end, it will get rethrown and reported.
|
||||
|
||||
This is a stopgap. We are exploring ways to make unhandled errors
|
||||
visible without any explicit handling.
|
||||
|
||||
|
||||
### The Beginning
|
||||
|
||||
Everything above assumes you get a promise from somewhere else. This
|
||||
is the common case. Every once in a while, you will need to create a
|
||||
promise from scratch.
|
||||
|
||||
#### Using ``Q.fcall``
|
||||
|
||||
You can create a promise from a value using ``Q.fcall``. This returns a
|
||||
promise for 10.
|
||||
|
||||
```javascript
|
||||
return Q.fcall(function () {
|
||||
return 10;
|
||||
});
|
||||
```
|
||||
|
||||
You can also use ``fcall`` to get a promise for an exception.
|
||||
|
||||
```javascript
|
||||
return Q.fcall(function () {
|
||||
throw new Error("Can't do it");
|
||||
});
|
||||
```
|
||||
|
||||
As the name implies, ``fcall`` can call functions, or even promised
|
||||
functions. This uses the ``eventualAdd`` function above to add two
|
||||
numbers.
|
||||
|
||||
```javascript
|
||||
return Q.fcall(eventualAdd, 2, 2);
|
||||
```
|
||||
|
||||
|
||||
#### Using Deferreds
|
||||
|
||||
If you have to interface with asynchronous functions that are callback-based
|
||||
instead of promise-based, Q provides a few shortcuts (like ``Q.nfcall`` and
|
||||
friends). But much of the time, the solution will be to use *deferreds*.
|
||||
|
||||
```javascript
|
||||
var deferred = Q.defer();
|
||||
FS.readFile("foo.txt", "utf-8", function (error, text) {
|
||||
if (error) {
|
||||
deferred.reject(new Error(error));
|
||||
} else {
|
||||
deferred.resolve(text);
|
||||
}
|
||||
});
|
||||
return deferred.promise;
|
||||
```
|
||||
|
||||
Note that a deferred can be resolved with a value or a promise. The
|
||||
``reject`` function is a shorthand for resolving with a rejected
|
||||
promise.
|
||||
|
||||
```javascript
|
||||
// this:
|
||||
deferred.reject(new Error("Can't do it"));
|
||||
|
||||
// is shorthand for:
|
||||
var rejection = Q.fcall(function () {
|
||||
throw new Error("Can't do it");
|
||||
});
|
||||
deferred.resolve(rejection);
|
||||
```
|
||||
|
||||
This is a simplified implementation of ``Q.delay``.
|
||||
|
||||
```javascript
|
||||
function delay(ms) {
|
||||
var deferred = Q.defer();
|
||||
setTimeout(deferred.resolve, ms);
|
||||
return deferred.promise;
|
||||
}
|
||||
```
|
||||
|
||||
This is a simplified implementation of ``Q.timeout``
|
||||
|
||||
```javascript
|
||||
function timeout(promise, ms) {
|
||||
var deferred = Q.defer();
|
||||
Q.when(promise, deferred.resolve);
|
||||
delay(ms).then(function () {
|
||||
deferred.reject(new Error("Timed out"));
|
||||
});
|
||||
return deferred.promise;
|
||||
}
|
||||
```
|
||||
|
||||
Finally, you can send a progress notification to the promise with
|
||||
``deferred.notify``.
|
||||
|
||||
For illustration, this is a wrapper for XML HTTP requests in the browser. Note
|
||||
that a more [thorough][XHR] implementation would be in order in practice.
|
||||
|
||||
[XHR]: https://github.com/montagejs/mr/blob/71e8df99bb4f0584985accd6f2801ef3015b9763/browser.js#L29-L73
|
||||
|
||||
```javascript
|
||||
function requestOkText(url) {
|
||||
var request = new XMLHttpRequest();
|
||||
var deferred = Q.defer();
|
||||
|
||||
request.open("GET", url, true);
|
||||
request.onload = onload;
|
||||
request.onerror = onerror;
|
||||
request.onprogress = onprogress;
|
||||
request.send();
|
||||
|
||||
function onload() {
|
||||
if (request.status === 200) {
|
||||
deferred.resolve(request.responseText);
|
||||
} else {
|
||||
deferred.reject(new Error("Status code was " + request.status));
|
||||
}
|
||||
}
|
||||
|
||||
function onerror() {
|
||||
deferred.reject(new Error("Can't XHR " + JSON.stringify(url)));
|
||||
}
|
||||
|
||||
function onprogress(event) {
|
||||
deferred.notify(event.loaded / event.total);
|
||||
}
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
```
|
||||
|
||||
Below is an example of how to use this ``requestOkText`` function:
|
||||
|
||||
```javascript
|
||||
requestOkText("http://localhost:3000")
|
||||
.then(function (responseText) {
|
||||
// If the HTTP response returns 200 OK, log the response text.
|
||||
console.log(responseText);
|
||||
}, function (error) {
|
||||
// If there's an error or a non-200 status code, log the error.
|
||||
console.error(error);
|
||||
}, function (progress) {
|
||||
// Log the progress as it comes in.
|
||||
console.log("Request progress: " + Math.round(progress * 100) + "%");
|
||||
});
|
||||
```
|
||||
|
||||
### The Middle
|
||||
|
||||
If you are using a function that may return a promise, but just might
|
||||
return a value if it doesn’t need to defer, you can use the “static”
|
||||
methods of the Q library.
|
||||
|
||||
The ``when`` function is the static equivalent for ``then``.
|
||||
|
||||
```javascript
|
||||
return Q.when(valueOrPromise, function (value) {
|
||||
}, function (error) {
|
||||
});
|
||||
```
|
||||
|
||||
All of the other methods on a promise have static analogs with the
|
||||
same name.
|
||||
|
||||
The following are equivalent:
|
||||
|
||||
```javascript
|
||||
return Q.all([a, b]);
|
||||
```
|
||||
|
||||
```javascript
|
||||
return Q.fcall(function () {
|
||||
return [a, b];
|
||||
})
|
||||
.all();
|
||||
```
|
||||
|
||||
When working with promises provided by other libraries, you should
|
||||
convert it to a Q promise. Not all promise libraries make the same
|
||||
guarantees as Q and certainly don’t provide all of the same methods.
|
||||
Most libraries only provide a partially functional ``then`` method.
|
||||
This thankfully is all we need to turn them into vibrant Q promises.
|
||||
|
||||
```javascript
|
||||
return Q($.ajax(...))
|
||||
.then(function () {
|
||||
});
|
||||
```
|
||||
|
||||
If there is any chance that the promise you receive is not a Q promise
|
||||
as provided by your library, you should wrap it using a Q function.
|
||||
You can even use ``Q.invoke`` as a shorthand.
|
||||
|
||||
```javascript
|
||||
return Q.invoke($, 'ajax', ...)
|
||||
.then(function () {
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
### Over the Wire
|
||||
|
||||
A promise can serve as a proxy for another object, even a remote
|
||||
object. There are methods that allow you to optimistically manipulate
|
||||
properties or call functions. All of these interactions return
|
||||
promises, so they can be chained.
|
||||
|
||||
```
|
||||
direct manipulation using a promise as a proxy
|
||||
-------------------------- -------------------------------
|
||||
value.foo promise.get("foo")
|
||||
value.foo = value promise.put("foo", value)
|
||||
delete value.foo promise.del("foo")
|
||||
value.foo(...args) promise.post("foo", [args])
|
||||
value.foo(...args) promise.invoke("foo", ...args)
|
||||
value(...args) promise.fapply([args])
|
||||
value(...args) promise.fcall(...args)
|
||||
```
|
||||
|
||||
If the promise is a proxy for a remote object, you can shave
|
||||
round-trips by using these functions instead of ``then``. To take
|
||||
advantage of promises for remote objects, check out [Q-Connection][].
|
||||
|
||||
[Q-Connection]: https://github.com/kriskowal/q-connection
|
||||
|
||||
Even in the case of non-remote objects, these methods can be used as
|
||||
shorthand for particularly-simple fulfillment handlers. For example, you
|
||||
can replace
|
||||
|
||||
```javascript
|
||||
return Q.fcall(function () {
|
||||
return [{ foo: "bar" }, { foo: "baz" }];
|
||||
})
|
||||
.then(function (value) {
|
||||
return value[0].foo;
|
||||
});
|
||||
```
|
||||
|
||||
with
|
||||
|
||||
```javascript
|
||||
return Q.fcall(function () {
|
||||
return [{ foo: "bar" }, { foo: "baz" }];
|
||||
})
|
||||
.get(0)
|
||||
.get("foo");
|
||||
```
|
||||
|
||||
|
||||
### Adapting Node
|
||||
|
||||
If you're working with functions that make use of the Node.js callback pattern,
|
||||
where callbacks are in the form of `function(err, result)`, Q provides a few
|
||||
useful utility functions for converting between them. The most straightforward
|
||||
are probably `Q.nfcall` and `Q.nfapply` ("Node function call/apply") for calling
|
||||
Node.js-style functions and getting back a promise:
|
||||
|
||||
```javascript
|
||||
return Q.nfcall(FS.readFile, "foo.txt", "utf-8");
|
||||
return Q.nfapply(FS.readFile, ["foo.txt", "utf-8"]);
|
||||
```
|
||||
|
||||
If you are working with methods, instead of simple functions, you can easily
|
||||
run in to the usual problems where passing a method to another function—like
|
||||
`Q.nfcall`—"un-binds" the method from its owner. To avoid this, you can either
|
||||
use `Function.prototype.bind` or some nice shortcut methods we provide:
|
||||
|
||||
```javascript
|
||||
return Q.ninvoke(redisClient, "get", "user:1:id");
|
||||
return Q.npost(redisClient, "get", ["user:1:id"]);
|
||||
```
|
||||
|
||||
You can also create reusable wrappers with `Q.denodeify` or `Q.nbind`:
|
||||
|
||||
```javascript
|
||||
var readFile = Q.denodeify(FS.readFile);
|
||||
return readFile("foo.txt", "utf-8");
|
||||
|
||||
var redisClientGet = Q.nbind(redisClient.get, redisClient);
|
||||
return redisClientGet("user:1:id");
|
||||
```
|
||||
|
||||
Finally, if you're working with raw deferred objects, there is a
|
||||
`makeNodeResolver` method on deferreds that can be handy:
|
||||
|
||||
```javascript
|
||||
var deferred = Q.defer();
|
||||
FS.readFile("foo.txt", "utf-8", deferred.makeNodeResolver());
|
||||
return deferred.promise;
|
||||
```
|
||||
|
||||
### Long Stack Traces
|
||||
|
||||
Q comes with optional support for “long stack traces,” wherein the `stack`
|
||||
property of `Error` rejection reasons is rewritten to be traced along
|
||||
asynchronous jumps instead of stopping at the most recent one. As an example:
|
||||
|
||||
```js
|
||||
function theDepthsOfMyProgram() {
|
||||
Q.delay(100).done(function explode() {
|
||||
throw new Error("boo!");
|
||||
});
|
||||
}
|
||||
|
||||
theDepthsOfMyProgram();
|
||||
```
|
||||
|
||||
usually would give a rather unhelpful stack trace looking something like
|
||||
|
||||
```
|
||||
Error: boo!
|
||||
at explode (/path/to/test.js:3:11)
|
||||
at _fulfilled (/path/to/test.js:q:54)
|
||||
at resolvedValue.promiseDispatch.done (/path/to/q.js:823:30)
|
||||
at makePromise.promise.promiseDispatch (/path/to/q.js:496:13)
|
||||
at pending (/path/to/q.js:397:39)
|
||||
at process.startup.processNextTick.process._tickCallback (node.js:244:9)
|
||||
```
|
||||
|
||||
But, if you turn this feature on by setting
|
||||
|
||||
```js
|
||||
Q.longStackSupport = true;
|
||||
```
|
||||
|
||||
then the above code gives a nice stack trace to the tune of
|
||||
|
||||
```
|
||||
Error: boo!
|
||||
at explode (/path/to/test.js:3:11)
|
||||
From previous event:
|
||||
at theDepthsOfMyProgram (/path/to/test.js:2:16)
|
||||
at Object.<anonymous> (/path/to/test.js:7:1)
|
||||
```
|
||||
|
||||
Note how you can see the the function that triggered the async operation in the
|
||||
stack trace! This is very helpful for debugging, as otherwise you end up getting
|
||||
only the first line, plus a bunch of Q internals, with no sign of where the
|
||||
operation started.
|
||||
|
||||
This feature does come with somewhat-serious performance and memory overhead,
|
||||
however. If you're working with lots of promises, or trying to scale a server
|
||||
to many users, you should probably keep it off. But in development, go for it!
|
||||
|
||||
## Tests
|
||||
|
||||
You can view the results of the Q test suite [in your browser][tests]!
|
||||
|
||||
[tests]: https://rawgithub.com/kriskowal/q/master/spec/q-spec.html
|
||||
|
||||
## License
|
||||
|
||||
Copyright 2009–2013 Kristopher Michael Kowal
|
||||
MIT License (enclosed)
|
||||
|
||||
71
bin/node_modules/q/benchmark/compare-with-callbacks.js
generated
vendored
Normal file
71
bin/node_modules/q/benchmark/compare-with-callbacks.js
generated
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
"use strict";
|
||||
|
||||
var Q = require("../q");
|
||||
var fs = require("fs");
|
||||
|
||||
suite("A single simple async operation", function () {
|
||||
bench("with an immediately-fulfilled promise", function (done) {
|
||||
Q().then(done);
|
||||
});
|
||||
|
||||
bench("with direct setImmediate usage", function (done) {
|
||||
setImmediate(done);
|
||||
});
|
||||
|
||||
bench("with direct setTimeout(…, 0)", function (done) {
|
||||
setTimeout(done, 0);
|
||||
});
|
||||
});
|
||||
|
||||
suite("A fs.readFile", function () {
|
||||
var denodeified = Q.denodeify(fs.readFile);
|
||||
|
||||
set("iterations", 1000);
|
||||
set("delay", 1000);
|
||||
|
||||
bench("directly, with callbacks", function (done) {
|
||||
fs.readFile(__filename, done);
|
||||
});
|
||||
|
||||
bench("with Q.nfcall", function (done) {
|
||||
Q.nfcall(fs.readFile, __filename).then(done);
|
||||
});
|
||||
|
||||
bench("with a Q.denodeify'ed version", function (done) {
|
||||
denodeified(__filename).then(done);
|
||||
});
|
||||
|
||||
bench("with manual usage of deferred.makeNodeResolver", function (done) {
|
||||
var deferred = Q.defer();
|
||||
fs.readFile(__filename, deferred.makeNodeResolver());
|
||||
deferred.promise.then(done);
|
||||
});
|
||||
});
|
||||
|
||||
suite("1000 operations in parallel", function () {
|
||||
function makeCounter(desiredCount, ultimateCallback) {
|
||||
var soFar = 0;
|
||||
return function () {
|
||||
if (++soFar === desiredCount) {
|
||||
ultimateCallback();
|
||||
}
|
||||
};
|
||||
}
|
||||
var numberOfOps = 1000;
|
||||
|
||||
bench("with immediately-fulfilled promises", function (done) {
|
||||
var counter = makeCounter(numberOfOps, done);
|
||||
|
||||
for (var i = 0; i < numberOfOps; ++i) {
|
||||
Q().then(counter);
|
||||
}
|
||||
});
|
||||
|
||||
bench("with direct setImmediate usage", function (done) {
|
||||
var counter = makeCounter(numberOfOps, done);
|
||||
|
||||
for (var i = 0; i < numberOfOps; ++i) {
|
||||
setImmediate(counter);
|
||||
}
|
||||
});
|
||||
});
|
||||
36
bin/node_modules/q/benchmark/scenarios.js
generated
vendored
Normal file
36
bin/node_modules/q/benchmark/scenarios.js
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
"use strict";
|
||||
|
||||
var Q = require("../q");
|
||||
|
||||
suite("Chaining", function () {
|
||||
var numberToChain = 1000;
|
||||
|
||||
bench("Chaining many already-fulfilled promises together", function (done) {
|
||||
var currentPromise = Q();
|
||||
for (var i = 0; i < numberToChain; ++i) {
|
||||
currentPromise = currentPromise.then(function () {
|
||||
return Q();
|
||||
});
|
||||
}
|
||||
|
||||
currentPromise.then(done);
|
||||
});
|
||||
|
||||
bench("Chaining and then fulfilling the end of the chain", function (done) {
|
||||
var deferred = Q.defer();
|
||||
|
||||
var currentPromise = deferred.promise;
|
||||
for (var i = 0; i < numberToChain; ++i) {
|
||||
(function () {
|
||||
var promiseToReturn = currentPromise;
|
||||
currentPromise = Q().then(function () {
|
||||
return promiseToReturn;
|
||||
});
|
||||
}());
|
||||
}
|
||||
|
||||
currentPromise.then(done);
|
||||
|
||||
deferred.resolve();
|
||||
});
|
||||
});
|
||||
93
bin/node_modules/q/package.json
generated
vendored
Normal file
93
bin/node_modules/q/package.json
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
1937
bin/node_modules/q/q.js
generated
vendored
Normal file
1937
bin/node_modules/q/q.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
35
bin/node_modules/q/queue.js
generated
vendored
Normal file
35
bin/node_modules/q/queue.js
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
|
||||
var Q = require("./q");
|
||||
|
||||
module.exports = Queue;
|
||||
function Queue() {
|
||||
var ends = Q.defer();
|
||||
var closed = Q.defer();
|
||||
return {
|
||||
put: function (value) {
|
||||
var next = Q.defer();
|
||||
ends.resolve({
|
||||
head: value,
|
||||
tail: next.promise
|
||||
});
|
||||
ends.resolve = next.resolve;
|
||||
},
|
||||
get: function () {
|
||||
var result = ends.promise.get("head");
|
||||
ends.promise = ends.promise.get("tail");
|
||||
return result.fail(function (error) {
|
||||
closed.resolve(error);
|
||||
throw error;
|
||||
});
|
||||
},
|
||||
closed: closed.promise,
|
||||
close: function (error) {
|
||||
error = error || new Error("Can't get value from closed queue");
|
||||
var end = {head: Q.reject(error)};
|
||||
end.tail = end;
|
||||
ends.resolve(end);
|
||||
return closed.promise;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
6
bin/node_modules/shelljs/.documentup.json
generated
vendored
Normal file
6
bin/node_modules/shelljs/.documentup.json
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "ShellJS",
|
||||
"twitter": [
|
||||
"r2r"
|
||||
]
|
||||
}
|
||||
7
bin/node_modules/shelljs/.jshintrc
generated
vendored
Normal file
7
bin/node_modules/shelljs/.jshintrc
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"loopfunc": true,
|
||||
"sub": true,
|
||||
"undef": true,
|
||||
"unused": true,
|
||||
"node": true
|
||||
}
|
||||
2
bin/node_modules/shelljs/.npmignore
generated
vendored
Normal file
2
bin/node_modules/shelljs/.npmignore
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
test/
|
||||
tmp/
|
||||
5
bin/node_modules/shelljs/.travis.yml
generated
vendored
Normal file
5
bin/node_modules/shelljs/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "0.8"
|
||||
- "0.10"
|
||||
- "0.11"
|
||||
26
bin/node_modules/shelljs/LICENSE
generated
vendored
Normal file
26
bin/node_modules/shelljs/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
Copyright (c) 2012, Artur Adib <aadib@mozilla.com>
|
||||
All rights reserved.
|
||||
|
||||
You may use this project under the terms of the New BSD license as follows:
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Artur Adib nor the
|
||||
names of the contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL ARTUR ADIB BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user