Compare commits
693 Commits
v1.1.0.rc1
...
v2.1.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
216b40439f | ||
|
|
590a9d9d41 | ||
|
|
66c8624022 | ||
|
|
75e5a5c308 | ||
|
|
9b5c20cc19 | ||
|
|
cc720e7f56 | ||
|
|
1426416666 | ||
|
|
197cb13817 | ||
|
|
816b7d701f | ||
|
|
da6813ef0d | ||
|
|
a4d134521a | ||
|
|
d4fc787ea7 | ||
|
|
663fbd0cdb | ||
|
|
cf83ae474c | ||
|
|
325c5a2288 | ||
|
|
3ca687a9ad | ||
|
|
3b557f85c7 | ||
|
|
b67a19507f | ||
|
|
ecae3d47a7 | ||
|
|
a76d6d1cd4 | ||
|
|
916dc03d9c | ||
|
|
2151a13705 | ||
|
|
6cc09e00d3 | ||
|
|
6d6c31328b | ||
|
|
c8cd2eabe5 | ||
|
|
f77071254a | ||
|
|
8880729250 | ||
|
|
9ad15eeaba | ||
|
|
10ca5f0246 | ||
|
|
a5cd2731b4 | ||
|
|
b12974db2e | ||
|
|
f4e5573ee3 | ||
|
|
0c77c6cfb5 | ||
|
|
cfc64a6f5c | ||
|
|
6ab70923b3 | ||
|
|
d9c0b10be4 | ||
|
|
a58fd20d82 | ||
|
|
eefa716530 | ||
|
|
66c364564e | ||
|
|
68ba5b6d48 | ||
|
|
15ae0379ec | ||
|
|
1fb0d2eefa | ||
|
|
ba0982d89f | ||
|
|
f703539942 | ||
|
|
62840f72a6 | ||
|
|
6d10f97151 | ||
|
|
15f3d0e9d7 | ||
|
|
b1344d5c73 | ||
|
|
59aaac026c | ||
|
|
21f62c697a | ||
|
|
dc93c33af6 | ||
|
|
4889583d5c | ||
|
|
41df058171 | ||
|
|
fa837ae90a | ||
|
|
c82c958e0d | ||
|
|
752e831b30 | ||
|
|
bd30065d66 | ||
|
|
84dff421ea | ||
|
|
709e032d1c | ||
|
|
1290d93b6a | ||
|
|
345903220c | ||
|
|
3332f93a24 | ||
|
|
3b19d66268 | ||
|
|
137c1a39f6 | ||
|
|
9402d59859 | ||
|
|
e8178d061b | ||
|
|
dd75394ea8 | ||
|
|
6b857d11ce | ||
|
|
eb48c83649 | ||
|
|
08a35d134d | ||
|
|
14824b5f9e | ||
|
|
9afae3d978 | ||
|
|
64a67ed320 | ||
|
|
dee1066652 | ||
|
|
d7ab9083be | ||
|
|
caee1508d1 | ||
|
|
3b8326f1e6 | ||
|
|
980509cd7b | ||
|
|
b984ff2fa6 | ||
|
|
61bf9ac7d7 | ||
|
|
5b397ff33e | ||
|
|
cd4d5c2445 | ||
|
|
5b6edff3fd | ||
|
|
cc3678f033 | ||
|
|
35f52bcb24 | ||
|
|
f8bccabf03 | ||
|
|
97867b2bf5 | ||
|
|
18eb6e2f36 | ||
|
|
51462f369b | ||
|
|
ea57ad97cf | ||
|
|
3132d98f23 | ||
|
|
b799f54bc9 | ||
|
|
3c051fc291 | ||
|
|
6b937da863 | ||
|
|
89232db2ee | ||
|
|
8b0d9c83bb | ||
|
|
60533ca868 | ||
|
|
048ab728ec | ||
|
|
488df899fb | ||
|
|
753f4b44b4 | ||
|
|
2c23d35b03 | ||
|
|
2b0be0c74b | ||
|
|
b4f49db6bd | ||
|
|
cee3cc56e6 | ||
|
|
f2346d357f | ||
|
|
ee09301d8d | ||
|
|
760b50d969 | ||
|
|
773b15e450 | ||
|
|
227698f5fa | ||
|
|
ff1fa6a893 | ||
|
|
ba1f8bc036 | ||
|
|
a5be51f912 | ||
|
|
d64ed6ebe9 | ||
|
|
062dc6b15a | ||
|
|
33641578e6 | ||
|
|
a1c109ea17 | ||
|
|
62212bbfa4 | ||
|
|
6a89d084f4 | ||
|
|
013c4f725f | ||
|
|
c064488192 | ||
|
|
f20df57607 | ||
|
|
48f7a5f17b | ||
|
|
f7ff47706c | ||
|
|
5f34be446c | ||
|
|
e1e49e8292 | ||
|
|
ae94dd1bfa | ||
|
|
eb1bd25445 | ||
|
|
aac6968ed8 | ||
|
|
1bad048c15 | ||
|
|
7d93541c09 | ||
|
|
29aad761d9 | ||
|
|
7d3de92cef | ||
|
|
13e0dd27c9 | ||
|
|
f0892a55aa | ||
|
|
fc6603e99f | ||
|
|
07cce0b1d1 | ||
|
|
6750559211 | ||
|
|
0419780682 | ||
|
|
6066c71966 | ||
|
|
0d4b04d37c | ||
|
|
7ad261837a | ||
|
|
00c8e37257 | ||
|
|
e53b487017 | ||
|
|
ed5cd6ba2c | ||
|
|
213a6023fd | ||
|
|
7d220fcd1b | ||
|
|
c1382c77b4 | ||
|
|
311263a3df | ||
|
|
33e4f5efbe | ||
|
|
367d3dcf66 | ||
|
|
21de44a204 | ||
|
|
c9e37a2a1c | ||
|
|
9e927af56e | ||
|
|
fc173e9a5e | ||
|
|
62a7f64659 | ||
|
|
3e739e4bc9 | ||
|
|
ba6f99423f | ||
|
|
3a5672cd33 | ||
|
|
af4cc76e2a | ||
|
|
1922514f2d | ||
|
|
668846147c | ||
|
|
76fafa0388 | ||
|
|
bed1c15ea4 | ||
|
|
6caf4c5de2 | ||
|
|
97ae9a2d88 | ||
|
|
71dbffeaef | ||
|
|
a3c3505086 | ||
|
|
a9e0112a9b | ||
|
|
a2ac5ef3b6 | ||
|
|
b200952195 | ||
|
|
9c6d03d3ac | ||
|
|
752a36d3ff | ||
|
|
52026fb0f7 | ||
|
|
e17a2cb1e0 | ||
|
|
ec5695acc1 | ||
|
|
47884032ad | ||
|
|
d7053612f5 | ||
|
|
9d1e92f5e2 | ||
|
|
eebba2ecca | ||
|
|
627a262085 | ||
|
|
305bd73142 | ||
|
|
fb853ad5b5 | ||
|
|
640f94a1bd | ||
|
|
5aac3e3292 | ||
|
|
84160ff51d | ||
|
|
e972bac80d | ||
|
|
455b6bade8 | ||
|
|
23c0e379e0 | ||
|
|
31d71ac22f | ||
|
|
095b02ad83 | ||
|
|
98c258a659 | ||
|
|
85fa148f18 | ||
|
|
76ca5ef6d4 | ||
|
|
46d2c43da1 | ||
|
|
b6c03a34e7 | ||
|
|
4ddf316388 | ||
|
|
a8cbef3123 | ||
|
|
a937d8d74f | ||
|
|
2fc2802809 | ||
|
|
7cf899a4ea | ||
|
|
83c0ea7f91 | ||
|
|
289c8313d1 | ||
|
|
b5775aec4f | ||
|
|
21b01f4a5d | ||
|
|
71faeea7b0 | ||
|
|
de7d005b3d | ||
|
|
7acf5d4220 | ||
|
|
2a8b5a30b6 | ||
|
|
9c7ba43ebd | ||
|
|
8ca08ff999 | ||
|
|
15aa3ecb5d | ||
|
|
2670bb40a7 | ||
|
|
c8ffa6000b | ||
|
|
06a553503d | ||
|
|
aab4808410 | ||
|
|
b525313cdb | ||
|
|
f576395620 | ||
|
|
b161e9e3df | ||
|
|
94ecb998bb | ||
|
|
38daa43c7e | ||
|
|
9fb9c12066 | ||
|
|
de2fb225b0 | ||
|
|
4f4ae086aa | ||
|
|
8510bdd947 | ||
|
|
66bd8c7825 | ||
|
|
a736e664ea | ||
|
|
812b14d000 | ||
|
|
a2a8b5dde2 | ||
|
|
78bed99ba3 | ||
|
|
b1d4ab09af | ||
|
|
3b52d015ea | ||
|
|
f9191d7b0d | ||
|
|
83a692d5a8 | ||
|
|
14a8c2ca09 | ||
|
|
b2e8de7bcd | ||
|
|
1d98a23b14 | ||
|
|
16ffd3b3fb | ||
|
|
6bc87ad223 | ||
|
|
555d328cf2 | ||
|
|
c78fba4b13 | ||
|
|
8a6d7828c6 | ||
|
|
c888b0c1b8 | ||
|
|
72e9851217 | ||
|
|
7ee5073921 | ||
|
|
614a18453e | ||
|
|
916f889c01 | ||
|
|
4a7b79ad0d | ||
|
|
775e2ff0a9 | ||
|
|
1b6725ec25 | ||
|
|
952eb59707 | ||
|
|
de6a305b44 | ||
|
|
8513201fa3 | ||
|
|
6e07dccb68 | ||
|
|
fcc50cc6f4 | ||
|
|
9e8466ba2b | ||
|
|
4350045d61 | ||
|
|
666e9c341e | ||
|
|
5830d9f86b | ||
|
|
ea888e4c03 | ||
|
|
c7e3ca6c8a | ||
|
|
06db4a8583 | ||
|
|
a2debf60b6 | ||
|
|
04c7db9259 | ||
|
|
8585ef69a5 | ||
|
|
cb5aea1fcf | ||
|
|
966f76b481 | ||
|
|
40e3020fdc | ||
|
|
69549a6ff3 | ||
|
|
a03fad8911 | ||
|
|
61993cf1fc | ||
|
|
cd9d5284cd | ||
|
|
e346e7dcc1 | ||
|
|
dd8a455f91 | ||
|
|
9e149d1e0f | ||
|
|
797984f173 | ||
|
|
29c5c127e5 | ||
|
|
26581b4c91 | ||
|
|
3186b24a66 | ||
|
|
81b822fea9 | ||
|
|
fb8bede8ea | ||
|
|
243ff80196 | ||
|
|
284bb0b608 | ||
|
|
6453ed656b | ||
|
|
a1a948b8df | ||
|
|
7a4876ecfa | ||
|
|
d9ece1f14f | ||
|
|
f1613ce77c | ||
|
|
a3424ea265 | ||
|
|
ab0b2b783c | ||
|
|
d0aff9ed02 | ||
|
|
a309117758 | ||
|
|
0c6e590a93 | ||
|
|
d06da150de | ||
|
|
39d7ebf28e | ||
|
|
5f429fcb37 | ||
|
|
b6eb9a4d5e | ||
|
|
fdb7df812c | ||
|
|
81299860aa | ||
|
|
ca6fa6f711 | ||
|
|
5aaafed4d8 | ||
|
|
c28c124f58 | ||
|
|
f0a1adb61c | ||
|
|
5ff2aecab8 | ||
|
|
8ca8197b4c | ||
|
|
55716723b5 | ||
|
|
3973cc5a71 | ||
|
|
95af58ade6 | ||
|
|
6641d64305 | ||
|
|
7c1fcd7bb5 | ||
|
|
e91d0341a4 | ||
|
|
144ff174f6 | ||
|
|
af4bfa8bc4 | ||
|
|
620e3f5992 | ||
|
|
ea76a30d85 | ||
|
|
adde1b4a5b | ||
|
|
07e7ad2314 | ||
|
|
706180ad01 | ||
|
|
547c9cfde9 | ||
|
|
d3ec12e62a | ||
|
|
749c15fe07 | ||
|
|
7e071547f5 | ||
|
|
6354ee17e5 | ||
|
|
255a50baee | ||
|
|
520a8c85a2 | ||
|
|
6de355544f | ||
|
|
95572fb314 | ||
|
|
18e1ab93ea | ||
|
|
0c4113e167 | ||
|
|
a563e67015 | ||
|
|
fab489851e | ||
|
|
1c19b8e38a | ||
|
|
fc258b3d36 | ||
|
|
ffa6138d75 | ||
|
|
51dd66a4cc | ||
|
|
37a3135d6a | ||
|
|
cb8ba74937 | ||
|
|
70fb0f0ed5 | ||
|
|
15889494c5 | ||
|
|
da33c7823e | ||
|
|
04e1d8420e | ||
|
|
19b2472761 | ||
|
|
1fc614ad19 | ||
|
|
84692f545c | ||
|
|
5017d1a4f1 | ||
|
|
963cd5e850 | ||
|
|
527394068e | ||
|
|
5e279a1393 | ||
|
|
8f0f0a607e | ||
|
|
4891d578e3 | ||
|
|
efc384c6d6 | ||
|
|
d60786a06c | ||
|
|
66010d01ec | ||
|
|
1619067ddd | ||
|
|
79a75f5bdb | ||
|
|
7158e048a6 | ||
|
|
f8f064d12d | ||
|
|
8ac085c103 | ||
|
|
03dfea967c | ||
|
|
f463e1f7aa | ||
|
|
4bff199c2a | ||
|
|
e3f0389ac2 | ||
|
|
be0f7b4117 | ||
|
|
edb46a6f7c | ||
|
|
a442acb8aa | ||
|
|
fc409f39a1 | ||
|
|
ba55cb5e38 | ||
|
|
2d4f398dd6 | ||
|
|
5ba6e51e1c | ||
|
|
ba43e37356 | ||
|
|
0f42f2709a | ||
|
|
4c4317b80e | ||
|
|
b4bb99dfdf | ||
|
|
d721418490 | ||
|
|
45fd8df861 | ||
|
|
0e800ee243 | ||
|
|
8a8cc03dea | ||
|
|
be0e6222c5 | ||
|
|
8c696ffc71 | ||
|
|
3dda67fe60 | ||
|
|
66d9b3d690 | ||
|
|
c350694c1b | ||
|
|
25d674f2c5 | ||
|
|
35bc200e31 | ||
|
|
9e886b3972 | ||
|
|
edd7e3932b | ||
|
|
0420e295f4 | ||
|
|
8d295a2612 | ||
|
|
d10b93cd28 | ||
|
|
358b9424b5 | ||
|
|
2571a6fbbb | ||
|
|
00f88edc04 | ||
|
|
98fa58ee49 | ||
|
|
984074ec95 | ||
|
|
6bb8a91301 | ||
|
|
97ce396008 | ||
|
|
051f3499ec | ||
|
|
8f5d0beb8c | ||
|
|
9609aba25f | ||
|
|
30aec66ce5 | ||
|
|
663a58d617 | ||
|
|
3847557bbc | ||
|
|
18c30566bd | ||
|
|
f2306729cd | ||
|
|
2165d71dc5 | ||
|
|
8c1881053c | ||
|
|
61a1f93488 | ||
|
|
d4f78922cd | ||
|
|
04ac41d911 | ||
|
|
75b9dc64af | ||
|
|
2d7fe0b6ce | ||
|
|
44feee57ac | ||
|
|
1394899c3c | ||
|
|
d0825a37a3 | ||
|
|
fc3d08bf40 | ||
|
|
990cc41f45 | ||
|
|
03ffe5ce6a | ||
|
|
1b0b4f22a0 | ||
|
|
a6953df28c | ||
|
|
5e71f3031e | ||
|
|
4ea4ed25ee | ||
|
|
39d40a1cad | ||
|
|
d40e0cebac | ||
|
|
89a54ea2bb | ||
|
|
bc9c857f43 | ||
|
|
24a7f55fa6 | ||
|
|
182cff4bd4 | ||
|
|
5dce5b1272 | ||
|
|
7c17b06856 | ||
|
|
6569176cc9 | ||
|
|
0f803430e4 | ||
|
|
821f13dff5 | ||
|
|
3e2d9baec2 | ||
|
|
f637c1f833 | ||
|
|
82b6904093 | ||
|
|
0daae4d7b4 | ||
|
|
f68657f14e | ||
|
|
c91df21a96 | ||
|
|
5b986c953c | ||
|
|
a932320d6c | ||
|
|
aabf8cec82 | ||
|
|
ccdcb293f4 | ||
|
|
ec7d58fce0 | ||
|
|
7f6b16ccf2 | ||
|
|
34b8bf5fb0 | ||
|
|
179e54b9fb | ||
|
|
09fe7b0540 | ||
|
|
264b1fea50 | ||
|
|
dcf7a0867e | ||
|
|
f5bc9faf63 | ||
|
|
2916a8a1ff | ||
|
|
8ac33ff6c2 | ||
|
|
661a884416 | ||
|
|
7acc6b327a | ||
|
|
e40e0c9170 | ||
|
|
7ae3fa9fef | ||
|
|
e73b9e7902 | ||
|
|
ffdf1eb16d | ||
|
|
d5f1264416 | ||
|
|
579fddc2d2 | ||
|
|
313e607135 | ||
|
|
b6599d52aa | ||
|
|
582ad6512a | ||
|
|
600be098af | ||
|
|
b87eb240b3 | ||
|
|
7055d95584 | ||
|
|
1c87060804 | ||
|
|
b4acdbd90a | ||
|
|
fbb9f53524 | ||
|
|
0ac497db6b | ||
|
|
9e31201f1a | ||
|
|
d53002c63a | ||
|
|
3271dc8838 | ||
|
|
475aacbfbb | ||
|
|
8303c79f26 | ||
|
|
5700ace2c9 | ||
|
|
aca43bd3a3 | ||
|
|
7516bba2b0 | ||
|
|
4f19d34ad7 | ||
|
|
c40b64a24c | ||
|
|
baad5ff01f | ||
|
|
bf2adf55eb | ||
|
|
dd8d3f9788 | ||
|
|
9c4467bac0 | ||
|
|
c017257164 | ||
|
|
2445fb36dc | ||
|
|
eec6d7d23e | ||
|
|
3110da62e5 | ||
|
|
d41b281eb1 | ||
|
|
6feb124853 | ||
|
|
3be247ceb1 | ||
|
|
edc2bfae93 | ||
|
|
01b2fc612c | ||
|
|
d8f6aac2cd | ||
|
|
e7a930a5b3 | ||
|
|
6b2d8da55f | ||
|
|
538b32e401 | ||
|
|
e6e8908f49 | ||
|
|
86dafd5d2d | ||
|
|
aa60d5f00d | ||
|
|
079e6e1e08 | ||
|
|
7706512525 | ||
|
|
e09fd40933 | ||
|
|
6eecc562ff | ||
|
|
cf7bb0269b | ||
|
|
b22bf9a031 | ||
|
|
b7af6abca5 | ||
|
|
d6da13a8dd | ||
|
|
dc4563d45c | ||
|
|
92492c0144 | ||
|
|
d6987a6c84 | ||
|
|
43c8fdd33f | ||
|
|
98ae076f0c | ||
|
|
2c06e36b9b | ||
|
|
5a744884fe | ||
|
|
e6888b840d | ||
|
|
e682d18387 | ||
|
|
10b09ea9f5 | ||
|
|
c53b36a9b2 | ||
|
|
af71f4d2f9 | ||
|
|
83227f2163 | ||
|
|
f865758124 | ||
|
|
3fc79bac9e | ||
|
|
05977203a6 | ||
|
|
5bea864e1c | ||
|
|
a9eaa66da5 | ||
|
|
30bf565e69 | ||
|
|
668dd784ef | ||
|
|
4ad43267ab | ||
|
|
be6b87a31b | ||
|
|
43552494ee | ||
|
|
98c99c4ebb | ||
|
|
4318de4647 | ||
|
|
a526ebf261 | ||
|
|
c2e1327f39 | ||
|
|
234f2a1585 | ||
|
|
c584f182ab | ||
|
|
74f928fd54 | ||
|
|
a1011e7748 | ||
|
|
8b02bf731b | ||
|
|
779dee1211 | ||
|
|
1f5e790c41 | ||
|
|
cd3a0c854b | ||
|
|
f9cbad1512 | ||
|
|
f840458b34 | ||
|
|
34bd1969e7 | ||
|
|
dfed37531e | ||
|
|
08f5a8c98f | ||
|
|
8d94d0bfc5 | ||
|
|
3e5da57cf9 | ||
|
|
e2af08e0a6 | ||
|
|
b6c3999c3a | ||
|
|
6785d1a05c | ||
|
|
e74f09df9c | ||
|
|
f7c9aaa996 | ||
|
|
86994b25db | ||
|
|
9a7c76ea23 | ||
|
|
e3a013ae99 | ||
|
|
ead9aa6d5a | ||
|
|
d9467317a8 | ||
|
|
63ad879c12 | ||
|
|
b95c43ab7c | ||
|
|
3685d3199c | ||
|
|
a34077a8af | ||
|
|
ac55e26870 | ||
|
|
acdc497361 | ||
|
|
b527ccd2fa | ||
|
|
cfa95fcf2c | ||
|
|
ae9ddd74a2 | ||
|
|
26f0f6f213 | ||
|
|
c5ba032d28 | ||
|
|
bbc4c70c91 | ||
|
|
c5c57247f8 | ||
|
|
9990eb7b6e | ||
|
|
b5b50182b2 | ||
|
|
4d106c2b33 | ||
|
|
5e594946bb | ||
|
|
6ac4b686a3 | ||
|
|
fd91433792 | ||
|
|
1f9004eaa3 | ||
|
|
58e6747930 | ||
|
|
4c083856be | ||
|
|
b94522193c | ||
|
|
867de62699 | ||
|
|
74cdc5a04f | ||
|
|
ddbee65aa8 | ||
|
|
beeb872a82 | ||
|
|
dbcb0b7983 | ||
|
|
c8436d1d44 | ||
|
|
639f757f6f | ||
|
|
d65bdc7e59 | ||
|
|
a1ed56741b | ||
|
|
7473b455dc | ||
|
|
b6fb23b069 | ||
|
|
386e83b53f | ||
|
|
f2b25f1780 | ||
|
|
5ca2888301 | ||
|
|
147cb36760 | ||
|
|
107463ad57 | ||
|
|
39a55d8f10 | ||
|
|
4b48dc1069 | ||
|
|
921f52862f | ||
|
|
ea2ffb7b01 | ||
|
|
54fbc48eb2 | ||
|
|
06c900ab20 | ||
|
|
3e070e9db6 | ||
|
|
7e04571ec0 | ||
|
|
ddd48f2c88 | ||
|
|
1c2e50d244 | ||
|
|
d2d60a798d | ||
|
|
442f3bf872 | ||
|
|
f910df00bb | ||
|
|
500b856cfa | ||
|
|
dad4865fbf | ||
|
|
1771ec3c63 | ||
|
|
2385acedd8 | ||
|
|
4c28bef387 | ||
|
|
7bbcf51d45 | ||
|
|
b6f96bc121 | ||
|
|
feebfbba68 | ||
|
|
8e4bd86865 | ||
|
|
4f218f7d6a | ||
|
|
bb1a4428db | ||
|
|
079740ca2c | ||
|
|
fbbccf6ef7 | ||
|
|
7ad75c13d4 | ||
|
|
d46ca4f506 | ||
|
|
ee7af4496c | ||
|
|
e22c4492a5 | ||
|
|
d63836afb4 | ||
|
|
06f1edc197 | ||
|
|
3a6b233a2e | ||
|
|
d15964b7dc | ||
|
|
6e22754c10 | ||
|
|
bab4538404 | ||
|
|
06d191af74 | ||
|
|
ad78d0d0d8 | ||
|
|
733a6a4ae4 | ||
|
|
3e0cad41f5 | ||
|
|
885832e920 | ||
|
|
3a0ada034b | ||
|
|
674197aef8 | ||
|
|
626da5a112 | ||
|
|
a3ccd8b0d3 | ||
|
|
4a1a2123a3 | ||
|
|
c87cf71f4f | ||
|
|
e4c557faae | ||
|
|
6559c5b43a | ||
|
|
912397120b | ||
|
|
551464b8d2 | ||
|
|
8a298e5c0e | ||
|
|
94a153ed15 | ||
|
|
b4439f74d5 | ||
|
|
d70e733f70 | ||
|
|
ac096f9911 | ||
|
|
08d72926ff | ||
|
|
67ec0af254 | ||
|
|
4f2fcff15a | ||
|
|
7158fc2426 | ||
|
|
992367dcbc | ||
|
|
ce886e20e4 | ||
|
|
86b0c80cc9 | ||
|
|
7dff84b1dc | ||
|
|
8c22b26d9c | ||
|
|
ad4f48dcd4 | ||
|
|
de9e2abad5 | ||
|
|
41f496001f | ||
|
|
6b5956724b | ||
|
|
ec24992250 | ||
|
|
83f232237d | ||
|
|
98d32bb4a4 | ||
|
|
c4f27ae377 | ||
|
|
a075c75bce | ||
|
|
a617b59e6a | ||
|
|
917b37481e | ||
|
|
67bbc98faa | ||
|
|
620f7b6e4c | ||
|
|
b722f416c7 | ||
|
|
634a7dc402 | ||
|
|
a4522e4dce | ||
|
|
e113c338d0 | ||
|
|
b81f690a25 | ||
|
|
c06e189699 | ||
|
|
67b6cfb828 | ||
|
|
57e622fb2a | ||
|
|
c0664dd6aa | ||
|
|
b640ce6fc0 | ||
|
|
e9af7834f5 | ||
|
|
0d43ae9c38 | ||
|
|
3775919c92 | ||
|
|
a692ff8c95 | ||
|
|
dbcabd397e | ||
|
|
a8b0a0ee4f | ||
|
|
60a5d60f42 |
13
.gitignore
vendored
13
.gitignore
vendored
@@ -5,7 +5,20 @@ site/
|
||||
.bundle/
|
||||
.pairs
|
||||
.rvmrc
|
||||
.ruby-gemset
|
||||
.ruby-version
|
||||
*.gem
|
||||
.bundle
|
||||
tags
|
||||
Gemfile.lock
|
||||
pkg/*
|
||||
.sass-cache/*
|
||||
src/html/.sass-cache/*
|
||||
node_modules/
|
||||
*.pyc
|
||||
sauce_connect.log
|
||||
*.swp
|
||||
build/
|
||||
*.egg-info/
|
||||
dist/*.tar.gz
|
||||
nbproject/
|
||||
|
||||
2
.gitmodules
vendored
2
.gitmodules
vendored
@@ -1,3 +1,3 @@
|
||||
[submodule "pages"]
|
||||
path = pages
|
||||
url = git@github.com:pivotal/jasmine.git
|
||||
url = https://github.com/pivotal/jasmine.git
|
||||
|
||||
9
.jshintrc
Normal file
9
.jshintrc
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"bitwise": true,
|
||||
"curly": true,
|
||||
"immed": true,
|
||||
"newcap": true,
|
||||
"trailing": true,
|
||||
"loopfunc": true,
|
||||
"quotmark": "single"
|
||||
}
|
||||
21
.npmignore
Normal file
21
.npmignore
Normal file
@@ -0,0 +1,21 @@
|
||||
dist/
|
||||
grunt/
|
||||
node_modules
|
||||
release_notes/
|
||||
spec/
|
||||
src/
|
||||
Gemfile
|
||||
Gemfile.lock
|
||||
Rakefile
|
||||
jasmine-core.gemspec
|
||||
.rspec
|
||||
.travis.yml
|
||||
.jshintrc
|
||||
.gitignore
|
||||
*.sh
|
||||
Gruntfile.js
|
||||
lib/jasmine-core.rb
|
||||
lib/jasmine-core/boot/
|
||||
lib/jasmine-core/spec
|
||||
lib/jasmine-core/version.rb
|
||||
lib/jasmine-core/*.py
|
||||
51
.travis.yml
Normal file
51
.travis.yml
Normal file
@@ -0,0 +1,51 @@
|
||||
---
|
||||
script: $TEST_COMMAND
|
||||
language: ruby
|
||||
cache: bundler
|
||||
rvm: 1.9.3
|
||||
env:
|
||||
global:
|
||||
- USE_SAUCE=true
|
||||
- NOKOGIRI_USE_SYSTEM_LIBRARIES=true
|
||||
- TEST_COMMAND="bash travis-core-script.sh"
|
||||
- JASMINE_BROWSER="firefox"
|
||||
- SAUCE_OS="Linux"
|
||||
- SAUCE_BROWSER_VERSION=''
|
||||
- secure: WSPWhlnC4mWSnSPquX+m1/BCu5ch5NygkaHuM2Nea7lD8oS3XLX8QncZZAsQ4lnNfqoDDuBOizG0AESiqNvE4y6x5qvLLTS6q+ce255ZEMZ71TBdZgDEEvGMEjOPPsVXiXyTQOP1lwOPlrbZvaPgWV7e11KIBab6DfFcQpnvDgo=
|
||||
- secure: SW7CJhZnwaNT749Gdnhvqb5rbXlAOsygUAzh9qhtyvbqXKkmJdBIEsO01YF6pbju1X2twE9JvWCOxeZju43NgQChJlPsGbjY2j3k/TdQeTAJesQe2K7ytwghunI30gjEovtRH0T3w1EmcKPH8yj5eBIcB2OYoJHx8KEC7e68q1g=
|
||||
matrix:
|
||||
include:
|
||||
- env:
|
||||
- USE_SAUCE=false
|
||||
- TEST_COMMAND="bash travis-node-script.sh"
|
||||
- env:
|
||||
- JASMINE_BROWSER="safari"
|
||||
- SAUCE_OS="OS X 10.8"
|
||||
- SAUCE_BROWSER_VERSION=6
|
||||
- env:
|
||||
- JASMINE_BROWSER="safari"
|
||||
- SAUCE_OS="OS X 10.6"
|
||||
- SAUCE_BROWSER_VERSION=5
|
||||
- env:
|
||||
- JASMINE_BROWSER="internet explorer"
|
||||
- SAUCE_OS="Windows 8"
|
||||
- SAUCE_BROWSER_VERSION=10
|
||||
- env:
|
||||
- JASMINE_BROWSER="internet explorer"
|
||||
- SAUCE_OS="Windows 7"
|
||||
- SAUCE_BROWSER_VERSION=9
|
||||
- env:
|
||||
- JASMINE_BROWSER="internet explorer"
|
||||
- SAUCE_OS="Windows 7"
|
||||
- SAUCE_BROWSER_VERSION=8
|
||||
- env:
|
||||
- JASMINE_BROWSER="chrome"
|
||||
- SAUCE_OS="Linux"
|
||||
- SAUCE_BROWSER_VERSION=''
|
||||
- env:
|
||||
- JASMINE_BROWSER="phantomjs"
|
||||
- USE_SAUCE=false
|
||||
- env:
|
||||
- USE_SAUCE=false
|
||||
- JASMINE_BROWSER="phantomjs"
|
||||
- TEST_COMMAND="bash travis-docs-script.sh"
|
||||
121
CONTRIBUTING.md
Normal file
121
CONTRIBUTING.md
Normal file
@@ -0,0 +1,121 @@
|
||||
# Developing for Jasmine Core
|
||||
|
||||
We welcome your contributions - Thanks for helping make Jasmine a better project for everyone. Please review the backlog and discussion lists (the main group - [http://groups.google.com/group/jasmine-js](http://groups.google.com/group/jasmine-js) and the developer's list - [http://groups.google.com/group/jasmine-js-dev](http://groups.google.com/group/jasmine-js-dev)) before starting work - what you're looking for may already have been done. If it hasn't, the community can help make your contribution better.
|
||||
|
||||
## General Workflow
|
||||
|
||||
Please submit pull requests via feature branches using the semi-standard workflow of:
|
||||
|
||||
1. Fork it
|
||||
1. Clone your fork: (`git clone git@github.com:yourUserName/jasmine.git`)
|
||||
1. Change directory: (`cd jasmine`)
|
||||
1. Asign original repository to a remote named 'upstream': (`git remote add
|
||||
upstream https://github.com/pivotal/jasmine.git`)
|
||||
1. Pull in changes not present in your local repository: (`git fetch upstream`)
|
||||
1. Create your feature branch (`git checkout -b my-new-feature`)
|
||||
1. Commit your changes (`git commit -am 'Add some feature'`)
|
||||
1. Push to the branch (`git push origin my-new-feature`)
|
||||
1. Create new Pull Request
|
||||
|
||||
We favor pull requests with very small, single commits with a single purpose.
|
||||
|
||||
## Background
|
||||
|
||||
### Directory Structure
|
||||
|
||||
* `/src` contains all of the source files
|
||||
* `/src/console` - Node.js-specific files
|
||||
* `/src/core` - generic source files
|
||||
* `/src/html` - browser-specific files
|
||||
* `/spec` contains all of the tests
|
||||
* mirrors the source directory
|
||||
* there are some additional files
|
||||
* `/dist` contains the standalone distributions as zip files
|
||||
* `/lib` contains the generated files for distribution as the Jasmine Rubygem and the Python package
|
||||
|
||||
### Self-testing
|
||||
|
||||
Note that Jasmine tests itself. The files in `lib` are loaded first, defining the reference `jasmine`. Then the files in `src` are loaded, defining the reference `j$`. So there are two copies of the code loaded under test.
|
||||
|
||||
The tests should always use `j$` to refer to the objects and functions that are being tested. But the tests can use functions on `jasmine` as needed. _Be careful how you structure any new test code_. Copy the patterns you see in the existing code - this ensures that the code you're testing is not leaking into the `jasmine` reference and vice-versa.
|
||||
|
||||
### `boot.js`
|
||||
|
||||
__This is new for Jasmine 2.0.__
|
||||
|
||||
This file does all of the setup necessary for Jasmine to work. It loads all of the code, creates an `Env`, attaches the global functions, and builds the reporter. It also sets up the execution of the `Env` - for browsers this is in `window.onload`. While the default in `lib` is appropriate for browsers, projects may wish to customize this file.
|
||||
|
||||
For example, for Jasmine development there is a different `dev_boot.js` for Jasmine development that does more work.
|
||||
|
||||
### Compatibility
|
||||
|
||||
* Browser Minimum
|
||||
* IE8
|
||||
* Firefox 3.x
|
||||
* Chrome ??
|
||||
* Safari 5
|
||||
|
||||
## Development
|
||||
|
||||
All source code belongs in `src/`. The `core/` directory contains the bulk of Jasmine's functionality. This code should remain browser- and environment-agnostic. If your feature or fix cannot be, as mentioned above, please degrade gracefully. Any code that should only be in a non-browser environment should live in `src/console/`. Any code that depends on a browser (specifically, it expects `window` to be the global or `document` is present) should live in `src/html/`.
|
||||
|
||||
### Install Dependencies
|
||||
|
||||
Jasmine Core relies on Ruby and Node.js.
|
||||
|
||||
To install the Ruby dependencies, you will need Ruby, Rubygems, and Bundler available. Then:
|
||||
|
||||
$ bundle
|
||||
|
||||
...will install all of the Ruby dependencies.
|
||||
|
||||
To install the Node dependencies, you will need Node.js, Npm, and [Grunt](http://gruntjs.com/), the [grunt-cli](https://github.com/gruntjs/grunt-cli) and ensure that `grunt` is on your path.
|
||||
|
||||
$ npm install --local
|
||||
|
||||
...will install all of the node modules locally. If when you run
|
||||
|
||||
$ grunt
|
||||
|
||||
...you see that JSHint runs your system is ready.
|
||||
|
||||
### How to write new Jasmine code
|
||||
|
||||
Or, How to make a successful pull request
|
||||
|
||||
* _Do not change the public interface_. Lots of projects depend on Jasmine and if you aren't careful you'll break them
|
||||
* _Be environment agnostic_ - server-side developers are just as important as browser developers
|
||||
* _Be browser agnostic_ - if you must rely on browser-specific functionality, please write it in a way that degrades gracefully
|
||||
* _Write specs_ - Jasmine's a testing framework; don't add functionality without test-driving it
|
||||
* _Write code in the style of the rest of the repo_ - Jasmine should look like a cohesive whole
|
||||
* _Ensure the *entire* test suite is green_ in all the big browsers, Node, and JSHint - your contribution shouldn't break Jasmine for other users
|
||||
|
||||
Follow these tips and your pull request, patch, or suggestion is much more likely to be integrated.
|
||||
|
||||
### Running Specs
|
||||
|
||||
Jasmine uses the [Jasmine Ruby gem](http://github.com/pivotal/jasmine-gem) to test itself in browser.
|
||||
|
||||
$ rake jasmine
|
||||
|
||||
...and then visit `http://localhost:8888` to run specs.
|
||||
|
||||
Jasmine uses the [Jasmine NPM package](http://github.com/pivotal/jasmine-npm) to test itself in a Node.js/npm environment.
|
||||
|
||||
$ grunt execSpecsInNode
|
||||
|
||||
...and then the results will print to the console. All specs run except those that expect a browser (the specs in `spec/html` are ignored).
|
||||
|
||||
## Before Committing or Submitting a Pull Request
|
||||
|
||||
1. Ensure all specs are green in browser *and* node
|
||||
1. Ensure JSHint is green with `grunt jshint`
|
||||
1. Build `jasmine.js` with `grunt buildDistribution` and run all specs again - this ensures that your changes self-test well
|
||||
|
||||
## Submitting a Pull Request
|
||||
1. Revert your changes to `jasmine.js` and `jasmine-html.js`
|
||||
* We do this because `jasmine.js` and `jasmine-html.js` are auto-generated (as you've seen in the previous steps) and accepting multiple pull requests when this auto-generated file changes causes lots of headaches.
|
||||
1. When we accept your pull request, we will generate these files as a separate commit and merge the entire branch into master.
|
||||
|
||||
Note that we use Travis for Continuous Integration. We only accept green pull requests.
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
# Developing for Jasmine Core
|
||||
|
||||
This repo is for the core code of Jasmine - `jasmine.js`. This implements the basic spec-defining, -executing, and -results-reporting logic.
|
||||
|
||||
## How to write new Jasmine code
|
||||
|
||||
* _Do not change the public interface_. Lots of projects depend on Jasmine and if you aren't careful you'll break them
|
||||
* _Be environment agnostic_ - server-side developers are just as important as browser developers
|
||||
* _Be browser agnostic_ - if you must rely on browser-specific functionality, please write it in a way that degrades gracefully
|
||||
* _Write specs_ - Jasmine's a testing framework; don't add functionality without test-driving it
|
||||
|
||||
Follow these tips and your pull request, patch, or suggestion is much more likely to be integrated.
|
||||
|
||||
## Environment
|
||||
|
||||
Ruby, RubyGems and Rake are used in order to script the various file interactions. You will need to run on a system that supports Ruby in order to run Jasmine's specs.
|
||||
|
||||
Node.js is used to run most of the specs (the HTML-independent code) and should be present. Additionally, the JS Hint project scrubs the source code as part of the spec process.
|
||||
|
||||
## Development
|
||||
|
||||
All source code belongs in `src/`. The `core/` directory contains the bulk of Jasmine's functionality. This code should remain browser- and environment-agnostic. If your feature or fix cannot be, as mentioned above, please degrade gracefully. Any code that should only be in a non-browser environment should live in `src/console/`. Any code that depends on a browser (specifically, it expects `window` to be the global or `document` is present) should live in `src/html/`.
|
||||
|
||||
Please respect the code patterns as possible. For example, using `jasmine.getGlobal()` to get the global object so as to remain environment agnostic.
|
||||
|
||||
## Running Specs
|
||||
|
||||
As in all good projects, the `spec/` directory mirrors `src/` and follows the same rules. The browser runner will include and attempt to run all specs. The node runner will exclude any html-dependent specs (those in `spec/html/`).
|
||||
|
||||
You will notice that all specs are run against the built `jasmine.js` instead of the component source files. This is intentional as a way to ensure that the concatenation code is working correctly.
|
||||
|
||||
Please ensure all specs are green before committing.
|
||||
|
||||
There are rake tasks to help with getting green:
|
||||
* `rake spec` outputs the expected number of specs that should be run and attempts to run in browser and Node
|
||||
* `rake spec:browser` opens `spec/runner.html` in the default browser on MacOS. Please run this in at least Firefox and Chrome before committing
|
||||
* `rake spec:node` runs all the Jasmine specs in Node.js - it will complain if Node is not installed
|
||||
* `rake hint` runs all the files through JSHint and will complain about potential viable issues with your code. Fix them.
|
||||
|
||||
64
GOALS_2.0.md
Normal file
64
GOALS_2.0.md
Normal file
@@ -0,0 +1,64 @@
|
||||
# (Vague) Jasmine 2.0 Goals/(Guidelines)
|
||||
|
||||
1. No globals!
|
||||
* jasmine library is entirely inside `jasmine` namespace
|
||||
* globals required for backwards compatibility should be added in `boot.js` (EG, var describe = jasmine.getCurrentEnv().describe lives in boot.js)
|
||||
1. Don't use properties as getters. Use methods.
|
||||
* Properties aren't encapsulated -- can be mutated, unsafe.
|
||||
1. Reporters get data objects (no methods).
|
||||
* easier to refactor as needed
|
||||
1. More unit tests - fewer nasty integration tests
|
||||
|
||||
## Remaining non-story-able work:
|
||||
* Make a `TODO` list
|
||||
|
||||
### Hard
|
||||
* Finish killing Globals
|
||||
* Guidelines:
|
||||
* New objects can have constructors on `jasmine`
|
||||
* Top level functions can live on `jasmine`
|
||||
* Top level (i.e., any `jasmine` property) should only be referenced inside the `Env` constructor
|
||||
* should better allow any object to get jasmine code (Node-friendly)
|
||||
* review everything in base.js
|
||||
* Remove isA functions:
|
||||
* isArray_ - used in matchers and spies
|
||||
* isString_
|
||||
* isDOMNode_
|
||||
* isA_
|
||||
* unimplementedMethod_, used by PrettyPrinter
|
||||
* jasmine.util should be util closure inside of env or something
|
||||
* argsToArray is used for Spies and matching (and can be replaced)
|
||||
* inherit is only for PrettyPrinter now
|
||||
* formatException is used only inside Env/spec
|
||||
* htmlEscape is for messages in matchers - should this be HTML at all?
|
||||
* Pretty printing
|
||||
* move away from pretty printer and to a JSON.stringify implementation?
|
||||
* jasmineToString vs. custom toString ?
|
||||
|
||||
### Easy
|
||||
|
||||
* unify params to ctors: options vs. attrs.
|
||||
* This will be a lot of the TODOs, but clean up & simplify Env.js (is this a 2.1 task?)
|
||||
|
||||
### DONE
|
||||
* Matchers improvements
|
||||
* unit testable DONE
|
||||
* better equality (from Underscore) DONE
|
||||
* addCustomMatchers doesn't explode stack DONE
|
||||
* refactor equals function so that it just loops & recurses over a list of fns (custom and built-in) - 2.1? (Tracker story)
|
||||
* Spies
|
||||
* break these out into their own tests/file DONE
|
||||
|
||||
|
||||
## Other Topics
|
||||
|
||||
* Docs
|
||||
* Docco has gone over well. Should we annotate all the sources and then have Pages be more complex, having tutorials and annotated source like Backbone? Are we small enough?
|
||||
* Need examples for:
|
||||
* How to build a Custom Matcher
|
||||
* How to add a custom equality tester
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
10
Gemfile
10
Gemfile
@@ -1,3 +1,9 @@
|
||||
source :rubygems
|
||||
gem "term-ansicolor", :require => "term/ansicolor"
|
||||
source 'https://rubygems.org'
|
||||
gem "jasmine", :git => 'https://github.com/pivotal/jasmine-gem.git'
|
||||
# gem "jasmine", path: "../jasmine-gem"
|
||||
|
||||
gemspec
|
||||
|
||||
gem "jasmine_selenium_runner", :github => 'jasmine/jasmine_selenium_runner'
|
||||
|
||||
gem "anchorman"
|
||||
|
||||
62
Gruntfile.js
Normal file
62
Gruntfile.js
Normal file
@@ -0,0 +1,62 @@
|
||||
module.exports = function(grunt) {
|
||||
var pkg = require("./package.json");
|
||||
global.jasmineVersion = pkg.version;
|
||||
|
||||
grunt.initConfig({
|
||||
pkg: pkg,
|
||||
jshint: require('./grunt/config/jshint.js'),
|
||||
concat: require('./grunt/config/concat.js'),
|
||||
compass: require('./grunt/config/compass.js'),
|
||||
compress: require('./grunt/config/compress.js')
|
||||
});
|
||||
|
||||
require('load-grunt-tasks')(grunt);
|
||||
|
||||
grunt.loadTasks('grunt/tasks');
|
||||
|
||||
grunt.registerTask('default', ['jshint:all']);
|
||||
|
||||
var version = require('./grunt/tasks/version.js');
|
||||
var standaloneBuilder = require('./grunt/tasks/build_standalone.js');
|
||||
|
||||
grunt.registerTask('build:copyVersionToGem',
|
||||
"Propagates the version from package.json to version.rb",
|
||||
version.copyToGem);
|
||||
|
||||
grunt.registerTask('buildDistribution',
|
||||
'Builds and lints jasmine.js, jasmine-html.js, jasmine.css',
|
||||
[
|
||||
'compass',
|
||||
'jshint:beforeConcat',
|
||||
'concat',
|
||||
'jshint:afterConcat',
|
||||
'build:copyVersionToGem'
|
||||
]
|
||||
);
|
||||
|
||||
grunt.registerTask("execSpecsInNode",
|
||||
"Run Jasmine core specs in Node.js",
|
||||
function() {
|
||||
var done = this.async(),
|
||||
Jasmine = require('jasmine'),
|
||||
jasmineCore = require('./lib/jasmine-core.js'),
|
||||
jasmine = new Jasmine({jasmineCore: jasmineCore});
|
||||
|
||||
jasmine.loadConfigFile('./spec/support/jasmine.json');
|
||||
jasmine.configureDefaultReporter({
|
||||
onComplete: function(passed) {
|
||||
done(passed);
|
||||
}
|
||||
});
|
||||
|
||||
jasmine.execute();
|
||||
}
|
||||
);
|
||||
|
||||
grunt.registerTask("execSpecsInNode:performance",
|
||||
"Run Jasmine performance specs in Node.js",
|
||||
function() {
|
||||
require("shelljs").exec("node_modules/.bin/jasmine JASMINE_CONFIG_PATH=spec/support/jasmine-performance.json");
|
||||
}
|
||||
);
|
||||
};
|
||||
5
MANIFEST.in
Normal file
5
MANIFEST.in
Normal file
@@ -0,0 +1,5 @@
|
||||
recursive-include . *.py
|
||||
include lib/jasmine-core/*.js
|
||||
include lib/jasmine-core/*.css
|
||||
include images/*.png
|
||||
include package.json
|
||||
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2008-2011 Pivotal Labs
|
||||
Copyright (c) 2008-2014 Pivotal Labs
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
<a name="README">[Jasmine](http://pivotal.github.com/jasmine/)</a>
|
||||
=======
|
||||
**A JavaScript Testing Framework**
|
||||
|
||||
Jasmine is a Behavior Driven Development testing framework for JavaScript. It does not rely on browsers, DOM, or any JavaScript framework. Thus it's suited for websites, [Node.js](http://nodejs.org) projects, or anywhere that JavaScript can run.
|
||||
|
||||
Documentation & guides live here: [http://pivotal.github.com/jasmine/](http://pivotal.github.com/jasmine/)
|
||||
|
||||
## Support
|
||||
|
||||
* Search past discussions: [http://groups.google.com/group/jasmine-js](http://groups.google.com/group/jasmine-js)
|
||||
* Send an email to the list: [jasmine-js@googlegroups.com](jasmine-js@googlegroups.com)
|
||||
* Check the current build status: [ci.pivotallabs.com](http://ci.pivotallabs.com)
|
||||
* View the project backlog at Pivotal Tracker: [http://www.pivotaltracker.com/projects/10606](http://www.pivotaltracker.com/projects/10606)
|
||||
* Follow us on Twitter: [@JasmineBDD](http://twitter.com/JasmineBDD)
|
||||
|
||||
## How to Contribute
|
||||
|
||||
We welcome your contributions - Thanks for helping make Jasmine a better project for everyone. Please review the backlog and discussion lists (the main group - [http://groups.google.com/group/jasmine-js](http://groups.google.com/group/jasmine-js) and the developer's list - [http://groups.google.com/group/jasmine-js-dev](http://groups.google.com/group/jasmine-js-dev)) before starting work - what you're looking for may already have been done. If it hasn't, the community can help make your contribution better.
|
||||
|
||||
### Development Environment
|
||||
|
||||
Jasmine Core relies on Ruby for executing the test suite and building the project for release. The spec suite runs in any major, modern browser (Firefox, Safari, Chrome, and yes various IE's) and in [Node.js](http://nodejs.org). While you probably have browsers installed, you want to make sure that Ruby and Node are present.
|
||||
|
||||
### How to Develop for Jasmine Core
|
||||
|
||||
* Write specs
|
||||
* Make them pass in a browser (or three):
|
||||
* open `spec/runner.html` in your browsers
|
||||
* `rake spec:browser` will run in the default browser on MacOS
|
||||
* Make them pass in Node: `rake spec:node`
|
||||
* Fix any warnings or errors from JSHint: `rake jasmine:lint`
|
||||
|
||||
Running `rake spec` will run the browser tests, then run specs in Node, then run JSHint. But this will only run in the default browser and only on MacOS (for now).
|
||||
|
||||
|
||||
### Making a Successful Pull Request
|
||||
|
||||
* __Include specs for your work__ - it helps us understand your intent and makes sure that future development doesn't break your work
|
||||
* __Ensure the full test suite is green__ in all the big browsers, Node, and JSHint - your contribution shouldn't break Jasmine for other users
|
||||
|
||||
Do these things and we'll take a look.
|
||||
|
||||
## Maintainers
|
||||
|
||||
* [Davis W. Frank](mailto:dwfrank@pivotallabs.com), Pivotal Labs
|
||||
* [Rajan Agaskar](mailto:rajan@pivotallabs.com), Pivotal Labs
|
||||
* [Christian Williams](mailto:antixian666@gmail.com), Square
|
||||
|
||||
Copyright (c) 2008-2011 Pivotal Labs. This software is licensed under the MIT License.
|
||||
65
README.md
Normal file
65
README.md
Normal file
@@ -0,0 +1,65 @@
|
||||
<a name="README">[<img src="https://rawgithub.com/pivotal/jasmine/master/images/jasmine-horizontal.svg" width="400px" />](http://jasmine.github.io)</a>
|
||||
|
||||
[](https://travis-ci.org/pivotal/jasmine) [](https://codeclimate.com/github/pivotal/jasmine)
|
||||
|
||||
=======
|
||||
|
||||
**A JavaScript Testing Framework**
|
||||
|
||||
Jasmine is a Behavior Driven Development testing framework for JavaScript. It does not rely on browsers, DOM, or any JavaScript framework. Thus it's suited for websites, [Node.js](http://nodejs.org) projects, or anywhere that JavaScript can run.
|
||||
|
||||
Documentation & guides live here: [http://jasmine.github.io](http://jasmine.github.io/)
|
||||
For a quick start guide of Jasmine 2.0, see the beginning of [http://jasmine.github.io/2.0/introduction.html](http://jasmine.github.io/2.0/introduction.html)
|
||||
|
||||
Upgrading from Jasmine 1.x? Check out the [2.0 release notes](https://github.com/pivotal/jasmine/blob/v2.0.0/release_notes/20.md) for a list of what's new (including breaking interface changes).
|
||||
|
||||
## Contributing
|
||||
|
||||
Please read the [contributors' guide](https://github.com/pivotal/jasmine/blob/master/CONTRIBUTING.md)
|
||||
|
||||
## Installation
|
||||
|
||||
To install Jasmine on your local box:
|
||||
|
||||
* Clone Jasmine - `git clone https://github.com/pivotal/jasmine.git`
|
||||
* Create a Jasmine directory in your project - `mkdir my-project/jasmine`
|
||||
* Move latest dist to your project directory - `mv jasmine/dist/jasmine-standalone-2.0.0.zip my-project/jasmine`
|
||||
* Change directory - `cd my-project/jasmine`
|
||||
* Unzip the dist - `unzip jasmine-standalone-2.0.0.zip`
|
||||
|
||||
Add the following to your HTML file:
|
||||
|
||||
<link rel="shortcut icon" type="image/png" href="jasmine/lib/jasmine-2.0.0/jasmine_favicon.png">
|
||||
<link rel="stylesheet" type="text/css" href="jasmine/lib/jasmine-2.0.0/jasmine.css">
|
||||
|
||||
<script type="text/javascript" src="jasmine/lib/jasmine-2.0.0/jasmine.js"></script>
|
||||
<script type="text/javascript" src="jasmine/lib/jasmine-2.0.0/jasmine-html.js"></script>
|
||||
<script type="text/javascript" src="jasmine/lib/jasmine-2.0.0/boot.js"></script>
|
||||
|
||||
For the Jasmine Ruby Gem:<br>
|
||||
[https://github.com/pivotal/jasmine-gem](https://github.com/pivotal/jasmine-gem)
|
||||
|
||||
For the Jasmine Python Egg:<br>
|
||||
[https://github.com/pivotal/jasmine-py](https://github.com/pivotal/jasmine-py)
|
||||
|
||||
|
||||
|
||||
## Support
|
||||
|
||||
* Search past discussions: [http://groups.google.com/group/jasmine-js](http://groups.google.com/group/jasmine-js)
|
||||
* Send an email to the list: [jasmine-js@googlegroups.com](mailto:jasmine-js@googlegroups.com)
|
||||
* View the project backlog at Pivotal Tracker: [http://www.pivotaltracker.com/projects/10606](http://www.pivotaltracker.com/projects/10606)
|
||||
* Follow us on Twitter: [@JasmineBDD](http://twitter.com/JasmineBDD)
|
||||
|
||||
## Maintainers
|
||||
|
||||
* [Davis W. Frank](mailto:dwfrank@pivotal.io), Pivotal Labs
|
||||
* [Rajan Agaskar](mailto:rajan@pivotal.io), Pivotal Labs
|
||||
* [Gregg Van Hove](mailto:ghove@pivotal.io), Pivotal Labs
|
||||
|
||||
### Maintainers Emeritus
|
||||
|
||||
* [Christian Williams](mailto:antixian666@gmail.com), Cloud Foundry
|
||||
* Sheel Choksi
|
||||
|
||||
Copyright (c) 2008-2014 Pivotal Labs. This software is licensed under the MIT License.
|
||||
70
RELEASE.md
Normal file
70
RELEASE.md
Normal file
@@ -0,0 +1,70 @@
|
||||
# How to work on a Jasmine Release
|
||||
|
||||
## Development
|
||||
___Jasmine Core Maintainers Only___
|
||||
|
||||
Follow the instructions in `CONTRIBUTING.md` during development.
|
||||
|
||||
### Git Rules
|
||||
|
||||
Please work on feature branches.
|
||||
|
||||
Please attempt to keep commits to `master` small, but cohesive. If a feature is contained in a bunch of small commits (e.g., it has several wip commits or small work), please squash them when merging back to `master`.
|
||||
|
||||
### Version
|
||||
|
||||
We attempt to stick to [Semantic Versioning](http://semver.org/). Most of the time, development should be against a new minor version - fixing bugs and adding new features that are backwards compatible.
|
||||
|
||||
The current version lives in the file `/package.json`. This file should be set to the version that is _currently_ under development. That is, if version 1.0.0 is the current release then version should be incremented say, to 1.1.0.
|
||||
|
||||
This version is used by both `jasmine.js` and the `jasmine-core` Ruby gem.
|
||||
|
||||
Note that Jasmine should *not* use the "patch" version number. Let downstream projects rev their patch versions as needed, keeping their major and minor version numbers in sync with Jasmine core.
|
||||
|
||||
## Release
|
||||
|
||||
When ready to release - specs are all green and the stories are done:
|
||||
|
||||
1. Update the release notes in `release_notes` - use the Anchorman gem to generate the markdown file and edit accordingly
|
||||
1. Update the version in `package.json` to a release candidate
|
||||
1. Update any links or top-level landing page for the Github Pages
|
||||
|
||||
### Build standalone distribution
|
||||
|
||||
1. Build the standalone distribution with `grunt buildStandaloneDist`
|
||||
1. Make sure you add the new ZIP file to git
|
||||
1. Should we still do this? Given we want to use github releases...
|
||||
|
||||
### Release the Python egg
|
||||
|
||||
1. `python setup.py register sdist upload` You will need pypi credentials to upload the egg.
|
||||
|
||||
### Release the Ruby gem
|
||||
|
||||
1. Copy version to the Ruby gem with `grunt build:copyVersionToGem`
|
||||
1. __NOTE__: You will likely need to point to a local jasmine gem in order to run tests locally. _Do not_ push this version of the Gemfile.
|
||||
1. __NOTE__: You will likely need to push a new jasmine gem with a dependent version right after this release.
|
||||
1. Push these changes to GitHub and verify that this SHA is green
|
||||
1. `rake release` - tags the repo with the version, builds the `jasmine-core` gem, pushes the gem to Rubygems.org. In order to release you will have to ensure you have rubygems creds locally.
|
||||
|
||||
### Release the NPM
|
||||
|
||||
1. `npm adduser` to save your credentials locally
|
||||
1. `npm publish .` to publish what's in `package.json`
|
||||
|
||||
### Release the docs
|
||||
|
||||
Probably only need to do this when releasing a minor version, and not a patch version.
|
||||
|
||||
1. `cp edge ${version}` to copy the current edge docs to the new version
|
||||
1. Add a link to the new version in `index.html`
|
||||
|
||||
### Finally
|
||||
|
||||
1. Visit the [Releases page for Jasmine](https://github.com/pivotal/jasmine/releases), find the tag just pushed.
|
||||
1. Paste in a link to the correct release notes for this release. The link should reference the blob and tag correctly, and the markdown file for the notes.
|
||||
1. If it is a pre-release, mark it as such.
|
||||
1. Attach the standalone zipfile
|
||||
|
||||
|
||||
There should be a post to Pivotal Labs blog and a tweet to that link.
|
||||
33
Rakefile
33
Rakefile
@@ -1,29 +1,18 @@
|
||||
require "bundler"
|
||||
Bundler::GemHelper.install_tasks
|
||||
require "term/ansicolor"
|
||||
require "json"
|
||||
require "tilt"
|
||||
require "jasmine"
|
||||
unless ENV["JASMINE_BROWSER"] == 'phantomjs'
|
||||
require "jasmine_selenium_runner"
|
||||
end
|
||||
load "jasmine/tasks/jasmine.rake"
|
||||
|
||||
Dir["#{File.dirname(__FILE__)}/tasks/**/*.rb"].each do |file|
|
||||
require file
|
||||
namespace :jasmine do
|
||||
task :set_env do
|
||||
ENV['JASMINE_CONFIG_PATH'] ||= 'spec/support/jasmine.yml'
|
||||
end
|
||||
end
|
||||
|
||||
task :default => :spec
|
||||
task "jasmine:configure" => "jasmine:set_env"
|
||||
|
||||
task :require_pages_submodule do
|
||||
raise "Submodule for Github Pages isn't present. Run git submodule update --init" unless File.exist?('pages/download.html')
|
||||
end
|
||||
|
||||
task :require_node do
|
||||
raise "\nNode.js is required to develop code for Jasmine. Please visit http://nodejs.org to install.\n\n" unless node_installed?
|
||||
end
|
||||
|
||||
def node_installed?
|
||||
`which node` =~ /node/
|
||||
end
|
||||
|
||||
class String
|
||||
include Term::ANSIColor
|
||||
end
|
||||
|
||||
Term::ANSIColor.coloring = STDOUT.isatty
|
||||
task :default => "jasmine:ci"
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
## Release
|
||||
__Jasmine Core Maintainers Only__
|
||||
|
||||
The current version lives in the file `src/version.json`. We attempt to stick to Semantic Versioning
|
||||
|
||||
## The Github Pages
|
||||
|
||||
Github pages have to exist in a branch called gh-pages in order for their app to serve them. This repo adds that branch as a submodule under the `pages` directory. This is a bit of a hack, but it allows us to work with the pages and the source at the same time and with one set of rake tasks.
|
||||
|
||||
If you want to submit changes to this repo and aren't a Pivotal Labs employee, you can fork and work in the gh-pages branch. You won't be able to edit the pages in the submodule off of master.
|
||||
|
||||
The pages are built with [Frank](https://github.com/blahed/frank). All the source for these pages live in the pages_source directory.
|
||||
BIN
dist/jasmine-standalone-1.0.0.zip
vendored
Normal file
BIN
dist/jasmine-standalone-1.0.0.zip
vendored
Normal file
Binary file not shown.
BIN
dist/jasmine-standalone-1.1.0.zip
vendored
Normal file
BIN
dist/jasmine-standalone-1.1.0.zip
vendored
Normal file
Binary file not shown.
BIN
dist/jasmine-standalone-1.2.0.zip
vendored
Normal file
BIN
dist/jasmine-standalone-1.2.0.zip
vendored
Normal file
Binary file not shown.
BIN
dist/jasmine-standalone-1.3.0.zip
vendored
Normal file
BIN
dist/jasmine-standalone-1.3.0.zip
vendored
Normal file
Binary file not shown.
BIN
dist/jasmine-standalone-1.3.1.zip
vendored
Normal file
BIN
dist/jasmine-standalone-1.3.1.zip
vendored
Normal file
Binary file not shown.
BIN
dist/jasmine-standalone-2.0.0.zip
vendored
Normal file
BIN
dist/jasmine-standalone-2.0.0.zip
vendored
Normal file
Binary file not shown.
BIN
dist/jasmine-standalone-2.0.1.zip
vendored
Normal file
BIN
dist/jasmine-standalone-2.0.1.zip
vendored
Normal file
Binary file not shown.
BIN
dist/jasmine-standalone-2.0.2.zip
vendored
Normal file
BIN
dist/jasmine-standalone-2.0.2.zip
vendored
Normal file
Binary file not shown.
BIN
dist/jasmine-standalone-2.0.3.zip
vendored
Normal file
BIN
dist/jasmine-standalone-2.0.3.zip
vendored
Normal file
Binary file not shown.
BIN
dist/jasmine-standalone-2.1.0.zip
vendored
Normal file
BIN
dist/jasmine-standalone-2.1.0.zip
vendored
Normal file
Binary file not shown.
10
grunt/config/compass.js
Normal file
10
grunt/config/compass.js
Normal file
@@ -0,0 +1,10 @@
|
||||
module.exports = {
|
||||
jasmine: {
|
||||
options: {
|
||||
cssDir: 'lib/jasmine-core/',
|
||||
sassDir: 'src/html',
|
||||
outputStyle: 'compact',
|
||||
noLineComments: true,
|
||||
}
|
||||
}
|
||||
};
|
||||
66
grunt/config/compress.js
Normal file
66
grunt/config/compress.js
Normal file
@@ -0,0 +1,66 @@
|
||||
var standaloneLibDir = "lib/jasmine-" + jasmineVersion;
|
||||
|
||||
function root(path) { return "./" + path; }
|
||||
function libJasmineCore(path) { return root("lib/jasmine-core/" + path); }
|
||||
function libConsole() { return "lib/console/" }
|
||||
function dist(path) { return root("dist/" + path); }
|
||||
|
||||
module.exports = {
|
||||
standalone: {
|
||||
options: {
|
||||
archive: root("dist/jasmine-standalone-" + global.jasmineVersion + ".zip")
|
||||
},
|
||||
|
||||
files: [
|
||||
{ src: [ root("MIT.LICENSE") ] },
|
||||
{
|
||||
src: [ "jasmine_favicon.png"],
|
||||
dest: standaloneLibDir,
|
||||
expand: true,
|
||||
cwd: root("images")
|
||||
},
|
||||
{
|
||||
src: [
|
||||
"jasmine.js",
|
||||
"jasmine-html.js",
|
||||
"jasmine.css"
|
||||
],
|
||||
dest: standaloneLibDir,
|
||||
expand: true,
|
||||
cwd: libJasmineCore("")
|
||||
},
|
||||
{
|
||||
src: [
|
||||
"console.js"
|
||||
],
|
||||
dest: standaloneLibDir,
|
||||
expand: true,
|
||||
cwd: libConsole()
|
||||
},
|
||||
{
|
||||
src: [ "boot.js" ],
|
||||
dest: standaloneLibDir,
|
||||
expand: true,
|
||||
cwd: libJasmineCore("boot")
|
||||
},
|
||||
{
|
||||
src: [ "SpecRunner.html" ],
|
||||
dest: root(""),
|
||||
expand: true,
|
||||
cwd: dist("tmp")
|
||||
},
|
||||
{
|
||||
src: [ "*.js" ],
|
||||
dest: "src",
|
||||
expand: true,
|
||||
cwd: libJasmineCore("example/src/")
|
||||
},
|
||||
{
|
||||
src: [ "*.js" ],
|
||||
dest: "spec",
|
||||
expand: true,
|
||||
cwd: libJasmineCore("example/spec/")
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
61
grunt/config/concat.js
Normal file
61
grunt/config/concat.js
Normal file
@@ -0,0 +1,61 @@
|
||||
var grunt = require('grunt');
|
||||
|
||||
function license() {
|
||||
var currentYear = "" + new Date(Date.now()).getFullYear();
|
||||
|
||||
return grunt.template.process(
|
||||
grunt.file.read("grunt/templates/licenseBanner.js.jst"),
|
||||
{ data: { currentYear: currentYear}});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
'jasmine-html': {
|
||||
src: [
|
||||
'src/html/requireHtml.js',
|
||||
'src/html/HtmlReporter.js',
|
||||
'src/html/HtmlSpecFilter.js',
|
||||
'src/html/ResultsNode.js',
|
||||
'src/html/QueryString.js'
|
||||
],
|
||||
dest: 'lib/jasmine-core/jasmine-html.js'
|
||||
},
|
||||
jasmine: {
|
||||
src: [
|
||||
'src/core/requireCore.js',
|
||||
'src/core/matchers/requireMatchers.js',
|
||||
'src/core/base.js',
|
||||
'src/core/util.js',
|
||||
'src/core/Spec.js',
|
||||
'src/core/Env.js',
|
||||
'src/core/JsApiReporter.js',
|
||||
'src/core/PrettyPrinter',
|
||||
'src/core/Suite',
|
||||
'src/core/**/*.js',
|
||||
'src/version.js'
|
||||
],
|
||||
dest: 'lib/jasmine-core/jasmine.js'
|
||||
},
|
||||
boot: {
|
||||
src: ['lib/jasmine-core/boot/boot.js'],
|
||||
dest: 'lib/jasmine-core/boot.js'
|
||||
},
|
||||
nodeBoot: {
|
||||
src: ['lib/jasmine-core/boot/node_boot.js'],
|
||||
dest: 'lib/jasmine-core/node_boot.js'
|
||||
},
|
||||
console: {
|
||||
src: [
|
||||
'src/console/requireConsole.js',
|
||||
'src/console/ConsoleReporter.js'
|
||||
],
|
||||
dest: 'lib/console/console.js'
|
||||
},
|
||||
options: {
|
||||
banner: license(),
|
||||
process: {
|
||||
data: {
|
||||
version: global.jasmineVersion
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
11
grunt/config/jshint.js
Normal file
11
grunt/config/jshint.js
Normal file
@@ -0,0 +1,11 @@
|
||||
module.exports = {
|
||||
beforeConcat: ['src/**/*.js'],
|
||||
afterConcat: [
|
||||
'lib/jasmine-core/jasmine-html.js',
|
||||
'lib/jasmine-core/jasmine.js'
|
||||
],
|
||||
options: {
|
||||
jshintrc: '.jshintrc'
|
||||
},
|
||||
all: ['src/**/*.js']
|
||||
};
|
||||
31
grunt/tasks/build_standalone.js
Normal file
31
grunt/tasks/build_standalone.js
Normal file
@@ -0,0 +1,31 @@
|
||||
var grunt = require("grunt");
|
||||
|
||||
function standaloneTmpDir(path) { return "dist/tmp/" + path; }
|
||||
|
||||
grunt.registerTask("build:compileSpecRunner",
|
||||
"Processes the spec runner template and writes to a tmp file",
|
||||
function() {
|
||||
var runnerHtml = grunt.template.process(
|
||||
grunt.file.read("grunt/templates/SpecRunner.html.jst"),
|
||||
{ data: { jasmineVersion: global.jasmineVersion }});
|
||||
|
||||
grunt.file.write(standaloneTmpDir("SpecRunner.html"), runnerHtml);
|
||||
}
|
||||
);
|
||||
|
||||
grunt.registerTask("build:cleanSpecRunner",
|
||||
"Deletes the tmp spec runner file",
|
||||
function() {
|
||||
grunt.file.delete(standaloneTmpDir(""));
|
||||
}
|
||||
);
|
||||
|
||||
grunt.registerTask("buildStandaloneDist",
|
||||
"Builds a standalone distribution",
|
||||
[
|
||||
"buildDistribution",
|
||||
"build:compileSpecRunner",
|
||||
"compress:standalone",
|
||||
"build:cleanSpecRunner"
|
||||
]
|
||||
);
|
||||
14
grunt/tasks/version.js
Normal file
14
grunt/tasks/version.js
Normal file
@@ -0,0 +1,14 @@
|
||||
var grunt = require("grunt");
|
||||
|
||||
function gemLib(path) { return './lib/jasmine-core/' + path; }
|
||||
function nodeToRuby(version) { return version.replace('-', '.'); }
|
||||
|
||||
module.exports = {
|
||||
copyToGem: function() {
|
||||
var versionRb = grunt.template.process(
|
||||
grunt.file.read("grunt/templates/version.rb.jst"),
|
||||
{ data: { jasmineVersion: nodeToRuby(global.jasmineVersion) }});
|
||||
|
||||
grunt.file.write(gemLib("version.rb"), versionRb);
|
||||
}
|
||||
};
|
||||
26
grunt/templates/SpecRunner.html.jst
Normal file
26
grunt/templates/SpecRunner.html.jst
Normal file
@@ -0,0 +1,26 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Jasmine Spec Runner v<%= jasmineVersion %></title>
|
||||
|
||||
<link rel="shortcut icon" type="image/png" href="lib/jasmine-<%= jasmineVersion %>/jasmine_favicon.png">
|
||||
<link rel="stylesheet" href="lib/jasmine-<%= jasmineVersion %>/jasmine.css">
|
||||
|
||||
<script src="lib/jasmine-<%= jasmineVersion %>/jasmine.js"></script>
|
||||
<script src="lib/jasmine-<%= jasmineVersion %>/jasmine-html.js"></script>
|
||||
<script src="lib/jasmine-<%= jasmineVersion %>/boot.js"></script>
|
||||
|
||||
<!-- include source files here... -->
|
||||
<script src="src/Player.js"></script>
|
||||
<script src="src/Song.js"></script>
|
||||
|
||||
<!-- include spec files here... -->
|
||||
<script src="spec/SpecHelper.js"></script>
|
||||
<script src="spec/PlayerSpec.js"></script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
22
grunt/templates/licenseBanner.js.jst
Normal file
22
grunt/templates/licenseBanner.js.jst
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
Copyright (c) 2008-<%= currentYear %> Pivotal Labs
|
||||
|
||||
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.
|
||||
*/
|
||||
9
grunt/templates/version.rb.jst
Normal file
9
grunt/templates/version.rb.jst
Normal file
@@ -0,0 +1,9 @@
|
||||
#
|
||||
# DO NOT Edit this file. Canonical version of Jasmine lives in the repo's package.json. This file is generated
|
||||
# by a grunt task when the standalone release is built.
|
||||
#
|
||||
module Jasmine
|
||||
module Core
|
||||
VERSION = "<%= jasmineVersion %>"
|
||||
end
|
||||
end
|
||||
BIN
images/jasmine-horizontal.png
Normal file
BIN
images/jasmine-horizontal.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
102
images/jasmine-horizontal.svg
Normal file
102
images/jasmine-horizontal.svg
Normal file
@@ -0,0 +1,102 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
width="681.96252"
|
||||
height="187.5"
|
||||
id="svg2"
|
||||
xml:space="preserve"><metadata
|
||||
id="metadata8"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs6"><clipPath
|
||||
id="clipPath18"><path
|
||||
d="M 0,1500 0,0 l 5455.74,0 0,1500 L 0,1500 z"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path20" /></clipPath></defs><g
|
||||
transform="matrix(1.25,0,0,-1.25,0,187.5)"
|
||||
id="g10"><g
|
||||
transform="scale(0.1,0.1)"
|
||||
id="g12"><g
|
||||
id="g14"><g
|
||||
clip-path="url(#clipPath18)"
|
||||
id="g16"><path
|
||||
d="m 1544,599.434 c 0.92,-40.352 25.68,-81.602 71.53,-81.602 27.51,0 47.68,12.832 61.44,35.754 12.83,22.93 12.83,56.852 12.83,82.527 l 0,329.184 -71.52,0 0,104.543 266.83,0 0,-104.543 -70.6,0 0,-344.77 c 0,-58.691 -3.68,-104.531 -44.93,-152.218 -36.68,-42.18 -96.28,-66.02 -153.14,-66.02 -117.37,0 -207.24,77.941 -202.64,197.145 l 130.2,0"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path22"
|
||||
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
|
||||
d="m 2301.4,662.695 c 0,80.703 -66.94,145.813 -147.63,145.813 -83.44,0 -147.63,-68.781 -147.63,-151.301 0,-79.785 66.94,-145.801 145.8,-145.801 84.35,0 149.46,67.852 149.46,151.289 z m -1.83,-181.547 c -35.77,-54.097 -93.53,-78.859 -157.72,-78.859 -140.3,0 -251.24,116.449 -251.24,254.918 0,142.129 113.7,260.41 256.74,260.41 63.27,0 118.29,-29.336 152.22,-82.523 l 0,69.687 175.14,0 0,-104.527 -61.44,0 0,-280.598 61.44,0 0,-104.527 -175.14,0 0,66.019"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path24"
|
||||
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
|
||||
d="m 2622.33,557.258 c 3.67,-44.016 33.01,-73.348 78.86,-73.348 33.93,0 66.93,23.824 66.93,60.504 0,48.606 -45.84,56.856 -83.44,66.941 -85.28,22.004 -178.81,48.606 -178.81,155.879 0,93.536 78.86,147.633 165.98,147.633 44,0 83.43,-9.176 110.94,-44.008 l 0,33.922 82.53,0 0,-132.965 -108.21,0 c -1.83,34.856 -28.42,57.774 -63.26,57.774 -30.26,0 -62.35,-17.422 -62.35,-51.348 0,-45.847 44.93,-55.93 80.69,-64.18 88.02,-20.175 182.47,-47.695 182.47,-157.734 0,-99.027 -83.44,-154.039 -175.13,-154.039 -49.53,0 -94.46,15.582 -126.55,53.18 l 0,-40.34 -85.27,0 0,142.129 114.62,0"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path26"
|
||||
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
|
||||
d="m 2988.18,800.254 -63.26,0 0,104.527 165.05,0 0,-73.355 c 31.18,51.347 78.86,85.277 141.21,85.277 67.85,0 124.71,-41.258 152.21,-102.699 26.6,62.351 92.62,102.699 160.47,102.699 53.19,0 105.46,-22 141.21,-62.351 38.52,-44.938 38.52,-93.532 38.52,-149.457 l 0,-185.239 63.27,0 0,-104.527 -238.42,0 0,104.527 63.28,0 0,157.715 c 0,32.102 0,60.527 -14.67,88.957 -18.34,26.582 -48.61,40.344 -79.77,40.344 -30.26,0 -63.28,-12.844 -82.53,-36.672 -22.93,-29.355 -22.93,-56.863 -22.93,-92.629 l 0,-157.715 63.27,0 0,-104.527 -238.41,0 0,104.527 63.28,0 0,150.383 c 0,29.348 0,66.023 -14.67,91.699 -15.59,29.336 -47.69,44.934 -80.7,44.934 -31.18,0 -57.77,-11.008 -77.94,-35.774 -24.77,-30.253 -26.6,-62.343 -26.6,-99.941 l 0,-151.301 63.27,0 0,-104.527 -238.4,0 0,104.527 63.26,0 0,280.598"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path28"
|
||||
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
|
||||
d="m 3998.66,951.547 -111.87,0 0,118.293 111.87,0 0,-118.293 z m 0,-431.891 63.27,0 0,-104.527 -239.33,0 0,104.527 64.19,0 0,280.598 -63.27,0 0,104.527 175.14,0 0,-385.125"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path30"
|
||||
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
|
||||
d="m 4159.12,800.254 -63.27,0 0,104.527 175.14,0 0,-69.687 c 29.35,54.101 84.36,80.699 144.87,80.699 53.19,0 105.45,-22.016 141.22,-60.527 40.34,-44.934 41.26,-88.032 41.26,-143.957 l 0,-191.653 63.27,0 0,-104.527 -238.4,0 0,104.527 63.26,0 0,158.637 c 0,30.262 0,61.434 -19.26,88.035 -20.17,26.582 -53.18,39.414 -86.19,39.414 -33.93,0 -68.77,-13.75 -88.94,-41.25 -21.09,-27.5 -21.09,-69.687 -21.09,-102.707 l 0,-142.129 63.26,0 0,-104.527 -238.4,0 0,104.527 63.27,0 0,280.598"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path32"
|
||||
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
|
||||
d="m 5082.48,703.965 c -19.24,70.605 -81.6,115.547 -154.04,115.547 -66.04,0 -129.3,-51.348 -143.05,-115.547 l 297.09,0 z m 85.27,-144.883 c -38.51,-93.523 -129.27,-156.793 -231.05,-156.793 -143.07,0 -257.68,111.871 -257.68,255.836 0,144.883 109.12,261.328 254.91,261.328 67.87,0 135.72,-30.258 183.39,-78.863 48.62,-51.344 68.79,-113.695 68.79,-183.383 l -3.67,-39.434 -396.13,0 c 14.67,-67.863 77.03,-117.363 146.72,-117.363 48.59,0 90.76,18.328 118.28,58.672 l 116.44,0"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path34"
|
||||
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
|
||||
d="m 690.895,850.703 90.75,0 22.543,31.035 0,243.122 -135.829,0 0,-243.141 22.536,-31.016"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path36"
|
||||
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
|
||||
d="m 632.395,742.258 28.039,86.304 -22.551,31.04 -231.223,75.128 -41.976,-129.183 231.257,-75.137 36.454,11.848"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path38"
|
||||
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
|
||||
d="m 717.449,653.105 -73.41,53.36 -36.488,-11.875 -142.903,-196.692 109.883,-79.828 142.918,196.703 0,38.332"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path40"
|
||||
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
|
||||
d="m 828.52,706.465 -73.426,-53.34 0.011,-38.359 L 898.004,418.07 1007.9,497.898 864.973,694.609 828.52,706.465"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path42"
|
||||
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
|
||||
d="m 812.086,828.586 28.055,-86.32 36.484,-11.836 231.225,75.117 -41.97,129.183 -231.239,-75.14 -22.555,-31.004"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path44"
|
||||
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
|
||||
d="m 736.301,1335.88 c -323.047,0 -585.875,-262.78 -585.875,-585.782 0,-323.118 262.828,-585.977 585.875,-585.977 323.019,0 585.809,262.859 585.809,585.977 0,323.002 -262.79,585.782 -585.809,585.782 l 0,0 z m 0,-118.61 c 257.972,0 467.189,-209.13 467.189,-467.172 0,-258.129 -209.217,-467.348 -467.189,-467.348 -258.074,0 -467.254,209.219 -467.254,467.348 0,258.042 209.18,467.172 467.254,467.172"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path46"
|
||||
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
|
||||
d="m 1091.13,619.883 -175.771,57.121 11.629,35.808 175.762,-57.121 -11.62,-35.808"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path48"
|
||||
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
|
||||
d="M 866.957,902.074 836.5,924.199 945.121,1073.73 975.586,1051.61 866.957,902.074"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path50"
|
||||
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
|
||||
d="M 607.465,903.445 498.855,1052.97 529.32,1075.1 637.93,925.566 607.465,903.445"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path52"
|
||||
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
|
||||
d="m 380.688,622.129 -11.626,35.801 175.758,57.09 11.621,-35.801 -175.753,-57.09"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path54"
|
||||
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
|
||||
d="m 716.289,376.59 37.6406,0 0,184.816 -37.6406,0 0,-184.816 z"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path56"
|
||||
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /></g></g></g></g></svg>
|
||||
|
After Width: | Height: | Size: 8.6 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 905 B After Width: | Height: | Size: 1.5 KiB |
@@ -6,18 +6,18 @@ Gem::Specification.new do |s|
|
||||
s.name = "jasmine-core"
|
||||
s.version = Jasmine::Core::VERSION
|
||||
s.platform = Gem::Platform::RUBY
|
||||
s.authors = ["Rajan Agaskar", "Davis Frank", "Christian Williams"]
|
||||
s.authors = ["Rajan Agaskar", "Davis W. Frank", "Gregg Van Hove"]
|
||||
s.summary = %q{JavaScript BDD framework}
|
||||
s.description = %q{Test your JavaScript without any framework dependencies, in any environment, and with a nice descriptive syntax.}
|
||||
s.email = %q{jasmine-js@googlegroups.com}
|
||||
s.homepage = "http://pivotal.github.com/jasmine"
|
||||
s.rubyforge_project = "jasmine-core"
|
||||
s.license = "MIT"
|
||||
|
||||
s.files = Dir.glob("./lib/**/*")
|
||||
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
||||
s.files = Dir.glob("./lib/**/*") + Dir.glob("./lib/jasmine-core/spec/**/*.js")
|
||||
s.require_paths = ["lib"]
|
||||
s.add_development_dependency "term-ansicolor"
|
||||
s.add_development_dependency "json_pure", ">= 1.4.3"
|
||||
s.add_development_dependency "frank"
|
||||
s.add_development_dependency "ragaskar-jsdoc_helper"
|
||||
s.add_development_dependency "rake"
|
||||
s.add_development_dependency "sauce-connect"
|
||||
s.add_development_dependency "compass"
|
||||
s.add_development_dependency "jasmine_selenium_runner", ">= 0.2.0"
|
||||
end
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
<div align="center">{+new Link().toFile("index.html").withText("Class Index")+}
|
||||
| {+new Link().toFile("files.html").withText("File Index")+}</div>
|
||||
<hr />
|
||||
<h2>Classes</h2>
|
||||
<ul class="classList">
|
||||
<for each="thisClass" in="data">
|
||||
<li>{!
|
||||
if (thisClass.alias == "_global_") {
|
||||
output += "<i>"+new Link().toClass(thisClass.alias)+"</i>";
|
||||
}
|
||||
else {
|
||||
output += new Link().toClass(thisClass.alias);
|
||||
}
|
||||
!}</li>
|
||||
</for>
|
||||
</ul>
|
||||
<hr />
|
||||
@@ -1,56 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset={+IO.encoding+}"" />
|
||||
{! Link.base = ""; /* all generated links will be relative to this */ !}
|
||||
<title>JsDoc Reference - File Index</title>
|
||||
<meta name="generator" content="JsDoc Toolkit" />
|
||||
|
||||
<style type="text/css">
|
||||
{+include("static/default.css")+}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
{+include("static/header.html")+}
|
||||
|
||||
<div id="index">
|
||||
{+publish.classesIndex+}
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
<h1 class="classTitle">File Index</h1>
|
||||
|
||||
<for each="item" in="data">
|
||||
<div>
|
||||
<h2>{+new Link().toSrc(item.alias).withText(item.name)+}</h2>
|
||||
<if test="item.desc">{+resolveLinks(summarize(item.desc))+}</if>
|
||||
<dl>
|
||||
<if test="item.author">
|
||||
<dt class="heading">Author:</dt>
|
||||
<dd>{+item.author+}</dd>
|
||||
</if>
|
||||
<if test="item.version">
|
||||
<dt class="heading">Version:</dt>
|
||||
<dd>{+item.version+}</dd>
|
||||
</if>
|
||||
{! var locations = item.comment.getTag('location').map(function($){return $.toString().replace(/(^\$ ?| ?\$$)/g, '').replace(/^HeadURL: https:/g, 'http:');}) !}
|
||||
<if test="locations.length">
|
||||
<dt class="heading">Location:</dt>
|
||||
<for each="location" in="locations">
|
||||
<dd><a href="{+location+}">{+location+}</a></dd>
|
||||
</for>
|
||||
</if>
|
||||
</dl>
|
||||
</div>
|
||||
<hr />
|
||||
</for>
|
||||
|
||||
</div>
|
||||
<div class="fineprint" style="clear:both">
|
||||
<if test="JSDOC.opt.D.copyright">©{+JSDOC.opt.D.copyright+}<br /></if>
|
||||
Documentation generated by <a href="http://www.jsdoctoolkit.org/" target="_blankt">JsDoc Toolkit</a> {+JSDOC.VERSION+} on {+new Date()+}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,646 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset={+IO.encoding+}" />
|
||||
<meta name="generator" content="JsDoc Toolkit" />
|
||||
{! Link.base = "../"; /* all generated links will be relative to this */ !}
|
||||
<title>JsDoc Reference - {+data.alias+}</title>
|
||||
|
||||
<style type="text/css">
|
||||
{+include("static/default.css")+}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- ============================== header ================================= -->
|
||||
<!-- begin static/header.html -->
|
||||
{+include("static/header.html")+}
|
||||
<!-- end static/header.html -->
|
||||
|
||||
<!-- ============================== classes index ============================ -->
|
||||
<div id="index">
|
||||
<!-- begin publish.classesIndex -->
|
||||
{+publish.classesIndex+}
|
||||
<!-- end publish.classesIndex -->
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
<!-- ============================== class title ============================ -->
|
||||
<h1 class="classTitle">
|
||||
{!
|
||||
var classType = "";
|
||||
|
||||
if (data.isBuiltin()) {
|
||||
classType += "Built-In ";
|
||||
}
|
||||
|
||||
if (data.isNamespace) {
|
||||
if (data.is('FUNCTION')) {
|
||||
classType += "Function ";
|
||||
}
|
||||
classType += "Namespace ";
|
||||
}
|
||||
else {
|
||||
classType += "Class ";
|
||||
}
|
||||
!}
|
||||
{+classType+}{+data.alias+}
|
||||
</h1>
|
||||
|
||||
<!-- ============================== class summary ========================== -->
|
||||
<p class="description">
|
||||
<if test="data.augments.length"><br />Extends
|
||||
{+
|
||||
data.augments
|
||||
.sort()
|
||||
.map(
|
||||
function($) { return new Link().toSymbol($); }
|
||||
)
|
||||
.join(", ")
|
||||
+}.<br />
|
||||
</if>
|
||||
|
||||
{+resolveLinks(data.classDesc)+}
|
||||
|
||||
<if test="!data.isBuiltin()">{# isn't defined in any file #}
|
||||
<br /><i>Defined in: </i> {+new Link().toSrc(data.srcFile)+}.
|
||||
</if>
|
||||
</p>
|
||||
|
||||
<!-- ============================== constructor summary ==================== -->
|
||||
<if test="!data.isBuiltin() && (data.isNamespace || data.is('CONSTRUCTOR'))">
|
||||
<table class="summaryTable" cellspacing="0" summary="A summary of the constructor documented in the class {+data.alias+}.">
|
||||
<caption>{+classType+}Summary</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Constructor Attributes</th>
|
||||
<th scope="col">Constructor Name and Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="attributes">{!
|
||||
if (data.isPrivate) output += "<private> ";
|
||||
if (data.isInner) output += "<inner> ";
|
||||
!} </td>
|
||||
<td class="nameDescription" {!if (data.comment.getTag("hilited").length){output += 'style="color: red"'}!}>
|
||||
<div class="fixedFont">
|
||||
<b>{+ new Link().toSymbol(data.alias).inner('constructor')+}</b><if test="classType != 'Namespace '">{+ makeSignature(data.params) +}</if>
|
||||
</div>
|
||||
<div class="description">{+resolveLinks(summarize(data.desc))+}</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</if>
|
||||
|
||||
<!-- ============================== properties summary ===================== -->
|
||||
<if test="data.properties.length">
|
||||
{! var ownProperties = data.properties.filter(function($){return $.memberOf == data.alias && !$.isNamespace}).sort(makeSortby("name")); !}
|
||||
<if test="ownProperties.length">
|
||||
<table class="summaryTable" cellspacing="0" summary="A summary of the fields documented in the class {+data.alias+}.">
|
||||
<caption>Field Summary</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Field Attributes</th>
|
||||
<th scope="col">Field Name and Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<for each="member" in="ownProperties">
|
||||
<tr>
|
||||
<td class="attributes">{!
|
||||
if (member.isPrivate) output += "<private> ";
|
||||
if (member.isInner) output += "<inner> ";
|
||||
if (member.isStatic) output += "<static> ";
|
||||
if (member.isConstant) output += "<constant> ";
|
||||
!} </td>
|
||||
<td class="nameDescription">
|
||||
<div class="fixedFont">
|
||||
<if test="member.isStatic && member.memberOf != '_global_'">{+member.memberOf+}.</if><b>{+new Link().toSymbol(member.alias).withText(member.name)+}</b>
|
||||
</div>
|
||||
<div class="description">{+resolveLinks(summarize(member.desc))+}</div>
|
||||
</td>
|
||||
</tr>
|
||||
</for>
|
||||
</tbody>
|
||||
</table>
|
||||
</if>
|
||||
|
||||
<if test="data.inheritsFrom.length">
|
||||
<dl class="inheritsList">
|
||||
{!
|
||||
var borrowedMembers = data.properties.filter(function($) {return $.memberOf != data.alias});
|
||||
|
||||
var contributers = [];
|
||||
borrowedMembers.map(function($) {if (contributers.indexOf($.memberOf) < 0) contributers.push($.memberOf)});
|
||||
for (var i = 0, l = contributers.length; i < l; i++) {
|
||||
output +=
|
||||
"<dt>Fields borrowed from class "+new Link().toSymbol(contributers[i])+": </dt>"
|
||||
+
|
||||
"<dd>" +
|
||||
borrowedMembers
|
||||
.filter(
|
||||
function($) { return $.memberOf == contributers[i] }
|
||||
)
|
||||
.sort(makeSortby("name"))
|
||||
.map(
|
||||
function($) { return new Link().toSymbol($.alias).withText($.name) }
|
||||
)
|
||||
.join(", ")
|
||||
+
|
||||
"</dd>";
|
||||
}
|
||||
!}
|
||||
</dl>
|
||||
</if>
|
||||
</if>
|
||||
|
||||
<!-- ============================== methods summary ======================== -->
|
||||
<if test="data.methods.length">
|
||||
{! var ownMethods = data.methods.filter(function($){return $.memberOf == data.alias && !$.isNamespace}).sort(makeSortby("name")); !}
|
||||
<if test="ownMethods.length">
|
||||
<table class="summaryTable" cellspacing="0" summary="A summary of the methods documented in the class {+data.alias+}.">
|
||||
<caption>Method Summary</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Method Attributes</th>
|
||||
<th scope="col">Method Name and Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<for each="member" in="ownMethods">
|
||||
<tr>
|
||||
<td class="attributes">{!
|
||||
if (member.isPrivate) output += "<private> ";
|
||||
if (member.isInner) output += "<inner> ";
|
||||
if (member.isStatic) output += "<static> ";
|
||||
!} </td>
|
||||
<td class="nameDescription">
|
||||
<div class="fixedFont"><if test="member.isStatic && member.memberOf != '_global_'">{+member.memberOf+}.</if><b>{+new Link().toSymbol(member.alias).withText(member.name)+}</b>{+makeSignature(member.params)+}
|
||||
</div>
|
||||
<div class="description">{+resolveLinks(summarize(member.desc))+}</div>
|
||||
</td>
|
||||
</tr>
|
||||
</for>
|
||||
</tbody>
|
||||
</table>
|
||||
</if>
|
||||
|
||||
<if test="data.inheritsFrom.length">
|
||||
<dl class="inheritsList">
|
||||
{!
|
||||
var borrowedMembers = data.methods.filter(function($) {return $.memberOf != data.alias});
|
||||
var contributers = [];
|
||||
borrowedMembers.map(function($) {if (contributers.indexOf($.memberOf) < 0) contributers.push($.memberOf)});
|
||||
for (var i = 0, l = contributers.length; i < l; i++) {
|
||||
output +=
|
||||
"<dt>Methods borrowed from class "+new Link().toSymbol(contributers[i])+": </dt>"
|
||||
+
|
||||
"<dd>" +
|
||||
borrowedMembers
|
||||
.filter(
|
||||
function($) { return $.memberOf == contributers[i] }
|
||||
)
|
||||
.sort(makeSortby("name"))
|
||||
.map(
|
||||
function($) { return new Link().toSymbol($.alias).withText($.name) }
|
||||
)
|
||||
.join(", ")
|
||||
+
|
||||
"</dd>";
|
||||
}
|
||||
|
||||
!}
|
||||
</dl>
|
||||
</if>
|
||||
</if>
|
||||
<!-- ============================== events summary ======================== -->
|
||||
<if test="data.events.length">
|
||||
{! var ownEvents = data.events.filter(function($){return $.memberOf == data.alias && !$.isNamespace}).sort(makeSortby("name")); !}
|
||||
<if test="ownEvents.length">
|
||||
<table class="summaryTable" cellspacing="0" summary="A summary of the events documented in the class {+data.alias+}.">
|
||||
<caption>Event Summary</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Event Attributes</th>
|
||||
<th scope="col">Event Name and Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<for each="member" in="ownEvents">
|
||||
<tr>
|
||||
<td class="attributes">{!
|
||||
if (member.isPrivate) output += "<private> ";
|
||||
if (member.isInner) output += "<inner> ";
|
||||
if (member.isStatic) output += "<static> ";
|
||||
!} </td>
|
||||
<td class="nameDescription">
|
||||
<div class="fixedFont"><if test="member.isStatic && member.memberOf != '_global_'">{+member.memberOf+}.</if><b>{+new Link().toSymbol(member.alias).withText(member.name)+}</b>{+makeSignature(member.params)+}
|
||||
</div>
|
||||
<div class="description">{+resolveLinks(summarize(member.desc))+}</div>
|
||||
</td>
|
||||
</tr>
|
||||
</for>
|
||||
</tbody>
|
||||
</table>
|
||||
</if>
|
||||
|
||||
<if test="data.inheritsFrom.length">
|
||||
<dl class="inheritsList">
|
||||
{!
|
||||
var borrowedMembers = data.events.filter(function($) {return $.memberOf != data.alias});
|
||||
var contributers = [];
|
||||
borrowedMembers.map(function($) {if (contributers.indexOf($.memberOf) < 0) contributers.push($.memberOf)});
|
||||
for (var i = 0, l = contributers.length; i < l; i++) {
|
||||
output +=
|
||||
"<dt>Events borrowed from class "+new Link().toSymbol(contributers[i])+": </dt>"
|
||||
+
|
||||
"<dd>" +
|
||||
borrowedMembers
|
||||
.filter(
|
||||
function($) { return $.memberOf == contributers[i] }
|
||||
)
|
||||
.sort(makeSortby("name"))
|
||||
.map(
|
||||
function($) { return new Link().toSymbol($.alias).withText($.name) }
|
||||
)
|
||||
.join(", ")
|
||||
+
|
||||
"</dd>";
|
||||
}
|
||||
|
||||
!}
|
||||
</dl>
|
||||
</if>
|
||||
</if>
|
||||
|
||||
<!-- ============================== constructor details ==================== -->
|
||||
<if test="!data.isBuiltin() && (data.isNamespace || data.is('CONSTRUCTOR'))">
|
||||
<div class="details"><a name="constructor"> </a>
|
||||
<div class="sectionTitle">
|
||||
{+classType+}Detail
|
||||
</div>
|
||||
|
||||
<div class="fixedFont">{!
|
||||
if (data.isPrivate) output += "<private> ";
|
||||
if (data.isInner) output += "<inner> ";
|
||||
!}
|
||||
<b>{+ data.alias +}</b><if test="classType != 'Namespace '">{+ makeSignature(data.params) +}</if>
|
||||
</div>
|
||||
|
||||
<div class="description">
|
||||
{+resolveLinks(data.desc)+}
|
||||
<if test="data.author"><br /><i>Author: </i>{+data.author+}.</if>
|
||||
</div>
|
||||
|
||||
<if test="data.example.length">
|
||||
<for each="example" in="data.example">
|
||||
<pre class="code">{+example+}</pre>
|
||||
</for>
|
||||
</if>
|
||||
|
||||
|
||||
<if test="data.params.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Parameters:</dt>
|
||||
<for each="item" in="data.params">
|
||||
<dt>
|
||||
{+((item.type)?""+("<span class=\"light fixedFont\">{"+(new Link().toSymbol(item.type)+"}</span> ")) : "")+} <b>{+item.name+}</b>
|
||||
<if test="item.isOptional"><i>Optional<if test="item.defaultValue">, Default: {+item.defaultValue+}</if></i></if>
|
||||
</dt>
|
||||
<dd>{+resolveLinks(item.desc)+}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="data.deprecated">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Deprecated:</dt>
|
||||
<dt>
|
||||
{+resolveLinks(data.deprecated)+}
|
||||
</dt>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="data.since">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Since:</dt>
|
||||
<dd>{+ data.since +}</dd>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="data.exceptions.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Throws:</dt>
|
||||
<for each="item" in="data.exceptions">
|
||||
<dt>
|
||||
{+((item.type)?"<span class=\"light fixedFont\">{"+(new Link().toSymbol(item.type))+"}</span> " : "")+} <b>{+item.name+}</b>
|
||||
</dt>
|
||||
<dd>{+resolveLinks(item.desc)+}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="data.returns.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Returns:</dt>
|
||||
<for each="item" in="data.returns">
|
||||
<dd>{+((item.type)?"<span class=\"light fixedFont\">{"+(new Link().toSymbol(item.type))+"}</span> " : "")+}{+resolveLinks(item.desc)+}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="data.requires.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Requires:</dt>
|
||||
<for each="item" in="data.requires">
|
||||
<dd>{+ resolveLinks(item) +}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="data.see.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">See:</dt>
|
||||
<for each="item" in="data.see">
|
||||
<dd>{+ new Link().toSymbol(item) +}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
|
||||
</div>
|
||||
</if>
|
||||
|
||||
<!-- ============================== field details ========================== -->
|
||||
<if test="defined(ownProperties) && ownProperties.length">
|
||||
<div class="sectionTitle">
|
||||
Field Detail
|
||||
</div>
|
||||
<for each="member" in="ownProperties">
|
||||
<a name="{+Link.symbolNameToLinkName(member)+}"> </a>
|
||||
<div class="fixedFont">{!
|
||||
if (member.isPrivate) output += "<private> ";
|
||||
if (member.isInner) output += "<inner> ";
|
||||
if (member.isStatic) output += "<static> ";
|
||||
if (member.isConstant) output += "<constant> ";
|
||||
!}
|
||||
|
||||
<if test="member.type"><span class="light">{{+new Link().toSymbol(member.type)+}}</span></if>
|
||||
<if test="member.isStatic && member.memberOf != '_global_'"><span class="light">{+member.memberOf+}.</span></if><b>{+member.name+}</b>
|
||||
|
||||
</div>
|
||||
<div class="description">
|
||||
{+resolveLinks(member.desc)+}
|
||||
<if test="member.srcFile != data.srcFile">
|
||||
<br />
|
||||
<i>Defined in: </i> {+new Link().toSrc(member.srcFile)+}.
|
||||
</if>
|
||||
<if test="member.author"><br /><i>Author: </i>{+member.author+}.</if>
|
||||
</div>
|
||||
|
||||
<if test="member.example.length">
|
||||
<for each="example" in="member.example">
|
||||
<pre class="code">{+example+}</pre>
|
||||
</for>
|
||||
</if>
|
||||
|
||||
<if test="member.deprecated">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Deprecated:</dt>
|
||||
<dt>
|
||||
{+ member.deprecated +}
|
||||
</dt>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="member.since">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Since:</dt>
|
||||
<dd>{+ member.since +}</dd>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="member.see.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">See:</dt>
|
||||
<for each="item" in="member.see">
|
||||
<dd>{+ new Link().toSymbol(item) +}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="member.defaultValue">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Default Value:</dt>
|
||||
<dd>
|
||||
{+resolveLinks(member.defaultValue)+}
|
||||
</dd>
|
||||
</dl>
|
||||
</if>
|
||||
|
||||
<if test="!$member_last"><hr /></if>
|
||||
</for>
|
||||
</if>
|
||||
|
||||
<!-- ============================== method details ========================= -->
|
||||
<if test="defined(ownMethods) && ownMethods.length">
|
||||
<div class="sectionTitle">
|
||||
Method Detail
|
||||
</div>
|
||||
<for each="member" in="ownMethods">
|
||||
<a name="{+Link.symbolNameToLinkName(member)+}"> </a>
|
||||
<div class="fixedFont">{!
|
||||
if (member.isPrivate) output += "<private> ";
|
||||
if (member.isInner) output += "<inner> ";
|
||||
if (member.isStatic) output += "<static> ";
|
||||
!}
|
||||
|
||||
<if test="member.type"><span class="light">{{+new Link().toSymbol(member.type)+}}</span></if>
|
||||
<if test="member.isStatic && member.memberOf != '_global_'"><span class="light">{+member.memberOf+}.</span></if><b>{+member.name+}</b>{+makeSignature(member.params)+}
|
||||
|
||||
</div>
|
||||
<div class="description">
|
||||
{+resolveLinks(member.desc)+}
|
||||
<if test="member.srcFile != data.srcFile">
|
||||
<br />
|
||||
<i>Defined in: </i> {+new Link().toSrc(member.srcFile)+}.
|
||||
</if>
|
||||
<if test="member.author"><br /><i>Author: </i>{+member.author+}.</if>
|
||||
</div>
|
||||
|
||||
<if test="member.example.length">
|
||||
<for each="example" in="member.example">
|
||||
<pre class="code">{+example+}</pre>
|
||||
</for>
|
||||
</if>
|
||||
|
||||
<if test="member.params.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Parameters:</dt>
|
||||
<for each="item" in="member.params">
|
||||
<dt>
|
||||
{+((item.type)?"<span class=\"light fixedFont\">{"+(new Link().toSymbol(item.type))+"}</span> " : "")+}<b>{+item.name+}</b>
|
||||
<if test="item.isOptional"><i>Optional<if test="item.defaultValue">, Default: {+item.defaultValue+}</if></i></if>
|
||||
</dt>
|
||||
<dd>{+resolveLinks(item.desc)+}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="member.deprecated">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Deprecated:</dt>
|
||||
<dt>
|
||||
{+member.deprecated+}
|
||||
</dt>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="member.since">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Since:</dt>
|
||||
<dd>{+ member.since +}</dd>
|
||||
</dl>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="member.exceptions.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Throws:</dt>
|
||||
<for each="item" in="member.exceptions">
|
||||
<dt>
|
||||
{+((item.type)?"<span class=\"light fixedFont\">{"+(new Link().toSymbol(item.type))+"}</span> " : "")+} <b>{+item.name+}</b>
|
||||
</dt>
|
||||
<dd>{+resolveLinks(item.desc)+}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="member.returns.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Returns:</dt>
|
||||
<for each="item" in="member.returns">
|
||||
<dd>{+((item.type)?"<span class=\"light fixedFont\">{"+(new Link().toSymbol(item.type))+"}</span> " : "")+}{+resolveLinks(item.desc)+}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="member.requires.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Requires:</dt>
|
||||
<for each="item" in="member.requires">
|
||||
<dd>{+ resolveLinks(item) +}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="member.see.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">See:</dt>
|
||||
<for each="item" in="member.see">
|
||||
<dd>{+ new Link().toSymbol(item) +}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
|
||||
<if test="!$member_last"><hr /></if>
|
||||
</for>
|
||||
</if>
|
||||
|
||||
<!-- ============================== event details ========================= -->
|
||||
<if test="defined(ownEvents) && ownEvents.length">
|
||||
<div class="sectionTitle">
|
||||
Event Detail
|
||||
</div>
|
||||
<for each="member" in="ownEvents">
|
||||
<a name="event:{+Link.symbolNameToLinkName(member)+}"> </a>
|
||||
<div class="fixedFont">{!
|
||||
if (member.isPrivate) output += "<private> ";
|
||||
if (member.isInner) output += "<inner> ";
|
||||
if (member.isStatic) output += "<static> ";
|
||||
!}
|
||||
|
||||
<if test="member.type"><span class="light">{{+new Link().toSymbol(member.type)+}}</span></if>
|
||||
<if test="member.isStatic && member.memberOf != '_global_'"><span class="light">{+member.memberOf+}.</span></if><b>{+member.name+}</b>{+makeSignature(member.params)+}
|
||||
|
||||
</div>
|
||||
<div class="description">
|
||||
{+resolveLinks(member.desc)+}
|
||||
<if test="member.srcFile != data.srcFile">
|
||||
<br />
|
||||
<i>Defined in: </i> {+new Link().toSrc(member.srcFile)+}.
|
||||
</if>
|
||||
<if test="member.author"><br /><i>Author: </i>{+member.author+}.</if>
|
||||
</div>
|
||||
|
||||
<if test="member.example.length">
|
||||
<for each="example" in="member.example">
|
||||
<pre class="code">{+example+}</pre>
|
||||
</for>
|
||||
</if>
|
||||
|
||||
<if test="member.params.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Parameters:</dt>
|
||||
<for each="item" in="member.params">
|
||||
<dt>
|
||||
{+((item.type)?"<span class=\"light fixedFont\">{"+(new Link().toSymbol(item.type))+"}</span> " : "")+}<b>{+item.name+}</b>
|
||||
<if test="item.isOptional"><i>Optional<if test="item.defaultValue">, Default: {+item.defaultValue+}</if></i></if>
|
||||
</dt>
|
||||
<dd>{+resolveLinks(item.desc)+}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="member.deprecated">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Deprecated:</dt>
|
||||
<dt>
|
||||
{+member.deprecated+}
|
||||
</dt>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="member.since">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Since:</dt>
|
||||
<dd>{+ member.since +}</dd>
|
||||
</dl>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="member.exceptions.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Throws:</dt>
|
||||
<for each="item" in="member.exceptions">
|
||||
<dt>
|
||||
{+((item.type)?"<span class=\"light fixedFont\">{"+(new Link().toSymbol(item.type))+"}</span> " : "")+} <b>{+item.name+}</b>
|
||||
</dt>
|
||||
<dd>{+resolveLinks(item.desc)+}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="member.returns.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Returns:</dt>
|
||||
<for each="item" in="member.returns">
|
||||
<dd>{+((item.type)?"<span class=\"light fixedFont\">{"+(new Link().toSymbol(item.type))+"}</span> " : "")+}{+resolveLinks(item.desc)+}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="member.requires.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">Requires:</dt>
|
||||
<for each="item" in="member.requires">
|
||||
<dd>{+ resolveLinks(item) +}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
<if test="member.see.length">
|
||||
<dl class="detailList">
|
||||
<dt class="heading">See:</dt>
|
||||
<for each="item" in="member.see">
|
||||
<dd>{+ new Link().toSymbol(item) +}</dd>
|
||||
</for>
|
||||
</dl>
|
||||
</if>
|
||||
|
||||
<if test="!$member_last"><hr /></if>
|
||||
</for>
|
||||
</if>
|
||||
|
||||
<hr />
|
||||
</div>
|
||||
|
||||
|
||||
<!-- ============================== footer ================================= -->
|
||||
<div class="fineprint" style="clear:both">
|
||||
<if test="JSDOC.opt.D.copyright">©{+JSDOC.opt.D.copyright+}<br /></if>
|
||||
Documentation generated by <a href="http://www.jsdoctoolkit.org/" target="_blank">JsDoc Toolkit</a> {+JSDOC.VERSION+} on {+new Date()+}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,39 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset={+IO.encoding+}"" />
|
||||
|
||||
<title>JsDoc Reference - Index</title>
|
||||
<meta name="generator" content="JsDoc Toolkit" />
|
||||
|
||||
<style type="text/css">
|
||||
{+include("static/default.css")+}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
{+include("static/header.html")+}
|
||||
|
||||
<div id="index">
|
||||
{+publish.classesIndex+}
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
<h1 class="classTitle">Class Index</h1>
|
||||
|
||||
<for each="thisClass" in="data">
|
||||
<div>
|
||||
<h2>{+(new Link().toSymbol(thisClass.alias))+}</h2>
|
||||
{+resolveLinks(summarize(thisClass.classDesc))+}
|
||||
</div>
|
||||
<hr />
|
||||
</for>
|
||||
|
||||
</div>
|
||||
<div class="fineprint" style="clear:both">
|
||||
<if test="JSDOC.opt.D.copyright">©{+JSDOC.opt.D.copyright+}<br /></if>
|
||||
Documentation generated by <a href="http://www.jsdoctoolkit.org/" target="_blankt">JsDoc Toolkit</a> {+JSDOC.VERSION+} on {+new Date()+}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,184 +0,0 @@
|
||||
/** Called automatically by JsDoc Toolkit. */
|
||||
function publish(symbolSet) {
|
||||
publish.conf = { // trailing slash expected for dirs
|
||||
ext: ".html",
|
||||
outDir: JSDOC.opt.d || SYS.pwd+"../out/jsdoc/",
|
||||
templatesDir: JSDOC.opt.t || SYS.pwd+"../templates/jsdoc/",
|
||||
symbolsDir: "symbols/",
|
||||
srcDir: "symbols/src/"
|
||||
};
|
||||
|
||||
// is source output is suppressed, just display the links to the source file
|
||||
if (JSDOC.opt.s && defined(Link) && Link.prototype._makeSrcLink) {
|
||||
Link.prototype._makeSrcLink = function(srcFilePath) {
|
||||
return "<"+srcFilePath+">";
|
||||
}
|
||||
}
|
||||
|
||||
// create the folders and subfolders to hold the output
|
||||
IO.mkPath((publish.conf.outDir+"symbols/src").split("/"));
|
||||
|
||||
// used to allow Link to check the details of things being linked to
|
||||
Link.symbolSet = symbolSet;
|
||||
|
||||
// create the required templates
|
||||
try {
|
||||
var classTemplate = new JSDOC.JsPlate(publish.conf.templatesDir+"class.tmpl");
|
||||
var classesTemplate = new JSDOC.JsPlate(publish.conf.templatesDir+"allclasses.tmpl");
|
||||
}
|
||||
catch(e) {
|
||||
print("Couldn't create the required templates: "+e);
|
||||
quit();
|
||||
}
|
||||
|
||||
// some ustility filters
|
||||
function hasNoParent($) {return ($.memberOf == "")}
|
||||
function isaFile($) {return ($.is("FILE"))}
|
||||
function isaClass($) {return ($.is("CONSTRUCTOR") || $.isNamespace)}
|
||||
|
||||
// get an array version of the symbolset, useful for filtering
|
||||
var symbols = symbolSet.toArray();
|
||||
|
||||
// create the hilited source code files
|
||||
var files = JSDOC.opt.srcFiles;
|
||||
for (var i = 0, l = files.length; i < l; i++) {
|
||||
var file = files[i];
|
||||
var srcDir = publish.conf.outDir + "symbols/src/";
|
||||
makeSrcFile(file, srcDir);
|
||||
}
|
||||
|
||||
// get a list of all the classes in the symbolset
|
||||
var classes = symbols.filter(isaClass).sort(makeSortby("alias"));
|
||||
|
||||
// create a class index, displayed in the left-hand column of every class page
|
||||
Link.base = "../";
|
||||
publish.classesIndex = classesTemplate.process(classes); // kept in memory
|
||||
|
||||
// create each of the class pages
|
||||
for (var i = 0, l = classes.length; i < l; i++) {
|
||||
var symbol = classes[i];
|
||||
|
||||
symbol.events = symbol.getEvents(); // 1 order matters
|
||||
symbol.methods = symbol.getMethods(); // 2
|
||||
|
||||
var output = "";
|
||||
output = classTemplate.process(symbol);
|
||||
|
||||
IO.saveFile(publish.conf.outDir+"symbols/", symbol.alias+publish.conf.ext, output);
|
||||
}
|
||||
|
||||
// regenerate the index with different relative links, used in the index pages
|
||||
Link.base = "";
|
||||
publish.classesIndex = classesTemplate.process(classes);
|
||||
|
||||
// create the class index page
|
||||
try {
|
||||
var classesindexTemplate = new JSDOC.JsPlate(publish.conf.templatesDir+"index.tmpl");
|
||||
}
|
||||
catch(e) { print(e.message); quit(); }
|
||||
|
||||
var classesIndex = classesindexTemplate.process(classes);
|
||||
IO.saveFile(publish.conf.outDir, "index"+publish.conf.ext, classesIndex);
|
||||
classesindexTemplate = classesIndex = classes = null;
|
||||
|
||||
// create the file index page
|
||||
try {
|
||||
var fileindexTemplate = new JSDOC.JsPlate(publish.conf.templatesDir+"allfiles.tmpl");
|
||||
}
|
||||
catch(e) { print(e.message); quit(); }
|
||||
|
||||
var documentedFiles = symbols.filter(isaFile); // files that have file-level docs
|
||||
var allFiles = []; // not all files have file-level docs, but we need to list every one
|
||||
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
allFiles.push(new JSDOC.Symbol(files[i], [], "FILE", new JSDOC.DocComment("/** */")));
|
||||
}
|
||||
|
||||
for (var i = 0; i < documentedFiles.length; i++) {
|
||||
var offset = files.indexOf(documentedFiles[i].alias);
|
||||
allFiles[offset] = documentedFiles[i];
|
||||
}
|
||||
|
||||
allFiles = allFiles.sort(makeSortby("name"));
|
||||
|
||||
// output the file index page
|
||||
var filesIndex = fileindexTemplate.process(allFiles);
|
||||
IO.saveFile(publish.conf.outDir, "files"+publish.conf.ext, filesIndex);
|
||||
fileindexTemplate = filesIndex = files = null;
|
||||
}
|
||||
|
||||
|
||||
/** Just the first sentence (up to a full stop). Should not break on dotted variable names. */
|
||||
function summarize(desc) {
|
||||
if (typeof desc != "undefined")
|
||||
return desc.match(/([\w\W]+?\.)[^a-z0-9_$]/i)? RegExp.$1 : desc;
|
||||
}
|
||||
|
||||
/** Make a symbol sorter by some attribute. */
|
||||
function makeSortby(attribute) {
|
||||
return function(a, b) {
|
||||
if (a[attribute] != undefined && b[attribute] != undefined) {
|
||||
a = a[attribute].toLowerCase();
|
||||
b = b[attribute].toLowerCase();
|
||||
if (a < b) return -1;
|
||||
if (a > b) return 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Pull in the contents of an external file at the given path. */
|
||||
function include(path) {
|
||||
var path = publish.conf.templatesDir+path;
|
||||
return IO.readFile(path);
|
||||
}
|
||||
|
||||
/** Turn a raw source file into a code-hilited page in the docs. */
|
||||
function makeSrcFile(path, srcDir, name) {
|
||||
if (JSDOC.opt.s) return;
|
||||
|
||||
if (!name) {
|
||||
name = path.replace(/\.\.?[\\\/]/g, "").replace(/[\\\/]/g, "_");
|
||||
name = name.replace(/\:/g, "_");
|
||||
}
|
||||
|
||||
var src = {path: path, name:name, charset: IO.encoding, hilited: ""};
|
||||
|
||||
if (defined(JSDOC.PluginManager)) {
|
||||
JSDOC.PluginManager.run("onPublishSrc", src);
|
||||
}
|
||||
|
||||
if (src.hilited) {
|
||||
IO.saveFile(srcDir, name+publish.conf.ext, src.hilited);
|
||||
}
|
||||
}
|
||||
|
||||
/** Build output for displaying function parameters. */
|
||||
function makeSignature(params) {
|
||||
if (!params) return "()";
|
||||
var signature = "("
|
||||
+
|
||||
params.filter(
|
||||
function($) {
|
||||
return $.name.indexOf(".") == -1; // don't show config params in signature
|
||||
}
|
||||
).map(
|
||||
function($) {
|
||||
return $.name;
|
||||
}
|
||||
).join(", ")
|
||||
+
|
||||
")";
|
||||
return signature;
|
||||
}
|
||||
|
||||
/** Find symbol {@link ...} strings in text and turn into html links */
|
||||
function resolveLinks(str, from) {
|
||||
str = str.replace(/\{@link ([^} ]+) ?\}/gi,
|
||||
function(match, symbolName) {
|
||||
return new Link().toSymbol(symbolName);
|
||||
}
|
||||
);
|
||||
|
||||
return str;
|
||||
}
|
||||
@@ -1,162 +0,0 @@
|
||||
/* default.css */
|
||||
body
|
||||
{
|
||||
font: 12px "Lucida Grande", Tahoma, Arial, Helvetica, sans-serif;
|
||||
width: 800px;
|
||||
}
|
||||
|
||||
.header
|
||||
{
|
||||
clear: both;
|
||||
background-color: #ccc;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
h1
|
||||
{
|
||||
font-size: 150%;
|
||||
font-weight: bold;
|
||||
padding: 0;
|
||||
margin: 1em 0 0 .3em;
|
||||
}
|
||||
|
||||
hr
|
||||
{
|
||||
border: none 0;
|
||||
border-top: 1px solid #7F8FB1;
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
pre.code
|
||||
{
|
||||
display: block;
|
||||
padding: 8px;
|
||||
border: 1px dashed #ccc;
|
||||
}
|
||||
|
||||
#index
|
||||
{
|
||||
margin-top: 24px;
|
||||
float: left;
|
||||
width: 160px;
|
||||
position: absolute;
|
||||
left: 8px;
|
||||
background-color: #F3F3F3;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
#content
|
||||
{
|
||||
margin-left: 190px;
|
||||
width: 600px;
|
||||
}
|
||||
|
||||
.classList
|
||||
{
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
margin: 0 0 0 8px;
|
||||
font-family: arial, sans-serif;
|
||||
font-size: 1em;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.classList li
|
||||
{
|
||||
padding: 0;
|
||||
margin: 0 0 8px 0;
|
||||
}
|
||||
|
||||
.summaryTable { width: 100%; }
|
||||
|
||||
h1.classTitle
|
||||
{
|
||||
font-size:170%;
|
||||
line-height:130%;
|
||||
}
|
||||
|
||||
h2 { font-size: 110%; }
|
||||
caption, div.sectionTitle
|
||||
{
|
||||
background-color: #7F8FB1;
|
||||
color: #fff;
|
||||
font-size:130%;
|
||||
text-align: left;
|
||||
padding: 2px 6px 2px 6px;
|
||||
border: 1px #7F8FB1 solid;
|
||||
}
|
||||
|
||||
div.sectionTitle { margin-bottom: 8px; }
|
||||
.summaryTable thead { display: none; }
|
||||
|
||||
.summaryTable td
|
||||
{
|
||||
vertical-align: top;
|
||||
padding: 4px;
|
||||
border-bottom: 1px #7F8FB1 solid;
|
||||
border-right: 1px #7F8FB1 solid;
|
||||
}
|
||||
|
||||
/*col#summaryAttributes {}*/
|
||||
.summaryTable td.attributes
|
||||
{
|
||||
border-left: 1px #7F8FB1 solid;
|
||||
width: 140px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
td.attributes, .fixedFont
|
||||
{
|
||||
line-height: 15px;
|
||||
color: #002EBE;
|
||||
font-family: "Courier New",Courier,monospace;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.summaryTable td.nameDescription
|
||||
{
|
||||
text-align: left;
|
||||
font-size: 13px;
|
||||
line-height: 15px;
|
||||
}
|
||||
|
||||
.summaryTable td.nameDescription, .description
|
||||
{
|
||||
line-height: 15px;
|
||||
padding: 4px;
|
||||
padding-left: 4px;
|
||||
}
|
||||
|
||||
.summaryTable { margin-bottom: 8px; }
|
||||
|
||||
ul.inheritsList
|
||||
{
|
||||
list-style: square;
|
||||
margin-left: 20px;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.detailList {
|
||||
margin-left: 20px;
|
||||
line-height: 15px;
|
||||
}
|
||||
.detailList dt { margin-left: 20px; }
|
||||
|
||||
.detailList .heading
|
||||
{
|
||||
font-weight: bold;
|
||||
padding-bottom: 6px;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.light, td.attributes, .light a:link, .light a:visited
|
||||
{
|
||||
color: #777;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.fineprint
|
||||
{
|
||||
text-align: right;
|
||||
font-size: 10px;
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
<div id="header">
|
||||
</div>
|
||||
@@ -1,19 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<title>Generated Javascript Documentation</title>
|
||||
</head>
|
||||
<frameset cols="20%,80%">
|
||||
<frame src="allclasses-frame.html" name="packageFrame" />
|
||||
<frame src="splash.html" name="classFrame" />
|
||||
<noframes>
|
||||
<body>
|
||||
<p>
|
||||
This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client.
|
||||
</p>
|
||||
</body>
|
||||
</noframes>
|
||||
</frameset>
|
||||
</html>
|
||||
@@ -1,35 +0,0 @@
|
||||
<symbol alias="{+data.alias+}">
|
||||
<name>{+data.name+}</name>
|
||||
<memberOf>{+data.memberOf+}</memberOf>
|
||||
<isStatic>{+data.isStatic+}</isStatic>
|
||||
<isa>{+data.isa+}</isa>
|
||||
<desc>{+data.desc+}</desc>
|
||||
<classDesc>{+data.classDesc+}</classDesc>
|
||||
|
||||
<methods><for each="method" in="data.methods">
|
||||
<method>
|
||||
<name>{+method.name+}</name>
|
||||
<memberOf>{+method.memberOf+}</memberOf>
|
||||
<isStatic>{+method.isStatic+}</isStatic>
|
||||
<desc>{+method.desc+}</desc>
|
||||
<params><for each="param" in="method.params">
|
||||
<param>
|
||||
<type>{+param.type+}</type>
|
||||
<name>{+param.name+}</name>
|
||||
<desc>{+param.desc+}</desc>
|
||||
<defaultValue>{+param.defaultValue+}</defaultValue>
|
||||
</param></for>
|
||||
</params>
|
||||
</method></for>
|
||||
</methods>
|
||||
|
||||
<properties><for each="property" in="data.properties">
|
||||
<property>
|
||||
<name>{+property.name+}</name>
|
||||
<memberOf>{+property.memberOf+}</memberOf>
|
||||
<isStatic>{+property.isStatic+}</isStatic>
|
||||
<desc>{+property.desc+}</desc>
|
||||
<type>{+property.type+}</type>
|
||||
</property></for>
|
||||
</properties>
|
||||
</symbol>
|
||||
5919
jshint/jshint.js
5919
jshint/jshint.js
File diff suppressed because it is too large
Load Diff
@@ -1,99 +0,0 @@
|
||||
var fs = require("fs");
|
||||
var sys = require("sys");
|
||||
var path = require("path");
|
||||
var JSHINT = require("./jshint").JSHINT;
|
||||
|
||||
// DWF TODO: Standardize this?
|
||||
function isExcluded(fullPath) {
|
||||
var fileName = path.basename(fullPath);
|
||||
var excludeFiles = ["json2.js", "jshint.js", "publish.js", "node_suite.js", "jasmine.js", "jasmine-html.js"];
|
||||
for (var i = 0; i < excludeFiles.length; i++) {
|
||||
if (fileName == excludeFiles[i]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// DWF TODO: This function could/should be re-written
|
||||
function allJasmineJsFiles(rootDir) {
|
||||
var files = [];
|
||||
fs.readdirSync(rootDir).filter(function(filename) {
|
||||
|
||||
var fullPath = rootDir + "/" + filename;
|
||||
if (fs.statSync(fullPath).isDirectory() && !fullPath.match(/pages/)) {
|
||||
var subDirFiles = allJasmineJsFiles(fullPath);
|
||||
if (subDirFiles.length > 0) {
|
||||
files = files.concat();
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (fullPath.match(/\.js$/) && !isExcluded(fullPath)) {
|
||||
files.push(fullPath);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
var jasmineJsFiles = allJasmineJsFiles(".");
|
||||
jasmineJsFiles.reverse(); //cheap way to do the stuff in src stuff first
|
||||
|
||||
var jasmineJsHintConfig = {
|
||||
|
||||
forin:true, //while it's possible that we could be
|
||||
//considering unwanted prototype methods, mostly
|
||||
//we're doing this because the jsobjects are being
|
||||
//used as maps.
|
||||
|
||||
loopfunc:true //we're fine with functions defined inside loops (setTimeout functions, etc)
|
||||
|
||||
};
|
||||
|
||||
var jasmineGlobals = {};
|
||||
|
||||
|
||||
//jasmine.undefined is a jasmine-ism, let's let it go...
|
||||
function removeJasmineUndefinedErrors(errors) {
|
||||
var keepErrors = [];
|
||||
for (var i = 0; i < errors.length; i++) {
|
||||
if (!(errors[i] &&
|
||||
errors[i].raw &&
|
||||
errors[i].evidence &&
|
||||
( errors[i].evidence.match(/jasmine\.undefined/) ||
|
||||
errors[i].evidence.match(/diz be undefined yo/) )
|
||||
)) {
|
||||
keepErrors.push(errors[i]);
|
||||
}
|
||||
}
|
||||
return keepErrors;
|
||||
}
|
||||
|
||||
(function() {
|
||||
var ansi = {
|
||||
green: '\033[32m',
|
||||
red: '\033[31m',
|
||||
yellow: '\033[33m',
|
||||
none: '\033[0m'
|
||||
};
|
||||
|
||||
for (var i = 0; i < jasmineJsFiles.length; i++) {
|
||||
var file = jasmineJsFiles[i];
|
||||
JSHINT(fs.readFileSync(file, "utf8"), jasmineJsHintConfig);
|
||||
var errors = JSHINT.data().errors || [];
|
||||
errors = removeJasmineUndefinedErrors(errors);
|
||||
|
||||
if (errors.length >= 1) {
|
||||
console.log(ansi.red + "Jasmine JSHint failure: " + ansi.none);
|
||||
console.log(file);
|
||||
console.log(errors);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
console.log(ansi.green + "Jasmine JSHint PASSED." + ansi.none);
|
||||
})();
|
||||
|
||||
190
lib/console/console.js
Normal file
190
lib/console/console.js
Normal file
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
Copyright (c) 2008-2014 Pivotal Labs
|
||||
|
||||
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.
|
||||
*/
|
||||
function getJasmineRequireObj() {
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
return exports;
|
||||
} else {
|
||||
window.jasmineRequire = window.jasmineRequire || {};
|
||||
return window.jasmineRequire;
|
||||
}
|
||||
}
|
||||
|
||||
getJasmineRequireObj().console = function(jRequire, j$) {
|
||||
j$.ConsoleReporter = jRequire.ConsoleReporter();
|
||||
};
|
||||
|
||||
getJasmineRequireObj().ConsoleReporter = function() {
|
||||
|
||||
var noopTimer = {
|
||||
start: function(){},
|
||||
elapsed: function(){ return 0; }
|
||||
};
|
||||
|
||||
function ConsoleReporter(options) {
|
||||
var print = options.print,
|
||||
showColors = options.showColors || false,
|
||||
onComplete = options.onComplete || function() {},
|
||||
timer = options.timer || noopTimer,
|
||||
specCount,
|
||||
failureCount,
|
||||
failedSpecs = [],
|
||||
pendingCount,
|
||||
ansi = {
|
||||
green: '\x1B[32m',
|
||||
red: '\x1B[31m',
|
||||
yellow: '\x1B[33m',
|
||||
none: '\x1B[0m'
|
||||
},
|
||||
failedSuites = [];
|
||||
|
||||
print('ConsoleReporter is deprecated and will be removed in a future version.');
|
||||
|
||||
this.jasmineStarted = function() {
|
||||
specCount = 0;
|
||||
failureCount = 0;
|
||||
pendingCount = 0;
|
||||
print('Started');
|
||||
printNewline();
|
||||
timer.start();
|
||||
};
|
||||
|
||||
this.jasmineDone = function() {
|
||||
printNewline();
|
||||
for (var i = 0; i < failedSpecs.length; i++) {
|
||||
specFailureDetails(failedSpecs[i]);
|
||||
}
|
||||
|
||||
if(specCount > 0) {
|
||||
printNewline();
|
||||
|
||||
var specCounts = specCount + ' ' + plural('spec', specCount) + ', ' +
|
||||
failureCount + ' ' + plural('failure', failureCount);
|
||||
|
||||
if (pendingCount) {
|
||||
specCounts += ', ' + pendingCount + ' pending ' + plural('spec', pendingCount);
|
||||
}
|
||||
|
||||
print(specCounts);
|
||||
} else {
|
||||
print('No specs found');
|
||||
}
|
||||
|
||||
printNewline();
|
||||
var seconds = timer.elapsed() / 1000;
|
||||
print('Finished in ' + seconds + ' ' + plural('second', seconds));
|
||||
printNewline();
|
||||
|
||||
for(i = 0; i < failedSuites.length; i++) {
|
||||
suiteFailureDetails(failedSuites[i]);
|
||||
}
|
||||
|
||||
onComplete(failureCount === 0);
|
||||
};
|
||||
|
||||
this.specDone = function(result) {
|
||||
specCount++;
|
||||
|
||||
if (result.status == 'pending') {
|
||||
pendingCount++;
|
||||
print(colored('yellow', '*'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (result.status == 'passed') {
|
||||
print(colored('green', '.'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (result.status == 'failed') {
|
||||
failureCount++;
|
||||
failedSpecs.push(result);
|
||||
print(colored('red', 'F'));
|
||||
}
|
||||
};
|
||||
|
||||
this.suiteDone = function(result) {
|
||||
if (result.failedExpectations && result.failedExpectations.length > 0) {
|
||||
failureCount++;
|
||||
failedSuites.push(result);
|
||||
}
|
||||
};
|
||||
|
||||
return this;
|
||||
|
||||
function printNewline() {
|
||||
print('\n');
|
||||
}
|
||||
|
||||
function colored(color, str) {
|
||||
return showColors ? (ansi[color] + str + ansi.none) : str;
|
||||
}
|
||||
|
||||
function plural(str, count) {
|
||||
return count == 1 ? str : str + 's';
|
||||
}
|
||||
|
||||
function repeat(thing, times) {
|
||||
var arr = [];
|
||||
for (var i = 0; i < times; i++) {
|
||||
arr.push(thing);
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
function indent(str, spaces) {
|
||||
var lines = (str || '').split('\n');
|
||||
var newArr = [];
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
newArr.push(repeat(' ', spaces).join('') + lines[i]);
|
||||
}
|
||||
return newArr.join('\n');
|
||||
}
|
||||
|
||||
function specFailureDetails(result) {
|
||||
printNewline();
|
||||
print(result.fullName);
|
||||
|
||||
for (var i = 0; i < result.failedExpectations.length; i++) {
|
||||
var failedExpectation = result.failedExpectations[i];
|
||||
printNewline();
|
||||
print(indent(failedExpectation.message, 2));
|
||||
print(indent(failedExpectation.stack, 2));
|
||||
}
|
||||
|
||||
printNewline();
|
||||
}
|
||||
|
||||
function suiteFailureDetails(result) {
|
||||
for (var i = 0; i < result.failedExpectations.length; i++) {
|
||||
printNewline();
|
||||
print(colored('red', 'An error was thrown in an afterAll'));
|
||||
printNewline();
|
||||
print(colored('red', 'AfterAll ' + result.failedExpectations[i].message));
|
||||
|
||||
}
|
||||
printNewline();
|
||||
}
|
||||
}
|
||||
|
||||
return ConsoleReporter;
|
||||
};
|
||||
37
lib/jasmine-core.js
Normal file
37
lib/jasmine-core.js
Normal file
@@ -0,0 +1,37 @@
|
||||
module.exports = require("./jasmine-core/jasmine.js");
|
||||
module.exports.boot = require('./jasmine-core/node_boot.js');
|
||||
|
||||
var path = require('path'),
|
||||
fs = require('fs');
|
||||
|
||||
var rootPath = path.join(__dirname, "jasmine-core"),
|
||||
bootFiles = ['boot.js'],
|
||||
nodeBootFiles = ['node_boot.js'],
|
||||
cssFiles = [],
|
||||
jsFiles = [],
|
||||
jsFilesToSkip = ['jasmine.js'].concat(bootFiles, nodeBootFiles);
|
||||
|
||||
fs.readdirSync(rootPath).forEach(function(file) {
|
||||
if(fs.statSync(path.join(rootPath, file)).isFile()) {
|
||||
switch(path.extname(file)) {
|
||||
case '.css':
|
||||
cssFiles.push(file);
|
||||
break;
|
||||
case '.js':
|
||||
if (jsFilesToSkip.indexOf(file) < 0) {
|
||||
jsFiles.push(file);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
module.exports.files = {
|
||||
path: rootPath,
|
||||
bootDir: rootPath,
|
||||
bootFiles: bootFiles,
|
||||
nodeBootFiles: nodeBootFiles,
|
||||
cssFiles: cssFiles,
|
||||
jsFiles: ['jasmine.js'].concat(jsFiles),
|
||||
imagesDir: path.join(__dirname, '../images')
|
||||
};
|
||||
@@ -6,12 +6,48 @@ module Jasmine
|
||||
end
|
||||
|
||||
def js_files
|
||||
(["jasmine.js"] + Dir.glob(File.join(path, "*.js"))).map { |f| File.basename(f) }.uniq
|
||||
(["jasmine.js"] + Dir.glob(File.join(path, "*.js"))).map { |f| File.basename(f) }.uniq - boot_files - node_boot_files
|
||||
end
|
||||
|
||||
SPEC_TYPES = ["core", "html", "node"]
|
||||
|
||||
def core_spec_files
|
||||
spec_files("core")
|
||||
end
|
||||
|
||||
def html_spec_files
|
||||
spec_files("html")
|
||||
end
|
||||
|
||||
def node_spec_files
|
||||
spec_files("node")
|
||||
end
|
||||
|
||||
def boot_files
|
||||
["boot.js"]
|
||||
end
|
||||
|
||||
def node_boot_files
|
||||
["node_boot.js"]
|
||||
end
|
||||
|
||||
def boot_dir
|
||||
path
|
||||
end
|
||||
|
||||
def spec_files(type)
|
||||
raise ArgumentError.new("Unrecognized spec type") unless SPEC_TYPES.include?(type)
|
||||
(Dir.glob(File.join(path, "spec", type, "*.js"))).map { |f| File.join("spec", type, File.basename(f)) }.uniq
|
||||
end
|
||||
|
||||
def css_files
|
||||
Dir.glob(File.join(path, "*.css")).map { |f| File.basename(f) }
|
||||
end
|
||||
|
||||
def images_dir
|
||||
File.join(File.dirname(__FILE__), '../images')
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
1
lib/jasmine-core/__init__.py
Normal file
1
lib/jasmine-core/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from .core import Core
|
||||
142
lib/jasmine-core/boot.js
Normal file
142
lib/jasmine-core/boot.js
Normal file
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
Copyright (c) 2008-2014 Pivotal Labs
|
||||
|
||||
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.
|
||||
*/
|
||||
/**
|
||||
Starting with version 2.0, this file "boots" Jasmine, performing all of the necessary initialization before executing the loaded environment and all of a project's specs. This file should be loaded after `jasmine.js` and `jasmine_html.js`, but before any project source files or spec files are loaded. Thus this file can also be used to customize Jasmine for a project.
|
||||
|
||||
If a project is using Jasmine via the standalone distribution, this file can be customized directly. If a project is using Jasmine via the [Ruby gem][jasmine-gem], this file can be copied into the support directory via `jasmine copy_boot_js`. Other environments (e.g., Python) will have different mechanisms.
|
||||
|
||||
The location of `boot.js` can be specified and/or overridden in `jasmine.yml`.
|
||||
|
||||
[jasmine-gem]: http://github.com/pivotal/jasmine-gem
|
||||
*/
|
||||
|
||||
(function() {
|
||||
|
||||
/**
|
||||
* ## Require & Instantiate
|
||||
*
|
||||
* Require Jasmine's core files. Specifically, this requires and attaches all of Jasmine's code to the `jasmine` reference.
|
||||
*/
|
||||
window.jasmine = jasmineRequire.core(jasmineRequire);
|
||||
|
||||
/**
|
||||
* Since this is being run in a browser and the results should populate to an HTML page, require the HTML-specific Jasmine code, injecting the same reference.
|
||||
*/
|
||||
jasmineRequire.html(jasmine);
|
||||
|
||||
/**
|
||||
* Create the Jasmine environment. This is used to run all specs in a project.
|
||||
*/
|
||||
var env = jasmine.getEnv();
|
||||
|
||||
/**
|
||||
* ## The Global Interface
|
||||
*
|
||||
* Build up the functions that will be exposed as the Jasmine public interface. A project can customize, rename or alias any of these functions as desired, provided the implementation remains unchanged.
|
||||
*/
|
||||
var jasmineInterface = jasmineRequire.interface(jasmine, env);
|
||||
|
||||
/**
|
||||
* Add all of the Jasmine global/public interface to the proper global, so a project can use the public interface directly. For example, calling `describe` in specs instead of `jasmine.getEnv().describe`.
|
||||
*/
|
||||
if (typeof window == "undefined" && typeof exports == "object") {
|
||||
extend(exports, jasmineInterface);
|
||||
} else {
|
||||
extend(window, jasmineInterface);
|
||||
}
|
||||
|
||||
/**
|
||||
* ## Runner Parameters
|
||||
*
|
||||
* More browser specific code - wrap the query string in an object and to allow for getting/setting parameters from the runner user interface.
|
||||
*/
|
||||
|
||||
var queryString = new jasmine.QueryString({
|
||||
getWindowLocation: function() { return window.location; }
|
||||
});
|
||||
|
||||
var catchingExceptions = queryString.getParam("catch");
|
||||
env.catchExceptions(typeof catchingExceptions === "undefined" ? true : catchingExceptions);
|
||||
|
||||
/**
|
||||
* ## Reporters
|
||||
* The `HtmlReporter` builds all of the HTML UI for the runner page. This reporter paints the dots, stars, and x's for specs, as well as all spec names and all failures (if any).
|
||||
*/
|
||||
var htmlReporter = new jasmine.HtmlReporter({
|
||||
env: env,
|
||||
onRaiseExceptionsClick: function() { queryString.setParam("catch", !env.catchingExceptions()); },
|
||||
getContainer: function() { return document.body; },
|
||||
createElement: function() { return document.createElement.apply(document, arguments); },
|
||||
createTextNode: function() { return document.createTextNode.apply(document, arguments); },
|
||||
timer: new jasmine.Timer()
|
||||
});
|
||||
|
||||
/**
|
||||
* The `jsApiReporter` also receives spec results, and is used by any environment that needs to extract the results from JavaScript.
|
||||
*/
|
||||
env.addReporter(jasmineInterface.jsApiReporter);
|
||||
env.addReporter(htmlReporter);
|
||||
|
||||
/**
|
||||
* Filter which specs will be run by matching the start of the full name against the `spec` query param.
|
||||
*/
|
||||
var specFilter = new jasmine.HtmlSpecFilter({
|
||||
filterString: function() { return queryString.getParam("spec"); }
|
||||
});
|
||||
|
||||
env.specFilter = function(spec) {
|
||||
return specFilter.matches(spec.getFullName());
|
||||
};
|
||||
|
||||
/**
|
||||
* Setting up timing functions to be able to be overridden. Certain browsers (Safari, IE 8, phantomjs) require this hack.
|
||||
*/
|
||||
window.setTimeout = window.setTimeout;
|
||||
window.setInterval = window.setInterval;
|
||||
window.clearTimeout = window.clearTimeout;
|
||||
window.clearInterval = window.clearInterval;
|
||||
|
||||
/**
|
||||
* ## Execution
|
||||
*
|
||||
* Replace the browser window's `onload`, ensure it's called, and then run all of the loaded specs. This includes initializing the `HtmlReporter` instance and then executing the loaded Jasmine environment. All of this will happen after all of the specs are loaded.
|
||||
*/
|
||||
var currentWindowOnload = window.onload;
|
||||
|
||||
window.onload = function() {
|
||||
if (currentWindowOnload) {
|
||||
currentWindowOnload();
|
||||
}
|
||||
htmlReporter.initialize();
|
||||
env.execute();
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper function for readability above.
|
||||
*/
|
||||
function extend(destination, source) {
|
||||
for (var property in source) destination[property] = source[property];
|
||||
return destination;
|
||||
}
|
||||
|
||||
}());
|
||||
120
lib/jasmine-core/boot/boot.js
Normal file
120
lib/jasmine-core/boot/boot.js
Normal file
@@ -0,0 +1,120 @@
|
||||
/**
|
||||
Starting with version 2.0, this file "boots" Jasmine, performing all of the necessary initialization before executing the loaded environment and all of a project's specs. This file should be loaded after `jasmine.js` and `jasmine_html.js`, but before any project source files or spec files are loaded. Thus this file can also be used to customize Jasmine for a project.
|
||||
|
||||
If a project is using Jasmine via the standalone distribution, this file can be customized directly. If a project is using Jasmine via the [Ruby gem][jasmine-gem], this file can be copied into the support directory via `jasmine copy_boot_js`. Other environments (e.g., Python) will have different mechanisms.
|
||||
|
||||
The location of `boot.js` can be specified and/or overridden in `jasmine.yml`.
|
||||
|
||||
[jasmine-gem]: http://github.com/pivotal/jasmine-gem
|
||||
*/
|
||||
|
||||
(function() {
|
||||
|
||||
/**
|
||||
* ## Require & Instantiate
|
||||
*
|
||||
* Require Jasmine's core files. Specifically, this requires and attaches all of Jasmine's code to the `jasmine` reference.
|
||||
*/
|
||||
window.jasmine = jasmineRequire.core(jasmineRequire);
|
||||
|
||||
/**
|
||||
* Since this is being run in a browser and the results should populate to an HTML page, require the HTML-specific Jasmine code, injecting the same reference.
|
||||
*/
|
||||
jasmineRequire.html(jasmine);
|
||||
|
||||
/**
|
||||
* Create the Jasmine environment. This is used to run all specs in a project.
|
||||
*/
|
||||
var env = jasmine.getEnv();
|
||||
|
||||
/**
|
||||
* ## The Global Interface
|
||||
*
|
||||
* Build up the functions that will be exposed as the Jasmine public interface. A project can customize, rename or alias any of these functions as desired, provided the implementation remains unchanged.
|
||||
*/
|
||||
var jasmineInterface = jasmineRequire.interface(jasmine, env);
|
||||
|
||||
/**
|
||||
* Add all of the Jasmine global/public interface to the proper global, so a project can use the public interface directly. For example, calling `describe` in specs instead of `jasmine.getEnv().describe`.
|
||||
*/
|
||||
if (typeof window == "undefined" && typeof exports == "object") {
|
||||
extend(exports, jasmineInterface);
|
||||
} else {
|
||||
extend(window, jasmineInterface);
|
||||
}
|
||||
|
||||
/**
|
||||
* ## Runner Parameters
|
||||
*
|
||||
* More browser specific code - wrap the query string in an object and to allow for getting/setting parameters from the runner user interface.
|
||||
*/
|
||||
|
||||
var queryString = new jasmine.QueryString({
|
||||
getWindowLocation: function() { return window.location; }
|
||||
});
|
||||
|
||||
var catchingExceptions = queryString.getParam("catch");
|
||||
env.catchExceptions(typeof catchingExceptions === "undefined" ? true : catchingExceptions);
|
||||
|
||||
/**
|
||||
* ## Reporters
|
||||
* The `HtmlReporter` builds all of the HTML UI for the runner page. This reporter paints the dots, stars, and x's for specs, as well as all spec names and all failures (if any).
|
||||
*/
|
||||
var htmlReporter = new jasmine.HtmlReporter({
|
||||
env: env,
|
||||
onRaiseExceptionsClick: function() { queryString.setParam("catch", !env.catchingExceptions()); },
|
||||
getContainer: function() { return document.body; },
|
||||
createElement: function() { return document.createElement.apply(document, arguments); },
|
||||
createTextNode: function() { return document.createTextNode.apply(document, arguments); },
|
||||
timer: new jasmine.Timer()
|
||||
});
|
||||
|
||||
/**
|
||||
* The `jsApiReporter` also receives spec results, and is used by any environment that needs to extract the results from JavaScript.
|
||||
*/
|
||||
env.addReporter(jasmineInterface.jsApiReporter);
|
||||
env.addReporter(htmlReporter);
|
||||
|
||||
/**
|
||||
* Filter which specs will be run by matching the start of the full name against the `spec` query param.
|
||||
*/
|
||||
var specFilter = new jasmine.HtmlSpecFilter({
|
||||
filterString: function() { return queryString.getParam("spec"); }
|
||||
});
|
||||
|
||||
env.specFilter = function(spec) {
|
||||
return specFilter.matches(spec.getFullName());
|
||||
};
|
||||
|
||||
/**
|
||||
* Setting up timing functions to be able to be overridden. Certain browsers (Safari, IE 8, phantomjs) require this hack.
|
||||
*/
|
||||
window.setTimeout = window.setTimeout;
|
||||
window.setInterval = window.setInterval;
|
||||
window.clearTimeout = window.clearTimeout;
|
||||
window.clearInterval = window.clearInterval;
|
||||
|
||||
/**
|
||||
* ## Execution
|
||||
*
|
||||
* Replace the browser window's `onload`, ensure it's called, and then run all of the loaded specs. This includes initializing the `HtmlReporter` instance and then executing the loaded Jasmine environment. All of this will happen after all of the specs are loaded.
|
||||
*/
|
||||
var currentWindowOnload = window.onload;
|
||||
|
||||
window.onload = function() {
|
||||
if (currentWindowOnload) {
|
||||
currentWindowOnload();
|
||||
}
|
||||
htmlReporter.initialize();
|
||||
env.execute();
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper function for readability above.
|
||||
*/
|
||||
function extend(destination, source) {
|
||||
for (var property in source) destination[property] = source[property];
|
||||
return destination;
|
||||
}
|
||||
|
||||
}());
|
||||
19
lib/jasmine-core/boot/node_boot.js
Normal file
19
lib/jasmine-core/boot/node_boot.js
Normal file
@@ -0,0 +1,19 @@
|
||||
module.exports = function(jasmineRequire) {
|
||||
var jasmine = jasmineRequire.core(jasmineRequire);
|
||||
|
||||
var consoleFns = require('../console/console.js');
|
||||
consoleFns.console(consoleFns, jasmine);
|
||||
|
||||
var env = jasmine.getEnv();
|
||||
|
||||
var jasmineInterface = jasmineRequire.interface(jasmine, env);
|
||||
|
||||
extend(global, jasmineInterface);
|
||||
|
||||
function extend(destination, source) {
|
||||
for (var property in source) destination[property] = source[property];
|
||||
return destination;
|
||||
}
|
||||
|
||||
return jasmine;
|
||||
};
|
||||
60
lib/jasmine-core/core.py
Normal file
60
lib/jasmine-core/core.py
Normal file
@@ -0,0 +1,60 @@
|
||||
import pkg_resources
|
||||
|
||||
try:
|
||||
from collections import OrderedDict
|
||||
except ImportError:
|
||||
from ordereddict import OrderedDict
|
||||
|
||||
class Core(object):
|
||||
@classmethod
|
||||
def js_package(cls):
|
||||
return __package__
|
||||
|
||||
@classmethod
|
||||
def css_package(cls):
|
||||
return __package__
|
||||
|
||||
@classmethod
|
||||
def image_package(cls):
|
||||
return __package__ + ".images"
|
||||
|
||||
@classmethod
|
||||
def js_files(cls):
|
||||
js_files = sorted(list(filter(lambda x: '.js' in x, pkg_resources.resource_listdir(cls.js_package(), '.'))))
|
||||
|
||||
# jasmine.js needs to be first
|
||||
js_files.insert(0, 'jasmine.js')
|
||||
|
||||
# boot needs to be last
|
||||
js_files.remove('boot.js')
|
||||
js_files.append('boot.js')
|
||||
|
||||
return cls._uniq(js_files)
|
||||
|
||||
@classmethod
|
||||
def css_files(cls):
|
||||
return cls._uniq(sorted(filter(lambda x: '.css' in x, pkg_resources.resource_listdir(cls.css_package(), '.'))))
|
||||
|
||||
@classmethod
|
||||
def favicon(cls):
|
||||
return 'jasmine_favicon.png'
|
||||
|
||||
@classmethod
|
||||
def _uniq(self, items, idfun=None):
|
||||
# order preserving
|
||||
|
||||
if idfun is None:
|
||||
def idfun(x): return x
|
||||
seen = {}
|
||||
result = []
|
||||
for item in items:
|
||||
marker = idfun(item)
|
||||
# in old Python versions:
|
||||
# if seen.has_key(marker)
|
||||
# but in new ones:
|
||||
if marker in seen:
|
||||
continue
|
||||
|
||||
seen[marker] = 1
|
||||
result.append(item)
|
||||
return result
|
||||
@@ -1,54 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
||||
"http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>Jasmine Spec Runner</title>
|
||||
|
||||
<link rel="shortcut icon" type="image/png" href="lib/jasmine-1.1.0.rc1/jasmine_favicon.png">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="lib/jasmine-1.1.0.rc1/jasmine.css">
|
||||
<script type="text/javascript" src="lib/jasmine-1.1.0.rc1/jasmine.js"></script>
|
||||
<script type="text/javascript" src="lib/jasmine-1.1.0.rc1/jasmine-html.js"></script>
|
||||
|
||||
<!-- include source files here... -->
|
||||
<script type="text/javascript" src="spec/SpecHelper.js"></script>
|
||||
<script type="text/javascript" src="spec/PlayerSpec.js"></script>
|
||||
|
||||
<!-- include spec files here... -->
|
||||
<script type="text/javascript" src="src/Player.js"></script>
|
||||
<script type="text/javascript" src="src/Song.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
(function() {
|
||||
var jasmineEnv = jasmine.getEnv();
|
||||
jasmineEnv.updateInterval = 1000;
|
||||
|
||||
var trivialReporter = new jasmine.TrivialReporter();
|
||||
|
||||
jasmineEnv.addReporter(trivialReporter);
|
||||
|
||||
jasmineEnv.specFilter = function(spec) {
|
||||
return trivialReporter.specFilter(spec);
|
||||
};
|
||||
|
||||
var currentWindowOnload = window.onload;
|
||||
|
||||
window.onload = function() {
|
||||
if (currentWindowOnload) {
|
||||
currentWindowOnload();
|
||||
}
|
||||
execJasmine();
|
||||
};
|
||||
|
||||
function execJasmine() {
|
||||
jasmineEnv.execute();
|
||||
}
|
||||
|
||||
})();
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
60
lib/jasmine-core/example/node_example/spec/PlayerSpec.js
Normal file
60
lib/jasmine-core/example/node_example/spec/PlayerSpec.js
Normal file
@@ -0,0 +1,60 @@
|
||||
describe("Player", function() {
|
||||
var Player = require('../src/Player.js');
|
||||
var Song = require('../src/Song.js');
|
||||
var player;
|
||||
var song;
|
||||
|
||||
beforeEach(function() {
|
||||
player = new Player();
|
||||
song = new Song();
|
||||
});
|
||||
|
||||
it("should be able to play a Song", function() {
|
||||
player.play(song);
|
||||
expect(player.currentlyPlayingSong).toEqual(song);
|
||||
|
||||
//demonstrates use of custom matcher
|
||||
expect(player).toBePlaying(song);
|
||||
});
|
||||
|
||||
describe("when song has been paused", function() {
|
||||
beforeEach(function() {
|
||||
player.play(song);
|
||||
player.pause();
|
||||
});
|
||||
|
||||
it("should indicate that the song is currently paused", function() {
|
||||
expect(player.isPlaying).toBeFalsy();
|
||||
|
||||
// demonstrates use of 'not' with a custom matcher
|
||||
expect(player).not.toBePlaying(song);
|
||||
});
|
||||
|
||||
it("should be possible to resume", function() {
|
||||
player.resume();
|
||||
expect(player.isPlaying).toBeTruthy();
|
||||
expect(player.currentlyPlayingSong).toEqual(song);
|
||||
});
|
||||
});
|
||||
|
||||
// demonstrates use of spies to intercept and test method calls
|
||||
it("tells the current song if the user has made it a favorite", function() {
|
||||
spyOn(song, 'persistFavoriteStatus');
|
||||
|
||||
player.play(song);
|
||||
player.makeFavorite();
|
||||
|
||||
expect(song.persistFavoriteStatus).toHaveBeenCalledWith(true);
|
||||
});
|
||||
|
||||
//demonstrates use of expected exceptions
|
||||
describe("#resume", function() {
|
||||
it("should throw an exception if song is already playing", function() {
|
||||
player.play(song);
|
||||
|
||||
expect(function() {
|
||||
player.resume();
|
||||
}).toThrowError("song is already playing");
|
||||
});
|
||||
});
|
||||
});
|
||||
15
lib/jasmine-core/example/node_example/spec/SpecHelper.js
Normal file
15
lib/jasmine-core/example/node_example/spec/SpecHelper.js
Normal file
@@ -0,0 +1,15 @@
|
||||
beforeEach(function () {
|
||||
jasmine.addMatchers({
|
||||
toBePlaying: function () {
|
||||
return {
|
||||
compare: function (actual, expected) {
|
||||
var player = actual;
|
||||
|
||||
return {
|
||||
pass: player.currentlyPlayingSong === expected && player.isPlaying
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
});
|
||||
24
lib/jasmine-core/example/node_example/src/Player.js
Normal file
24
lib/jasmine-core/example/node_example/src/Player.js
Normal file
@@ -0,0 +1,24 @@
|
||||
function Player() {
|
||||
}
|
||||
Player.prototype.play = function(song) {
|
||||
this.currentlyPlayingSong = song;
|
||||
this.isPlaying = true;
|
||||
};
|
||||
|
||||
Player.prototype.pause = function() {
|
||||
this.isPlaying = false;
|
||||
};
|
||||
|
||||
Player.prototype.resume = function() {
|
||||
if (this.isPlaying) {
|
||||
throw new Error("song is already playing");
|
||||
}
|
||||
|
||||
this.isPlaying = true;
|
||||
};
|
||||
|
||||
Player.prototype.makeFavorite = function() {
|
||||
this.currentlyPlayingSong.persistFavoriteStatus(true);
|
||||
};
|
||||
|
||||
module.exports = Player;
|
||||
9
lib/jasmine-core/example/node_example/src/Song.js
Normal file
9
lib/jasmine-core/example/node_example/src/Song.js
Normal file
@@ -0,0 +1,9 @@
|
||||
function Song() {
|
||||
}
|
||||
|
||||
Song.prototype.persistFavoriteStatus = function(value) {
|
||||
// something complicated
|
||||
throw new Error("not yet implemented");
|
||||
};
|
||||
|
||||
module.exports = Song;
|
||||
@@ -52,7 +52,7 @@ describe("Player", function() {
|
||||
|
||||
expect(function() {
|
||||
player.resume();
|
||||
}).toThrow("song is already playing");
|
||||
}).toThrowError("song is already playing");
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
beforeEach(function() {
|
||||
this.addMatchers({
|
||||
toBePlaying: function(expectedSong) {
|
||||
var player = this.actual;
|
||||
return player.currentlyPlayingSong === expectedSong &&
|
||||
player.isPlaying;
|
||||
beforeEach(function () {
|
||||
jasmine.addMatchers({
|
||||
toBePlaying: function () {
|
||||
return {
|
||||
compare: function (actual, expected) {
|
||||
var player = actual;
|
||||
|
||||
return {
|
||||
pass: player.currentlyPlayingSong === expected && player.isPlaying
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,190 +1,404 @@
|
||||
jasmine.TrivialReporter = function(doc) {
|
||||
this.document = doc || document;
|
||||
this.suiteDivs = {};
|
||||
this.logRunningSpecs = false;
|
||||
/*
|
||||
Copyright (c) 2008-2014 Pivotal Labs
|
||||
|
||||
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.
|
||||
*/
|
||||
jasmineRequire.html = function(j$) {
|
||||
j$.ResultsNode = jasmineRequire.ResultsNode();
|
||||
j$.HtmlReporter = jasmineRequire.HtmlReporter(j$);
|
||||
j$.QueryString = jasmineRequire.QueryString();
|
||||
j$.HtmlSpecFilter = jasmineRequire.HtmlSpecFilter();
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.createDom = function(type, attrs, childrenVarArgs) {
|
||||
var el = document.createElement(type);
|
||||
jasmineRequire.HtmlReporter = function(j$) {
|
||||
|
||||
for (var i = 2; i < arguments.length; i++) {
|
||||
var child = arguments[i];
|
||||
var noopTimer = {
|
||||
start: function() {},
|
||||
elapsed: function() { return 0; }
|
||||
};
|
||||
|
||||
if (typeof child === 'string') {
|
||||
el.appendChild(document.createTextNode(child));
|
||||
} else {
|
||||
if (child) { el.appendChild(child); }
|
||||
}
|
||||
}
|
||||
function HtmlReporter(options) {
|
||||
var env = options.env || {},
|
||||
getContainer = options.getContainer,
|
||||
createElement = options.createElement,
|
||||
createTextNode = options.createTextNode,
|
||||
onRaiseExceptionsClick = options.onRaiseExceptionsClick || function() {},
|
||||
timer = options.timer || noopTimer,
|
||||
results = [],
|
||||
specsExecuted = 0,
|
||||
failureCount = 0,
|
||||
pendingSpecCount = 0,
|
||||
htmlReporterMain,
|
||||
symbols,
|
||||
failedSuites = [];
|
||||
|
||||
for (var attr in attrs) {
|
||||
if (attr == "className") {
|
||||
el[attr] = attrs[attr];
|
||||
} else {
|
||||
el.setAttribute(attr, attrs[attr]);
|
||||
}
|
||||
}
|
||||
|
||||
return el;
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) {
|
||||
var showPassed, showSkipped;
|
||||
|
||||
this.outerDiv = this.createDom('div', { className: 'jasmine_reporter' },
|
||||
this.createDom('div', { className: 'banner' },
|
||||
this.createDom('div', { className: 'logo' },
|
||||
this.createDom('span', { className: 'title' }, "Jasmine"),
|
||||
this.createDom('span', { className: 'version' }, runner.env.versionString())),
|
||||
this.createDom('div', { className: 'options' },
|
||||
"Show ",
|
||||
showPassed = this.createDom('input', { id: "__jasmine_TrivialReporter_showPassed__", type: 'checkbox' }),
|
||||
this.createDom('label', { "for": "__jasmine_TrivialReporter_showPassed__" }, " passed "),
|
||||
showSkipped = this.createDom('input', { id: "__jasmine_TrivialReporter_showSkipped__", type: 'checkbox' }),
|
||||
this.createDom('label', { "for": "__jasmine_TrivialReporter_showSkipped__" }, " skipped")
|
||||
)
|
||||
),
|
||||
|
||||
this.runnerDiv = this.createDom('div', { className: 'runner running' },
|
||||
this.createDom('a', { className: 'run_spec', href: '?' }, "run all"),
|
||||
this.runnerMessageSpan = this.createDom('span', {}, "Running..."),
|
||||
this.finishedAtSpan = this.createDom('span', { className: 'finished-at' }, ""))
|
||||
this.initialize = function() {
|
||||
clearPrior();
|
||||
htmlReporterMain = createDom('div', {className: 'jasmine_html-reporter'},
|
||||
createDom('div', {className: 'banner'},
|
||||
createDom('a', {className: 'title', href: 'http://jasmine.github.io/', target: '_blank'}),
|
||||
createDom('span', {className: 'version'}, j$.version)
|
||||
),
|
||||
createDom('ul', {className: 'symbol-summary'}),
|
||||
createDom('div', {className: 'alert'}),
|
||||
createDom('div', {className: 'results'},
|
||||
createDom('div', {className: 'failures'})
|
||||
)
|
||||
);
|
||||
getContainer().appendChild(htmlReporterMain);
|
||||
|
||||
this.document.body.appendChild(this.outerDiv);
|
||||
symbols = find('.symbol-summary');
|
||||
};
|
||||
|
||||
var suites = runner.suites();
|
||||
for (var i = 0; i < suites.length; i++) {
|
||||
var suite = suites[i];
|
||||
var suiteDiv = this.createDom('div', { className: 'suite' },
|
||||
this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, "run"),
|
||||
this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, suite.description));
|
||||
this.suiteDivs[suite.id] = suiteDiv;
|
||||
var parentDiv = this.outerDiv;
|
||||
if (suite.parentSuite) {
|
||||
parentDiv = this.suiteDivs[suite.parentSuite.id];
|
||||
var totalSpecsDefined;
|
||||
this.jasmineStarted = function(options) {
|
||||
totalSpecsDefined = options.totalSpecsDefined || 0;
|
||||
timer.start();
|
||||
};
|
||||
|
||||
var summary = createDom('div', {className: 'summary'});
|
||||
|
||||
var topResults = new j$.ResultsNode({}, '', null),
|
||||
currentParent = topResults;
|
||||
|
||||
this.suiteStarted = function(result) {
|
||||
currentParent.addChild(result, 'suite');
|
||||
currentParent = currentParent.last();
|
||||
};
|
||||
|
||||
this.suiteDone = function(result) {
|
||||
if (result.status == 'failed') {
|
||||
failedSuites.push(result);
|
||||
}
|
||||
|
||||
if (currentParent == topResults) {
|
||||
return;
|
||||
}
|
||||
|
||||
currentParent = currentParent.parent;
|
||||
};
|
||||
|
||||
this.specStarted = function(result) {
|
||||
currentParent.addChild(result, 'spec');
|
||||
};
|
||||
|
||||
var failures = [];
|
||||
this.specDone = function(result) {
|
||||
if(noExpectations(result) && typeof console !== 'undefined' && typeof console.error !== 'undefined') {
|
||||
console.error('Spec \'' + result.fullName + '\' has no expectations.');
|
||||
}
|
||||
|
||||
if (result.status != 'disabled') {
|
||||
specsExecuted++;
|
||||
}
|
||||
|
||||
symbols.appendChild(createDom('li', {
|
||||
className: noExpectations(result) ? 'empty' : result.status,
|
||||
id: 'spec_' + result.id,
|
||||
title: result.fullName
|
||||
}
|
||||
));
|
||||
|
||||
if (result.status == 'failed') {
|
||||
failureCount++;
|
||||
|
||||
var failure =
|
||||
createDom('div', {className: 'spec-detail failed'},
|
||||
createDom('div', {className: 'description'},
|
||||
createDom('a', {title: result.fullName, href: specHref(result)}, result.fullName)
|
||||
),
|
||||
createDom('div', {className: 'messages'})
|
||||
);
|
||||
var messages = failure.childNodes[1];
|
||||
|
||||
for (var i = 0; i < result.failedExpectations.length; i++) {
|
||||
var expectation = result.failedExpectations[i];
|
||||
messages.appendChild(createDom('div', {className: 'result-message'}, expectation.message));
|
||||
messages.appendChild(createDom('div', {className: 'stack-trace'}, expectation.stack));
|
||||
}
|
||||
|
||||
failures.push(failure);
|
||||
}
|
||||
|
||||
if (result.status == 'pending') {
|
||||
pendingSpecCount++;
|
||||
}
|
||||
};
|
||||
|
||||
this.jasmineDone = function() {
|
||||
var banner = find('.banner');
|
||||
banner.appendChild(createDom('span', {className: 'duration'}, 'finished in ' + timer.elapsed() / 1000 + 's'));
|
||||
|
||||
var alert = find('.alert');
|
||||
|
||||
alert.appendChild(createDom('span', { className: 'exceptions' },
|
||||
createDom('label', { className: 'label', 'for': 'raise-exceptions' }, 'raise exceptions'),
|
||||
createDom('input', {
|
||||
className: 'raise',
|
||||
id: 'raise-exceptions',
|
||||
type: 'checkbox'
|
||||
})
|
||||
));
|
||||
var checkbox = find('#raise-exceptions');
|
||||
|
||||
checkbox.checked = !env.catchingExceptions();
|
||||
checkbox.onclick = onRaiseExceptionsClick;
|
||||
|
||||
if (specsExecuted < totalSpecsDefined) {
|
||||
var skippedMessage = 'Ran ' + specsExecuted + ' of ' + totalSpecsDefined + ' specs - run all';
|
||||
alert.appendChild(
|
||||
createDom('span', {className: 'bar skipped'},
|
||||
createDom('a', {href: '?', title: 'Run all specs'}, skippedMessage)
|
||||
)
|
||||
);
|
||||
}
|
||||
var statusBarMessage = '';
|
||||
var statusBarClassName = 'bar ';
|
||||
|
||||
if (totalSpecsDefined > 0) {
|
||||
statusBarMessage += pluralize('spec', specsExecuted) + ', ' + pluralize('failure', failureCount);
|
||||
if (pendingSpecCount) { statusBarMessage += ', ' + pluralize('pending spec', pendingSpecCount); }
|
||||
statusBarClassName += (failureCount > 0) ? 'failed' : 'passed';
|
||||
} else {
|
||||
statusBarClassName += 'skipped';
|
||||
statusBarMessage += 'No specs found';
|
||||
}
|
||||
|
||||
alert.appendChild(createDom('span', {className: statusBarClassName}, statusBarMessage));
|
||||
|
||||
for(i = 0; i < failedSuites.length; i++) {
|
||||
var failedSuite = failedSuites[i];
|
||||
for(var j = 0; j < failedSuite.failedExpectations.length; j++) {
|
||||
var errorBarMessage = 'AfterAll ' + failedSuite.failedExpectations[j].message;
|
||||
var errorBarClassName = 'bar errored';
|
||||
alert.appendChild(createDom('span', {className: errorBarClassName}, errorBarMessage));
|
||||
}
|
||||
}
|
||||
|
||||
var results = find('.results');
|
||||
results.appendChild(summary);
|
||||
|
||||
summaryList(topResults, summary);
|
||||
|
||||
function summaryList(resultsTree, domParent) {
|
||||
var specListNode;
|
||||
for (var i = 0; i < resultsTree.children.length; i++) {
|
||||
var resultNode = resultsTree.children[i];
|
||||
if (resultNode.type == 'suite') {
|
||||
var suiteListNode = createDom('ul', {className: 'suite', id: 'suite-' + resultNode.result.id},
|
||||
createDom('li', {className: 'suite-detail'},
|
||||
createDom('a', {href: specHref(resultNode.result)}, resultNode.result.description)
|
||||
)
|
||||
);
|
||||
|
||||
summaryList(resultNode, suiteListNode);
|
||||
domParent.appendChild(suiteListNode);
|
||||
}
|
||||
if (resultNode.type == 'spec') {
|
||||
if (domParent.getAttribute('class') != 'specs') {
|
||||
specListNode = createDom('ul', {className: 'specs'});
|
||||
domParent.appendChild(specListNode);
|
||||
}
|
||||
var specDescription = resultNode.result.description;
|
||||
if(noExpectations(resultNode.result)) {
|
||||
specDescription = 'SPEC HAS NO EXPECTATIONS ' + specDescription;
|
||||
}
|
||||
specListNode.appendChild(
|
||||
createDom('li', {
|
||||
className: resultNode.result.status,
|
||||
id: 'spec-' + resultNode.result.id
|
||||
},
|
||||
createDom('a', {href: specHref(resultNode.result)}, specDescription)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (failures.length) {
|
||||
alert.appendChild(
|
||||
createDom('span', {className: 'menu bar spec-list'},
|
||||
createDom('span', {}, 'Spec List | '),
|
||||
createDom('a', {className: 'failures-menu', href: '#'}, 'Failures')));
|
||||
alert.appendChild(
|
||||
createDom('span', {className: 'menu bar failure-list'},
|
||||
createDom('a', {className: 'spec-list-menu', href: '#'}, 'Spec List'),
|
||||
createDom('span', {}, ' | Failures ')));
|
||||
|
||||
find('.failures-menu').onclick = function() {
|
||||
setMenuModeTo('failure-list');
|
||||
};
|
||||
find('.spec-list-menu').onclick = function() {
|
||||
setMenuModeTo('spec-list');
|
||||
};
|
||||
|
||||
setMenuModeTo('failure-list');
|
||||
|
||||
var failureNode = find('.failures');
|
||||
for (var i = 0; i < failures.length; i++) {
|
||||
failureNode.appendChild(failures[i]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return this;
|
||||
|
||||
function find(selector) {
|
||||
return getContainer().querySelector('.jasmine_html-reporter ' + selector);
|
||||
}
|
||||
parentDiv.appendChild(suiteDiv);
|
||||
}
|
||||
|
||||
this.startedAt = new Date();
|
||||
|
||||
var self = this;
|
||||
showPassed.onclick = function(evt) {
|
||||
if (showPassed.checked) {
|
||||
self.outerDiv.className += ' show-passed';
|
||||
} else {
|
||||
self.outerDiv.className = self.outerDiv.className.replace(/ show-passed/, '');
|
||||
}
|
||||
};
|
||||
|
||||
showSkipped.onclick = function(evt) {
|
||||
if (showSkipped.checked) {
|
||||
self.outerDiv.className += ' show-skipped';
|
||||
} else {
|
||||
self.outerDiv.className = self.outerDiv.className.replace(/ show-skipped/, '');
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.reportRunnerResults = function(runner) {
|
||||
var results = runner.results();
|
||||
var className = (results.failedCount > 0) ? "runner failed" : "runner passed";
|
||||
this.runnerDiv.setAttribute("class", className);
|
||||
//do it twice for IE
|
||||
this.runnerDiv.setAttribute("className", className);
|
||||
var specs = runner.specs();
|
||||
var specCount = 0;
|
||||
for (var i = 0; i < specs.length; i++) {
|
||||
if (this.specFilter(specs[i])) {
|
||||
specCount++;
|
||||
}
|
||||
}
|
||||
var message = "" + specCount + " spec" + (specCount == 1 ? "" : "s" ) + ", " + results.failedCount + " failure" + ((results.failedCount == 1) ? "" : "s");
|
||||
message += " in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s";
|
||||
this.runnerMessageSpan.replaceChild(this.createDom('a', { className: 'description', href: '?'}, message), this.runnerMessageSpan.firstChild);
|
||||
|
||||
this.finishedAtSpan.appendChild(document.createTextNode("Finished at " + new Date().toString()));
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.reportSuiteResults = function(suite) {
|
||||
var results = suite.results();
|
||||
var status = results.passed() ? 'passed' : 'failed';
|
||||
if (results.totalCount === 0) { // todo: change this to check results.skipped
|
||||
status = 'skipped';
|
||||
}
|
||||
this.suiteDivs[suite.id].className += " " + status;
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.reportSpecStarting = function(spec) {
|
||||
if (this.logRunningSpecs) {
|
||||
this.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');
|
||||
}
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.reportSpecResults = function(spec) {
|
||||
var results = spec.results();
|
||||
var status = results.passed() ? 'passed' : 'failed';
|
||||
if (results.skipped) {
|
||||
status = 'skipped';
|
||||
}
|
||||
var specDiv = this.createDom('div', { className: 'spec ' + status },
|
||||
this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(spec.getFullName()) }, "run"),
|
||||
this.createDom('a', {
|
||||
className: 'description',
|
||||
href: '?spec=' + encodeURIComponent(spec.getFullName()),
|
||||
title: spec.getFullName()
|
||||
}, spec.description));
|
||||
|
||||
|
||||
var resultItems = results.getItems();
|
||||
var messagesDiv = this.createDom('div', { className: 'messages' });
|
||||
for (var i = 0; i < resultItems.length; i++) {
|
||||
var result = resultItems[i];
|
||||
|
||||
if (result.type == 'log') {
|
||||
messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString()));
|
||||
} else if (result.type == 'expect' && result.passed && !result.passed()) {
|
||||
messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message));
|
||||
|
||||
if (result.trace.stack) {
|
||||
messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack));
|
||||
function clearPrior() {
|
||||
// return the reporter
|
||||
var oldReporter = find('');
|
||||
|
||||
if(oldReporter) {
|
||||
getContainer().removeChild(oldReporter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (messagesDiv.childNodes.length > 0) {
|
||||
specDiv.appendChild(messagesDiv);
|
||||
}
|
||||
function createDom(type, attrs, childrenVarArgs) {
|
||||
var el = createElement(type);
|
||||
|
||||
this.suiteDivs[spec.suite.id].appendChild(specDiv);
|
||||
};
|
||||
for (var i = 2; i < arguments.length; i++) {
|
||||
var child = arguments[i];
|
||||
|
||||
jasmine.TrivialReporter.prototype.log = function() {
|
||||
var console = jasmine.getGlobal().console;
|
||||
if (console && console.log) {
|
||||
if (console.log.apply) {
|
||||
console.log.apply(console, arguments);
|
||||
} else {
|
||||
console.log(arguments); // ie fix: console.log.apply doesn't exist on ie
|
||||
if (typeof child === 'string') {
|
||||
el.appendChild(createTextNode(child));
|
||||
} else {
|
||||
if (child) {
|
||||
el.appendChild(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var attr in attrs) {
|
||||
if (attr == 'className') {
|
||||
el[attr] = attrs[attr];
|
||||
} else {
|
||||
el.setAttribute(attr, attrs[attr]);
|
||||
}
|
||||
}
|
||||
|
||||
return el;
|
||||
}
|
||||
|
||||
function pluralize(singular, count) {
|
||||
var word = (count == 1 ? singular : singular + 's');
|
||||
|
||||
return '' + count + ' ' + word;
|
||||
}
|
||||
|
||||
function specHref(result) {
|
||||
return '?spec=' + encodeURIComponent(result.fullName);
|
||||
}
|
||||
|
||||
function setMenuModeTo(mode) {
|
||||
htmlReporterMain.setAttribute('class', 'jasmine_html-reporter ' + mode);
|
||||
}
|
||||
|
||||
function noExpectations(result) {
|
||||
return (result.failedExpectations.length + result.passedExpectations.length) === 0 &&
|
||||
result.status === 'passed';
|
||||
}
|
||||
}
|
||||
|
||||
return HtmlReporter;
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.getLocation = function() {
|
||||
return this.document.location;
|
||||
};
|
||||
jasmineRequire.HtmlSpecFilter = function() {
|
||||
function HtmlSpecFilter(options) {
|
||||
var filterString = options && options.filterString() && options.filterString().replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
|
||||
var filterPattern = new RegExp(filterString);
|
||||
|
||||
jasmine.TrivialReporter.prototype.specFilter = function(spec) {
|
||||
var paramMap = {};
|
||||
var params = this.getLocation().search.substring(1).split('&');
|
||||
for (var i = 0; i < params.length; i++) {
|
||||
var p = params[i].split('=');
|
||||
paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
|
||||
this.matches = function(specName) {
|
||||
return filterPattern.test(specName);
|
||||
};
|
||||
}
|
||||
|
||||
if (!paramMap.spec) {
|
||||
return true;
|
||||
}
|
||||
return spec.getFullName().indexOf(paramMap.spec) === 0;
|
||||
return HtmlSpecFilter;
|
||||
};
|
||||
|
||||
jasmineRequire.ResultsNode = function() {
|
||||
function ResultsNode(result, type, parent) {
|
||||
this.result = result;
|
||||
this.type = type;
|
||||
this.parent = parent;
|
||||
|
||||
this.children = [];
|
||||
|
||||
this.addChild = function(result, type) {
|
||||
this.children.push(new ResultsNode(result, type, this));
|
||||
};
|
||||
|
||||
this.last = function() {
|
||||
return this.children[this.children.length - 1];
|
||||
};
|
||||
}
|
||||
|
||||
return ResultsNode;
|
||||
};
|
||||
|
||||
jasmineRequire.QueryString = function() {
|
||||
function QueryString(options) {
|
||||
|
||||
this.setParam = function(key, value) {
|
||||
var paramMap = queryStringToParamMap();
|
||||
paramMap[key] = value;
|
||||
options.getWindowLocation().search = toQueryString(paramMap);
|
||||
};
|
||||
|
||||
this.getParam = function(key) {
|
||||
return queryStringToParamMap()[key];
|
||||
};
|
||||
|
||||
return this;
|
||||
|
||||
function toQueryString(paramMap) {
|
||||
var qStrPairs = [];
|
||||
for (var prop in paramMap) {
|
||||
qStrPairs.push(encodeURIComponent(prop) + '=' + encodeURIComponent(paramMap[prop]));
|
||||
}
|
||||
return '?' + qStrPairs.join('&');
|
||||
}
|
||||
|
||||
function queryStringToParamMap() {
|
||||
var paramStr = options.getWindowLocation().search.substring(1),
|
||||
params = [],
|
||||
paramMap = {};
|
||||
|
||||
if (paramStr.length > 0) {
|
||||
params = paramStr.split('&');
|
||||
for (var i = 0; i < params.length; i++) {
|
||||
var p = params[i].split('=');
|
||||
var value = decodeURIComponent(p[1]);
|
||||
if (value === 'true' || value === 'false') {
|
||||
value = JSON.parse(value);
|
||||
}
|
||||
paramMap[decodeURIComponent(p[0])] = value;
|
||||
}
|
||||
}
|
||||
|
||||
return paramMap;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return QueryString;
|
||||
};
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
http://www.JSON.org/json2.js
|
||||
2009-08-17
|
||||
json2.js
|
||||
2014-02-04
|
||||
|
||||
Public Domain.
|
||||
|
||||
@@ -8,6 +8,14 @@
|
||||
|
||||
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.
|
||||
|
||||
@@ -136,15 +144,9 @@
|
||||
|
||||
This is a reference implementation. You are free to copy, modify, or
|
||||
redistribute.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/*jslint evil: true */
|
||||
/*jslint evil: true, regexp: true */
|
||||
|
||||
/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
|
||||
call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
|
||||
@@ -153,16 +155,16 @@
|
||||
test, toJSON, toString, valueOf
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
// 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 = {};
|
||||
if (typeof JSON !== 'object') {
|
||||
JSON = {};
|
||||
}
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
function f(n) {
|
||||
// Format integers to have at least two digits.
|
||||
@@ -171,37 +173,30 @@ if (!this.JSON) {
|
||||
|
||||
if (typeof Date.prototype.toJSON !== 'function') {
|
||||
|
||||
Date.prototype.toJSON = function (key) {
|
||||
Date.prototype.toJSON = function () {
|
||||
|
||||
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;
|
||||
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();
|
||||
};
|
||||
String.prototype.toJSON =
|
||||
Number.prototype.toJSON =
|
||||
Boolean.prototype.toJSON = function () {
|
||||
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,
|
||||
var cx,
|
||||
escapable,
|
||||
gap,
|
||||
indent,
|
||||
meta = { // table of character substitutions
|
||||
'\b': '\\b',
|
||||
'\t': '\\t',
|
||||
'\n': '\\n',
|
||||
'\f': '\\f',
|
||||
'\r': '\\r',
|
||||
'"' : '\\"',
|
||||
'\\': '\\\\'
|
||||
},
|
||||
meta,
|
||||
rep;
|
||||
|
||||
|
||||
@@ -213,17 +208,17 @@ if (!this.JSON) {
|
||||
// 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 + '"';
|
||||
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.
|
||||
@@ -301,11 +296,11 @@ if (!this.JSON) {
|
||||
// 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(',') + ']';
|
||||
v = partial.length === 0
|
||||
? '[]'
|
||||
: gap
|
||||
? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']'
|
||||
: '[' + partial.join(',') + ']';
|
||||
gap = mind;
|
||||
return v;
|
||||
}
|
||||
@@ -315,8 +310,8 @@ if (!this.JSON) {
|
||||
if (rep && typeof rep === 'object') {
|
||||
length = rep.length;
|
||||
for (i = 0; i < length; i += 1) {
|
||||
k = rep[i];
|
||||
if (typeof k === 'string') {
|
||||
if (typeof rep[i] === 'string') {
|
||||
k = rep[i];
|
||||
v = str(k, value);
|
||||
if (v) {
|
||||
partial.push(quote(k) + (gap ? ': ' : ':') + v);
|
||||
@@ -328,7 +323,7 @@ if (!this.JSON) {
|
||||
// Otherwise, iterate through all of the keys in the object.
|
||||
|
||||
for (k in value) {
|
||||
if (Object.hasOwnProperty.call(value, k)) {
|
||||
if (Object.prototype.hasOwnProperty.call(value, k)) {
|
||||
v = str(k, value);
|
||||
if (v) {
|
||||
partial.push(quote(k) + (gap ? ': ' : ':') + v);
|
||||
@@ -340,9 +335,11 @@ if (!this.JSON) {
|
||||
// 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(',') + '}';
|
||||
v = partial.length === 0
|
||||
? '{}'
|
||||
: gap
|
||||
? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}'
|
||||
: '{' + partial.join(',') + '}';
|
||||
gap = mind;
|
||||
return v;
|
||||
}
|
||||
@@ -351,7 +348,18 @@ if (!this.JSON) {
|
||||
// If the JSON object does not yet have a stringify method, give it one.
|
||||
|
||||
if (typeof JSON.stringify !== 'function') {
|
||||
escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
|
||||
meta = { // table of character substitutions
|
||||
'\b': '\\b',
|
||||
'\t': '\\t',
|
||||
'\n': '\\n',
|
||||
'\f': '\\f',
|
||||
'\r': '\\r',
|
||||
'"' : '\\"',
|
||||
'\\': '\\\\'
|
||||
};
|
||||
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.
|
||||
@@ -382,7 +390,7 @@ if (!this.JSON) {
|
||||
rep = replacer;
|
||||
if (replacer && typeof replacer !== 'function' &&
|
||||
(typeof replacer !== 'object' ||
|
||||
typeof replacer.length !== 'number')) {
|
||||
typeof replacer.length !== 'number')) {
|
||||
throw new Error('JSON.stringify');
|
||||
}
|
||||
|
||||
@@ -397,6 +405,7 @@ if (!this.JSON) {
|
||||
// If the JSON object does not yet have a parse method, give it one.
|
||||
|
||||
if (typeof JSON.parse !== 'function') {
|
||||
cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
|
||||
JSON.parse = function (text, reviver) {
|
||||
|
||||
// The parse method takes a text and an optional reviver function, and returns
|
||||
@@ -412,7 +421,7 @@ if (!this.JSON) {
|
||||
var k, v, value = holder[key];
|
||||
if (value && typeof value === 'object') {
|
||||
for (k in value) {
|
||||
if (Object.hasOwnProperty.call(value, k)) {
|
||||
if (Object.prototype.hasOwnProperty.call(value, k)) {
|
||||
v = walk(value, k);
|
||||
if (v !== undefined) {
|
||||
value[k] = v;
|
||||
@@ -430,6 +439,7 @@ if (!this.JSON) {
|
||||
// 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) {
|
||||
@@ -451,10 +461,10 @@ if (!this.JSON) {
|
||||
// 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, ''))) {
|
||||
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
|
||||
@@ -466,8 +476,9 @@ replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
|
||||
// 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;
|
||||
return typeof reviver === 'function'
|
||||
? walk({'': j}, '')
|
||||
: j;
|
||||
}
|
||||
|
||||
// If the text is not JSON parseable, then a SyntaxError is thrown.
|
||||
|
||||
41
lib/jasmine-core/node_boot.js
Normal file
41
lib/jasmine-core/node_boot.js
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
Copyright (c) 2008-2014 Pivotal Labs
|
||||
|
||||
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.
|
||||
*/
|
||||
module.exports = function(jasmineRequire) {
|
||||
var jasmine = jasmineRequire.core(jasmineRequire);
|
||||
|
||||
var consoleFns = require('../console/console.js');
|
||||
consoleFns.console(consoleFns, jasmine);
|
||||
|
||||
var env = jasmine.getEnv();
|
||||
|
||||
var jasmineInterface = jasmineRequire.interface(jasmine, env);
|
||||
|
||||
extend(global, jasmineInterface);
|
||||
|
||||
function extend(destination, source) {
|
||||
for (var property in source) destination[property] = source[property];
|
||||
return destination;
|
||||
}
|
||||
|
||||
return jasmine;
|
||||
};
|
||||
1
lib/jasmine-core/spec
Symbolic link
1
lib/jasmine-core/spec
Symbolic link
@@ -0,0 +1 @@
|
||||
../../spec
|
||||
@@ -1,8 +1,9 @@
|
||||
#
|
||||
# DO NOT Edit this file. Canonical version of Jasmine lives in the repo's package.json. This file is generated
|
||||
# by a grunt task when the standalone release is built.
|
||||
#
|
||||
module Jasmine
|
||||
module Core
|
||||
require 'json'
|
||||
VERSION_HASH = JSON.parse(File.new(File.join(File.dirname(__FILE__), "..", "..", "src", "version.json")).read);
|
||||
VERSION = "#{VERSION_HASH['major']}.#{VERSION_HASH['minor']}.#{VERSION_HASH['build']}"
|
||||
VERSION << ".rc#{VERSION_HASH['release_candidate']}" if VERSION_HASH['release_candidate']
|
||||
VERSION = "2.1.0"
|
||||
end
|
||||
end
|
||||
|
||||
23
package.json
Normal file
23
package.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"name": "jasmine-core",
|
||||
"license": "MIT",
|
||||
"version": "2.1.0",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pivotal/jasmine.git"
|
||||
},
|
||||
"description": "Official packaging of Jasmine's core files for use by Node.js projects.",
|
||||
"homepage": "http://jasmine.github.io",
|
||||
"main": "./lib/jasmine-core.js",
|
||||
"devDependencies": {
|
||||
"grunt": "~0.4.1",
|
||||
"grunt-contrib-jshint": "~0.7.0",
|
||||
"grunt-contrib-concat": "~0.3.0",
|
||||
"grunt-contrib-compass": "~0.6.0",
|
||||
"grunt-contrib-compress": "~0.5.2",
|
||||
"shelljs": "~0.1.4",
|
||||
"glob": "~3.2.9",
|
||||
"jasmine": "https://github.com/pivotal/jasmine-npm/archive/master.tar.gz",
|
||||
"load-grunt-tasks": "^0.4.0"
|
||||
}
|
||||
}
|
||||
1
pages
1
pages
Submodule pages deleted from d08ce2de24
22
release_notes/1.3.0.md
Normal file
22
release_notes/1.3.0.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# Jasmine Core 1.3.0 Release Notes
|
||||
|
||||
## Summary
|
||||
This version was a very incremental release that merged in some pull requests for bug fixes.
|
||||
|
||||
## Features
|
||||
|
||||
* HTML Runner exposes UI to not swallow Exceptions, instead raising as soon as thrown
|
||||
* Migrated homepage content to Wiki
|
||||
* Made a far more useful [tutorial page](http://pivotal.github.com/jasmine)
|
||||
* Added a `toBeNaN` matcher
|
||||
|
||||
## Fixes
|
||||
|
||||
* Better detection of in-browser vs. not
|
||||
* `afterEach` functions will run now even when there is a timeout
|
||||
* `toBeCloseTo` matcher is more accurate
|
||||
* More explicit matcher messages for spies
|
||||
* Better equality comparisons for regular expressions
|
||||
* Improvements to the Pretty Printer: controllable recursion depth, don't include inherited properties
|
||||
* Fix where `for` was being used as a property on an object (failed on IE)
|
||||
|
||||
12
release_notes/1.3.1.md
Normal file
12
release_notes/1.3.1.md
Normal file
@@ -0,0 +1,12 @@
|
||||
# Jasmine Core 1.3.1 Release Notes
|
||||
|
||||
## Summary
|
||||
|
||||
This release is for browser compatibility fixes
|
||||
|
||||
## Changes
|
||||
|
||||
### Features
|
||||
|
||||
Fixing test runner failures in IE 6/7/8
|
||||
|
||||
70
release_notes/2.0.1.md
Normal file
70
release_notes/2.0.1.md
Normal file
@@ -0,0 +1,70 @@
|
||||
# Jasmine Core 2.0.1 Release Notes
|
||||
|
||||
## Summary
|
||||
|
||||
This release is for small bug fixes and enhancements ahead of a real-soon-now 2.1.
|
||||
|
||||
## Changes
|
||||
|
||||
### Features
|
||||
|
||||
* NodeJS is now supported with a jasmine-core npm
|
||||
* [Support browsers that don't supply a `Date.now()` by having a `mockDate` object](http://www.pivotaltracker.com/story/66606132) - Closes #361
|
||||
* [Show message if no specs where loaded](http://www.pivotaltracker.com/story/12784235)
|
||||
* When using `jasmine.any`, the `class` will now be included in the error message
|
||||
* Reporters now receive the number of passed expectations in a spec
|
||||
* Use default failure message for `toBeNaN`
|
||||
* Use the latest `jasmine_selenium_runner` so we use the fix for printing objects with cycles
|
||||
* Add jasmine logo image to HTML runner
|
||||
* Stop Jasmine's CSS affecting the style of the body tag - Closes #600
|
||||
* Standardized location of the standalone distributions - they now live in the repo in `/dist` as well as on the Releases page
|
||||
|
||||
### Bugs
|
||||
|
||||
* Don't allow calling the same done callback multiple times - Fixes #523
|
||||
* [Remove 'empty' as an option as a spec result](http://www.pivotaltracker.com/story/73741032) as this was a breaking change
|
||||
* Instead, we determine if a spec has no expectations using the added
|
||||
key of `passedExpectations` in combination of the `failedExpectations`
|
||||
to determine that there a spec is 'empty'
|
||||
* Fix build in IE8 (IE8 doesn't support `Object.freeze`)
|
||||
* Fix `ObjectContaining` to match recursively
|
||||
|
||||
### Documentation
|
||||
|
||||
* Update release doc to use GitHub releases
|
||||
* Add installation instructions to README - Merges #621
|
||||
* Add Ruby Gem and Python Egg to docs
|
||||
* Add detailed steps on how to contribute - Merges #580 from @pablofiu
|
||||
|
||||
## Pull Requests and Issues
|
||||
|
||||
* Contains is explicitly false if actual is `undefined` or `null` - Fixes #627
|
||||
* namespace `html-reporter` -> `jasmine_html-reporter` - Fixes #600
|
||||
* Throw a more specific error when `expect` is used without a `currentSpec` - Fixes #602
|
||||
* Reduced size of logo with PNG Gauntlet - Merges #588
|
||||
* HTML Reporter resets previous DOM when re-initialized - Merges #594 from @plukevdh
|
||||
* Narrow down raise exceptions query selector; Finding by any input tag is a little bit broad - Closes #605
|
||||
* Pass through custom equality testers in toHaveBeenCalledWith - Fixes #536
|
||||
* Fix outdated copyright year (update to 2014) - Merges #550 from @slothmonster
|
||||
* [Add package.json to Python egg to get correct version number](http://www.pivotaltracker.com/story/67556148) - Fixes #551
|
||||
* Allow users to set the maximum length of array that the pretty-printer
|
||||
will print out - Fixes #323 @mikemoraned and #374 @futuraprime
|
||||
* `matchersUtil.equals()` does not expect a matcher as its first argument,
|
||||
so send the "actual" value first and the "expected" value second. - Merges #538 from @cbandy
|
||||
* Add single quote check to `jshint` and fix src files for that - Closes #522
|
||||
* Remove an `eval` in order to support running jasmine within CSP - Closes #503
|
||||
* Allow matcher custom failure messages to be a function - Closes #520
|
||||
* More color blind friendly CSS from @dleppik - Closes #463 & #509
|
||||
* Use `load-grunt-tasks` Merges #521 from @robinboehm
|
||||
* Special case printing `-0` - Closes #496
|
||||
* Allow stub or spy Date object safely using a closure to get a clean copy - Closes #506
|
||||
* [Use `\d7` instead of plain 'x' for more square appearance](http://www.pivotaltracker.com/story/48434179)
|
||||
* Better support in pretty printer when an object has null prototype - Fixes #500
|
||||
* Update link at top of README to improve access to Jasmine 2.0 docs - Merges #486 from @nextmat
|
||||
* Force query selector to seek within the html-reporter element - Merges #479 from @shprink
|
||||
* Netbeans files are in gitignore - Merges #478 from @shprink
|
||||
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with [Anchorman](http://github.com/infews/anchorman)_
|
||||
25
release_notes/2.0.2.md
Normal file
25
release_notes/2.0.2.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# Release Notes
|
||||
|
||||
## Summary
|
||||
|
||||
## Changes
|
||||
|
||||
* keep the files for running in a webpage around in the npm package
|
||||
* Expose files and paths necessary to embed jasmine in an html page for nodejs
|
||||
* Pull out the building of the jasmine interface so node and web both get the same one.
|
||||
* Show a dot with color of pending spec when no expectations
|
||||
* Console reporter prints out failed expectation's message
|
||||
|
||||
### Bugs
|
||||
|
||||
* Allow mocked Date constructor to be called with a subset of full params
|
||||
|
||||
## Pull Requests and Issues
|
||||
|
||||
* a disabled suite should call resultCallback with status being disabled
|
||||
* disabled suite should still call onStart callback
|
||||
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_
|
||||
83
release_notes/2.1.0.md
Normal file
83
release_notes/2.1.0.md
Normal file
@@ -0,0 +1,83 @@
|
||||
# Jasmine Core 2.1.0 Release Notes
|
||||
|
||||
## Summary
|
||||
|
||||
This is the release of Jasmine 2.1.
|
||||
|
||||
## Features
|
||||
|
||||
- Support for focused specs via `fit` and `fdescribe`
|
||||
- Support for `beforeAll` and `afterAll`
|
||||
- Support for an explicit `fail` function, both in synchronous and asynchronous specs
|
||||
- Allow custom timeout for `beforeEach`, `afterEach`, `beforeAll`, `afterAll` and `it`
|
||||
- Spies now track return values
|
||||
- Specs can now specify their own timeouts
|
||||
- Testing in Node.js via the official Jasmine Node Module
|
||||
- Spec results now have `suiteResults` method that behaves similarly to to `specResults`
|
||||
- HtmlReporter shows error alerts for afterAllExceptions
|
||||
|
||||
## Bugs
|
||||
|
||||
- CI now works for IE8 (this was releated to `ConsoleReporter` below)
|
||||
- Detect global object properly when getting the jasmine require obj
|
||||
- Fixes Issue #[569][issue_569] - [Tracker Story #73684570](http://www.pivotaltracker.com/story/73684570)
|
||||
|
||||
## Deprecations
|
||||
|
||||
### `ConsoleReporter` as part of Jasmine core
|
||||
|
||||
The Console Reporter exists nearly entirely for the old manner of running Jasmine's own specs in node.js. As we are now supporting node.js officially, this reporter code no longer needs to be in this repo and instead will be in the Jasmine npm.
|
||||
|
||||
For now you will see a deprecation message. It will be removed entirely in Jasmine 3.0.
|
||||
|
||||
## Documentation
|
||||
|
||||
- Release Notes from previous releases now live at [Jasmine's GitHub release page][releases]. See Tracker Story #[54582902][tracker_1]
|
||||
- Better instructions for releasing new documentation
|
||||
|
||||
[releases]: https://github.com/pivotal/jasmine/releases
|
||||
[tracker_1]: http://www.pivotaltracker.com/story/54582902
|
||||
|
||||
|
||||
## Pull Requests and Issues
|
||||
|
||||
- Simplification of HTMLtags in SpecRunner.html
|
||||
- Merges #[700][issue_700] from @tkrotoff
|
||||
- `toContain` works with array-like objects (Arguments, HTMLCollections, etc)
|
||||
- Merges #[699][issue_699] from @charleshansen
|
||||
- Fixed isPendingSpecException test title
|
||||
- Merges #[691][issue_691] from @ertrzyiks
|
||||
- Fixed an issue with example code in the npm
|
||||
- Merges #[686][issue_686] from @akoptsov
|
||||
- When the Jasmine clock is installed and date is mocked, `new Date() instanceof Date` should equal `true` Issue #[678][issue_678] & Issue #[679][issue_679] from @chernetsov
|
||||
- Support for an explicit `fail` function, both in synchronous and asynchronous specs
|
||||
- Fixes Issue #[567][issue_567], Issue #[568][issue_568], and Issue #[563][issue_563]
|
||||
- Allow custom timeout for `beforeEach`, `afterEach`, `beforeAll`, `afterAll` and `it`
|
||||
- Fixes Issue #[483][issue_483] - specs can now specify their own timeouts
|
||||
- Spies can track return values
|
||||
- Fixes Issue #[660][issue_660], Merged Issue #[669][issue_669] from @mkhanal
|
||||
- Interval handlers can now clear their interval
|
||||
- Fixes Issue #[655][issue_655] Merged Issue #[658][issue_658] from @tgirardi
|
||||
- Updated to the latest `json2.js`
|
||||
- Merges #[616][issue_616] from @apaladox2015
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with [Anchorman](http://github.com/infews/anchorman)_
|
||||
|
||||
[issue_569]: http://github.com/pivotal/jasmine/issues/569
|
||||
[issue_700]: http://github.com/pivotal/jasmine/issues/700
|
||||
[issue_699]: http://github.com/pivotal/jasmine/issues/699
|
||||
[issue_691]: http://github.com/pivotal/jasmine/issues/691
|
||||
[issue_678]: http://github.com/pivotal/jasmine/issues/678
|
||||
[issue_679]: http://github.com/pivotal/jasmine/issues/679
|
||||
[issue_567]: http://github.com/pivotal/jasmine/issues/567
|
||||
[issue_568]: http://github.com/pivotal/jasmine/issues/568
|
||||
[issue_563]: http://github.com/pivotal/jasmine/issues/563
|
||||
[issue_483]: http://github.com/pivotal/jasmine/issues/483
|
||||
[issue_660]: http://github.com/pivotal/jasmine/issues/660
|
||||
[issue_669]: http://github.com/pivotal/jasmine/issues/669
|
||||
[issue_655]: http://github.com/pivotal/jasmine/issues/655
|
||||
[issue_658]: http://github.com/pivotal/jasmine/issues/658
|
||||
[issue_616]: http://github.com/pivotal/jasmine/issues/616
|
||||
[issue_686]: http://github.com/pivotal/jasmine/issues/686
|
||||
179
release_notes/20.md
Normal file
179
release_notes/20.md
Normal file
@@ -0,0 +1,179 @@
|
||||
# Jasmine Core 2.0 Release Notes
|
||||
|
||||
## Summary
|
||||
|
||||
These notes are for Jasmine Core 2.0.
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
The [`introduction.js`][intro] page covers the current syntax, highlighting the changes. Here are the known interface changes that are not backwards compatible with 1.x.
|
||||
|
||||
* New syntax for asynchronous specs
|
||||
* New syntax for spies
|
||||
* New interface for reporters
|
||||
* Better Equality testing
|
||||
* Replaced custom matchers for ease of use
|
||||
* Change to `toThrow` matcher
|
||||
* Clock now remains installed when a spec finishes
|
||||
* More Jasmine internal variables/functions have been moved into closures
|
||||
|
||||
### New syntax for asynchronous specs
|
||||
|
||||
Similar to [Mocha][mocha], Jasmine `before`s, `spec`s, and `after`s can take an optional `done` callback in order to force asynchronous tests. The next function, whether it's a `before`, `spec` or `after`, will wait until this function is called or until a timeout is reached.
|
||||
|
||||
### New syntax for spies
|
||||
|
||||
Spies have a slightly modified syntax. The idea came from a desire to preserve any of the properties on a spied-upon function and some better testing patterns.
|
||||
|
||||
### New interface for reporters
|
||||
|
||||
The reporter interface has been **replaced**. The callbacks are different and more consistent. The objects passed in should only provide what is needed to report results. This enforces an interface to result data so custom reporters will be less coupled to the Jasmine implementation. The Jasmine reporter API now includes a slot for a `timer` object.
|
||||
|
||||
### Better Equality testing
|
||||
|
||||
We removed the previous equality code and are now using new code for testing equality. We started with [Underscore.js][underscore]'s `isEqual`, refactored a bit and added some additional tests.
|
||||
|
||||
### Replaced custom matchers for ease of use
|
||||
|
||||
The interface for adding custom matchers has been **replaced**. It has always been possible to add custom matchers, but the API was barely documented and difficult to test. We've changed how matchers are added and tested. Jasmine adds its own matchers by the same mechanism that custom matchers use. Dogfooding FTW.
|
||||
|
||||
### Change to `toThrow` matcher
|
||||
|
||||
We've changed the behavior of the `toThrow` matcher, moving some functionality to the `toThrowError` matcher. This should allow more of the requested use cases.
|
||||
|
||||
### Clock now remains installed when a spec finishes
|
||||
|
||||
After installing the Jasmine Clock, it will stay installed until `uninstall` is called -- clearing up any ambiguity for when those timing functions will revert to using the global clock object.
|
||||
|
||||
## More Jasmine internal variables/functions have been moved into closures
|
||||
|
||||
Certain variables/functions like a function to get the next spec id have been moved into closures, making the Jasmine interface cleaner.
|
||||
|
||||
## Other Changes
|
||||
|
||||
* Massive refactoring and better testing
|
||||
* Environment setup now in `boot.js`
|
||||
* Development and Build moved to Grunt
|
||||
* Changes to how Jasmine is loaded
|
||||
* Changes to how Jasmine is tested
|
||||
* Better node.js support
|
||||
* Better Continuous Integration Environment at Travis
|
||||
* Support matrix updated
|
||||
* Removed JsDoc Pages
|
||||
* Adding Code Climate for JavaScript
|
||||
|
||||
## Massive refactoring and better testing
|
||||
|
||||
This is the biggest set of changes. We've touched nearly every file and every object. We've merged objects together and factored out code. We styled the code more consistently. We've improved nearly every test.
|
||||
|
||||
In general, Jasmine is made of smaller, more-loosely-coupled objects, unit-tested with explicit dependencies injected. This made tests easier to read, write, and maintain. We know this has made Jasmine development easier for the core team. We expect (and hope) this makes it easier for the community to extend Jasmine and provide pull requests that make more sense the first time out.
|
||||
|
||||
## Environment setup now in `boot.js`
|
||||
|
||||
Instantiation and setup of the Jasmine environment, including building reporters, exposing the "global" functions, and executing tests has moved into its own file: `boot.js`. This should make it easier to add custom reporters, configure some objects, or just in general change how you use Jasmine from the outside.
|
||||
|
||||
For example, during development, Jasmine uses its own `devboot.js` to load itself twice - once from `jasmine.js` and once from the source directories.
|
||||
|
||||
## Development and Build moved to Grunt
|
||||
|
||||
We've moved away from Ruby and embraced [Node.js][node] and [Grunt.js][grunt] for the various command line tasks during development. Yes, it's a just a different set of dependencies. But it's less code for the team to maintain - it turns out that JavaScript tools are pretty good at building JavaScript projects. This will make it easier for the community to make sure contributions work in browsers and in Node.js before submitting Pull Requests. There is more detail in the [Contributor's Guide][contrib].
|
||||
|
||||
## Changes to how Jasmine is loaded
|
||||
|
||||
We did not want to add new run-time dependencies, yet we needed to be cleaner when loading Jasmine. So we wrote a custom "require" scheme that works in Node.js and in browsers. This only affects pull requests which add files - please be careful in these cases. Again, the [Contributor's Guide][contrib] should help.
|
||||
|
||||
## Changes to how Jasmine is tested with Jasmine
|
||||
|
||||
Writing a custom require system helped enforce self-testing - the built `jasmine.js` testing Jasmine from the source directories. Overall this has improved the stability of the code. When you look at Jasmine's tests, you'll see both `jasmine` and `j$` used. The former, `jasmine`, will always be used to test the code from source, which is loaded into the reference `j$`. Please adhere to this pattern when writing tests for contributions.
|
||||
|
||||
## Better node.js support
|
||||
|
||||
`Node.js` is now officially a first-class citizen. For a long time we've made sure tests were green in Node before releasing. But it is now officially part of Jasmine's CI build at [Travis][travis]. For the curious, the [`node_suite.js`][node_suite], is essentially a `boot.js` for Node. An official `npm` is coming.
|
||||
|
||||
## Better Continuous Integration Environment at Travis
|
||||
|
||||
The [CI build at Travis][travis_jasmine] now runs the core specs in a build matrix across browsers. It's far from complete on the operating system matrix, but you will see that Jasmine runs against: Firefox, Chrome, Safari 5, Safari 6, [Phantom.js][phantom], [Node.js][node], and IE versions 8, 9, and 10. Big thanks to [SauceLabs][sauce] for their support of open source projects. We will happily take pull requests for additional OS/Browser combos within the matrix.
|
||||
|
||||
## Support Matrix Updated
|
||||
|
||||
We're dropping support for IE < 8. [Jasmine 1.x][jasmine_downloads] remains for projects that need to support older browsers.
|
||||
|
||||
## Removed JsDoc Pages
|
||||
|
||||
Comments in code are lies waiting to happen. Jasmine's JsDoc comments were no exception. The comments were out of date, the generated pages were even more out of date, and frankly they were not helpful. So they're gone.
|
||||
|
||||
Last year saw the posting of the [`introduction.js`][intro] page to document the real, practical interface for projects to use. This page has received a lot of positive feedback so expect more pages like this one.
|
||||
|
||||
## Adding Code Climate for JavaScript
|
||||
|
||||
We are running Code Climate for Jasmine. We have some work to do here but it's helping us easily find code hotspots.
|
||||
|
||||
## Pull Requests and Issues
|
||||
|
||||
The following Pull Requests were merged:
|
||||
|
||||
* ObjectContaining wrong filed value error message #[394](https://github.com/pivotal/jasmine/issues/394) from albertandrejev
|
||||
* Removed unnecessary parameter from `suiteFactory()` call #[397](https://github.com/pivotal/jasmine/issues/397) from valera-rozuvan
|
||||
* `jasmine.Any` supports `Boolean` #[392](https://github.com/pivotal/jasmine/issues/392) from albertandrejev
|
||||
* Reporters get execution time #[30](https://github.com/pivotal/jasmine/issues/30)
|
||||
* `toThrow` matchers handle falsy exceptions #[317](https://github.com/pivotal/jasmine/issues/371)
|
||||
* Removed deprecated `jasmine.Matchers.pp` #[363](https://github.com/pivotal/jasmine/issues/363) from robinboehm
|
||||
* Fix for Clock ticking to default to 0 #[340](https://github.com/pivotal/jasmine/issues/340) from Caio Cunha
|
||||
* Whitespace failures should be easier to understand #[332](https://github.com/pivotal/jasmine/issues/332) from bjornblomqvist
|
||||
* Fix for more markdown-y image for Build status #[329](https://github.com/pivotal/jasmine/issues/329) from sunliwen
|
||||
* UTF-8 encoding fixes #[333](https://github.com/pivotal/jasmine/issues/333) from bjornblomqvist
|
||||
* Replaced deprecated octal literal with hexadecimal from kris7t
|
||||
* Make getGlobal() work in strict mode from metaweta
|
||||
* Clears timeout timer even when async spec throws an exception from tidoust
|
||||
* Timeouts scheduled within a delayed function are correctly scheduled and executed from maciej-filip-sz
|
||||
|
||||
### Bug Fixes
|
||||
* Improved the performance of the HTML output with a CSS change #[428](https://github.com/pivotal/jasmine/issues/428) - Thanks @tjgrathwell
|
||||
* Removed an accidental global pollution of `j$` as a reference to Jasmine. Thanks to Morten Maxild from the mailing list
|
||||
* There is now a consistent `this` between `beforeEach`, `it` and `afterEach` for a spec
|
||||
* A spy's strategy now has properties `returnValue` and `throwError` because they are better names
|
||||
* Make it easy to copy the title of failing specs from the HTML output
|
||||
* Don't add periods to the full name of a spec fix #[427](https://github.com/pivotal/jasmine/issues/427)
|
||||
* Allow Env to take optional spec/suite ids when asked to `execute`
|
||||
* [Mock clock now less intrusive, replacing global timer functions only when clock is installed](http://www.pivotaltracker.com/story/54168708)
|
||||
* Restore custom failure messages for `toHaveBeenCalledWith`
|
||||
* Jasmine global object has a addCustomEqualityTester and addMatchers (no longer directly on global)
|
||||
* Fixed a global leak of `timer`
|
||||
* Remove currentRunner from Env (users can use topSuite from Env instead)
|
||||
* [Specs without expectations are now considered passing](http://www.pivotaltracker.com/story/59422744)
|
||||
* Improve error message when a spec does not call the async callback within the default time interval
|
||||
* Allow passing a negativeCompare in a custom matcher for more custom implementations when `.not` is called
|
||||
* Update favicon to be higher resolution
|
||||
* Make all async functions be subject to the timeout
|
||||
|
||||
There were several other pull requests that either had already been fixed, or were good starting points for the various changes above. Thank you for all of the hard work to keep Jasmine awesome.
|
||||
|
||||
## Other Bugs and Features
|
||||
|
||||
There were a few small changes and fixes that didn't fit into any of the above categories:
|
||||
|
||||
* HTML Reporter refactored for simplicity and performance
|
||||
* Default character encoding on the HTML runner page is UTF-8
|
||||
* [Escape special regex characters from the spec param](http://www.pivotaltracker.com/story/52731407)
|
||||
* Favicon returns
|
||||
* [Clock supports `eval`'d strings as functions](http://www.pivotaltracker.com/story/40853563)
|
||||
* There should always be stack traces on failures
|
||||
* Removed references to unused `jasmine.VERBOSE`
|
||||
* Removed references to unused `jasmine.XmlHttpRequest`
|
||||
|
||||
[mocha]: http://visionmedia.github.io/mocha/
|
||||
[underscore]: http://underscorejs.org/
|
||||
[grunt]: http://gruntjs.com
|
||||
[node]: http://nodejs.org
|
||||
[phantom]: http://phantomjs.org
|
||||
[jasmine_downloads]: https://github.com/pivotal/jasmine/downloads
|
||||
[contrib]: https://github.com/pivotal/jasmine/blob/master/CONTRIBUTING.md
|
||||
[travis]: http://travis-ci.org
|
||||
[travis_jasmine]: http://travis-ci.org/jasmine
|
||||
[sauce]: http://saucelabs.com
|
||||
[node_suite]: https://github.com/pivotal/jasmine/blob/master/spec/node_suite.js
|
||||
[intro]: http://jasmine.github.io/2.0/introduction.html
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with [Anchorman](http://github.com/infews/anchorman)_
|
||||
110
release_notes/older_versions.md
Normal file
110
release_notes/older_versions.md
Normal file
@@ -0,0 +1,110 @@
|
||||
# Release 1.0.1.1 — November 9, 2010
|
||||
|
||||
## Jasmine Gem
|
||||
|
||||
## Bugs fixed
|
||||
* Rails 3.0 and RSpec 2.0 are now supported.
|
||||
|
||||
|
||||
## Known issues
|
||||
* Rails 3 generators are not yet implemented -- coming soon!
|
||||
|
||||
|
||||
-----
|
||||
# Release 1.0.1 — October 5, 2010
|
||||
-----
|
||||
|
||||
## Jasmine Core
|
||||
|
||||
## Bugs fixed
|
||||
* Bug fixes for Internet Explorer (thanks fschwiet, fabiomcosta, and jfirebaugh).
|
||||
|
||||
|
||||
## Jasmine Gem
|
||||
|
||||
## Bugs fixed
|
||||
* Bug fix for Windows (thanks jfirebaugh).
|
||||
|
||||
|
||||
-----
|
||||
# Release 1.0 — September 14, 2010
|
||||
-----
|
||||
|
||||
## Jasmine Core
|
||||
|
||||
## Features
|
||||
* `waitsFor()` arguments can now be specified in any order. Timeout and message are optional.
|
||||
* The default `waitsFor()` timeout period is now specified in `env.defaultTimeoutInterval`; the default value is 5 seconds.
|
||||
* Added link to jasmine site from html runner.
|
||||
* Added license file to standalone distribution.
|
||||
* New friendly version number.
|
||||
|
||||
|
||||
## Bugs fixed
|
||||
* `waitsFor()` hanged forever if latch function never returned true.
|
||||
* The `not.toThrow()` matcher threw an exception when used with no args.
|
||||
* The `toThrow()` matcher, when inverted, gave misleading failure messages.
|
||||
* Spy matchers, when inverted, gave misleading failure messages.
|
||||
|
||||
|
||||
## Deprecations
|
||||
* Deprecated `waits()` block in favor of `waitsFor()`; `waits()` will be removed in a future release.
|
||||
* Deprecated `toNotBe()`, `toNotEqual()`, `toNotMatch()`, and `toNotContain()` matchers; they will be removed in a future release.
|
||||
* Console X was removed from the distribution as it was no longer used.
|
||||
* To give us some flexibility for future features, wrapped matcher functions now return `undefined` (they previously returned `true` or `false`, but this was undocumented).
|
||||
|
||||
|
||||
## Jasmine Gem
|
||||
|
||||
## Features
|
||||
* Jasmine now supports JRuby.
|
||||
* Jasmine now supports Ruby 1.9.
|
||||
|
||||
|
||||
## Bugs fixed
|
||||
* Various generator issues fixed.
|
||||
|
||||
|
||||
## Known issues
|
||||
* Rails 3 and RSpec 2 are not yet fully supported.
|
||||
|
||||
|
||||
-----
|
||||
# Release 0.11.1 — June 25, 2010
|
||||
-----
|
||||
|
||||
## Jasmine Core
|
||||
|
||||
### Features
|
||||
* Jasmine no longer logs "Jasmine Running…" messages to the log by default. This can be enabled in runner.html by adding 'trivialReporter.logRunningSpecs = true;'.
|
||||
* The `wasCalled()`, `wasCalledWith()`, `wasNotCalled()` and `wasNotCalledWith()` matchers have been deprecated. The new matchers `toHaveBeenCalled()` and `toHaveBeenCalledWith()` have been added. You can use the `not` prefix to achieve equivalent of the `wasNot…()` expectation (e.g. `not.toHaveBeenCalled()`).
|
||||
|
||||
|
||||
## Notables
|
||||
* A barebones version of Jasmine is now available on <a href="http://pivotal.github.com/jasmine/">http://pivotal.github.com/jasmine/</a>.
|
||||
|
||||
|
||||
-----
|
||||
# Release 0.11.0 — June 23, 2010
|
||||
-----
|
||||
## Jasmine Core
|
||||
|
||||
## Features
|
||||
* The version number has been removed from the generated single-file /lib/jasmine.js. We're also now uploading this file, with the version number in the filename, to github's Downloads page.
|
||||
* Old-style matchers (those using this.report(), from before 0.10.x) are no longer supported. See the <span class="caps">README</span> for instructions on writing new-style matchers.
|
||||
* <strong>jasmine.log</strong> pretty-prints its parameters to the spec's output.
|
||||
* Jasmine no longer depends on 'window'.
|
||||
* <span class="caps">HTML</span> runner should show number of passes/fails by spec, not expectation.
|
||||
* Small modification to JsApiReporter data format.
|
||||
|
||||
|
||||
## Bugs fixed:
|
||||
* If multiple beforeEach blocks were declared, they were executed in reverse order.
|
||||
* Specs with duplicate names confused TrivialReporter output.
|
||||
* Errors in describe functions caused later tests to be weirdly nested.
|
||||
* Nested specs weren't reported properly by the JsApiReporter.
|
||||
|
||||
|
||||
## Known issues:
|
||||
* If you turn on the mock clock, you'll get a spurious log message at the end of your spec.
|
||||
|
||||
1
requirements.txt
Normal file
1
requirements.txt
Normal file
@@ -0,0 +1 @@
|
||||
ordereddict==1.1
|
||||
47
setup.py
Normal file
47
setup.py
Normal file
@@ -0,0 +1,47 @@
|
||||
from setuptools import setup, find_packages, os
|
||||
import json
|
||||
|
||||
with open('package.json') as packageFile:
|
||||
version = json.load(packageFile)['version']
|
||||
|
||||
setup(
|
||||
name="jasmine-core",
|
||||
version=version,
|
||||
url="http://pivotal.github.io/jasmine/",
|
||||
author="Pivotal Labs",
|
||||
author_email="jasmine-js@googlegroups.com",
|
||||
description=('Jasmine is a Behavior Driven Development testing framework for JavaScript. It does not rely on '+
|
||||
'browsers, DOM, or any JavaScript framework. Thus it\'s suited for websites, '+
|
||||
'Node.js (http://nodejs.org) projects, or anywhere that JavaScript can run.'),
|
||||
license='MIT',
|
||||
classifiers=[
|
||||
'Development Status :: 5 - Production/Stable',
|
||||
'Environment :: Console',
|
||||
'Environment :: Web Environment',
|
||||
'Framework :: Django',
|
||||
'Intended Audience :: Developers',
|
||||
'License :: OSI Approved :: MIT License',
|
||||
'Operating System :: OS Independent',
|
||||
'Programming Language :: Python',
|
||||
'Programming Language :: Python :: 2',
|
||||
'Programming Language :: Python :: 2.6',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.2',
|
||||
'Programming Language :: Python :: 3.3',
|
||||
'Programming Language :: Python :: Implementation :: PyPy',
|
||||
'Topic :: Internet :: WWW/HTTP',
|
||||
'Topic :: Software Development :: Libraries :: Python Modules',
|
||||
'Topic :: Software Development :: Build Tools',
|
||||
'Topic :: Software Development :: Quality Assurance',
|
||||
'Topic :: Software Development :: Testing',
|
||||
],
|
||||
|
||||
packages=['jasmine_core', 'jasmine_core.images'],
|
||||
package_dir={'jasmine_core': 'lib/jasmine-core', 'jasmine_core.images': 'images'},
|
||||
package_data={'jasmine_core': ['*.js', '*.css'], 'jasmine_core.images': ['*.png']},
|
||||
|
||||
include_package_data=True,
|
||||
|
||||
install_requires=['glob2>=0.4.1', 'ordereddict==1.1']
|
||||
)
|
||||
@@ -1,451 +1,270 @@
|
||||
describe("ConsoleReporter", function() {
|
||||
//keep these literal. otherwise the test loses value as a test.
|
||||
function green(str) {
|
||||
return '\033[32m' + str + '\033[0m';
|
||||
}
|
||||
|
||||
function red(str) {
|
||||
return '\033[31m' + str + '\033[0m';
|
||||
}
|
||||
|
||||
function yellow(str) {
|
||||
return '\033[33m' + str + '\033[0m';
|
||||
}
|
||||
|
||||
function prefixGreen(str) {
|
||||
return '\033[32m' + str;
|
||||
}
|
||||
|
||||
function prefixRed(str) {
|
||||
return '\033[31m' + str;
|
||||
}
|
||||
|
||||
var newline = "\n";
|
||||
|
||||
var passingSpec = {
|
||||
results: function() {
|
||||
return {
|
||||
passed: function() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
failingSpec = {
|
||||
results: function() {
|
||||
return {
|
||||
passed: function() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
skippedSpec = {
|
||||
results: function() {
|
||||
return {skipped: true};
|
||||
}
|
||||
},
|
||||
passingRun = {
|
||||
specs: function() {
|
||||
return [null, null, null];
|
||||
},
|
||||
results: function() {
|
||||
return {failedCount: 0, items_: [null, null, null]};
|
||||
}
|
||||
},
|
||||
failingRun = {
|
||||
specs: function() {
|
||||
return [null, null, null];
|
||||
},
|
||||
results: function() {
|
||||
return {
|
||||
failedCount: 7, items_: [null, null, null]};
|
||||
}
|
||||
};
|
||||
|
||||
function repeatedlyInvoke(f, times) {
|
||||
for (var i = 0; i < times; i++) f(times + 1);
|
||||
}
|
||||
|
||||
function repeat(thing, times) {
|
||||
var arr = [];
|
||||
for (var i = 0; i < times; i++) arr.push(thing);
|
||||
return arr;
|
||||
}
|
||||
|
||||
function simulateRun(reporter, specResults, suiteResults, finalRunner, startTime, endTime) {
|
||||
reporter.reportRunnerStarting();
|
||||
for (var i = 0; i < specResults.length; i++) {
|
||||
reporter.reportSpecResults(specResults[i]);
|
||||
}
|
||||
for (i = 0; i < suiteResults.length; i++) {
|
||||
reporter.reportSuiteResults(suiteResults[i]);
|
||||
}
|
||||
reporter.runnerStartTime = startTime;
|
||||
reporter.now = function() {
|
||||
return endTime;
|
||||
};
|
||||
reporter.reportRunnerResults(finalRunner);
|
||||
}
|
||||
|
||||
var reporter, out, done;
|
||||
var out;
|
||||
|
||||
beforeEach(function() {
|
||||
out = (function() {
|
||||
var output = "";
|
||||
return {
|
||||
print:function(str) {
|
||||
print: function(str) {
|
||||
output += str;
|
||||
},
|
||||
getOutput:function() {
|
||||
return output;
|
||||
getOutput: function() {
|
||||
return output.replace('ConsoleReporter is deprecated and will be removed in a future version.', '');
|
||||
},
|
||||
clear: function() {
|
||||
output = "";
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
done = false;
|
||||
reporter = new jasmine.ConsoleReporter(out.print, function(runner) {
|
||||
done = true
|
||||
});
|
||||
}());
|
||||
});
|
||||
|
||||
|
||||
describe('Integration', function() {
|
||||
it("prints the proper output under a pass scenario - small numbers.", function() {
|
||||
simulateRun(reporter,
|
||||
repeat(passingSpec, 3),
|
||||
[],
|
||||
{
|
||||
specs: function() {
|
||||
return [null, null, null];
|
||||
},
|
||||
results:function() {
|
||||
return {
|
||||
items_: [null, null, null],
|
||||
totalCount: 7,
|
||||
failedCount: 0
|
||||
};
|
||||
}
|
||||
},
|
||||
1000,
|
||||
1777
|
||||
);
|
||||
|
||||
var output = out.getOutput();
|
||||
expect(output).toMatch(/^Started/);
|
||||
expect(output).toMatch(/\.\.\./);
|
||||
expect(output).toMatch(/3 specs, 0 failures/);
|
||||
it("reports that the suite has started to the console", function() {
|
||||
var reporter = new j$.ConsoleReporter({
|
||||
print: out.print
|
||||
});
|
||||
|
||||
it("prints the proper output under a pass scenario. large numbers.", function() {
|
||||
simulateRun(reporter,
|
||||
repeat(passingSpec, 57),
|
||||
[],
|
||||
{
|
||||
specs: function() {
|
||||
return [null, null, null];
|
||||
},
|
||||
results:function() {
|
||||
return {
|
||||
items_: [null, null, null],
|
||||
totalCount: 7,
|
||||
failedCount: 0
|
||||
};
|
||||
}
|
||||
},
|
||||
1000,
|
||||
1777);
|
||||
reporter.jasmineStarted();
|
||||
|
||||
var output = out.getOutput();
|
||||
expect(output).toMatch(/^Started/);
|
||||
expect(output).toMatch(/\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\./);
|
||||
expect(output).toMatch(/3 specs, 0 failures/);
|
||||
});
|
||||
|
||||
it("prints the proper output under a failure scenario.", function() {
|
||||
simulateRun(reporter,
|
||||
[failingSpec, passingSpec, failingSpec],
|
||||
[
|
||||
{description:"The oven",
|
||||
results:function() {
|
||||
return {
|
||||
items_:[
|
||||
{failedCount:2,
|
||||
description:"heats up",
|
||||
items_:[
|
||||
{trace:{stack:"stack trace one\n second line"}},
|
||||
{trace:{stack:"stack trace two"}}
|
||||
]}
|
||||
]
|
||||
};
|
||||
}},
|
||||
{description:"The washing machine",
|
||||
results:function() {
|
||||
return {
|
||||
items_:[
|
||||
{failedCount:2,
|
||||
description:"washes clothes",
|
||||
items_:[
|
||||
{trace:{stack:"stack trace one"}}
|
||||
]}
|
||||
]
|
||||
};
|
||||
}}
|
||||
],
|
||||
{
|
||||
specs: function() {
|
||||
return [null, null, null];
|
||||
},
|
||||
results:function() {
|
||||
return {
|
||||
items_: [null, null, null],
|
||||
totalCount: 7,
|
||||
failedCount: 2
|
||||
};
|
||||
}
|
||||
},
|
||||
1000,
|
||||
1777);
|
||||
|
||||
var output = out.getOutput();
|
||||
expect(output).toMatch(/^Started/);
|
||||
expect(output).toMatch(/F\.F/);
|
||||
expect(output).toMatch(/The oven heats up\n stack trace one\n second line\n stack trace two/);
|
||||
expect(output).toMatch(/The washing machine washes clothes\n stack trace one/);
|
||||
expect(output).toMatch(/3 specs, 2 failures/);
|
||||
});
|
||||
expect(out.getOutput()).toEqual("Started\n");
|
||||
});
|
||||
|
||||
describe('When a Jasmine environment executes', function() {
|
||||
it("starts the provided timer when jasmine starts", function() {
|
||||
var timerSpy = jasmine.createSpyObj('timer', ['start']),
|
||||
reporter = new j$.ConsoleReporter({
|
||||
print: out.print,
|
||||
timer: timerSpy
|
||||
});
|
||||
|
||||
reporter.jasmineStarted();
|
||||
|
||||
expect(timerSpy.start).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("reports a passing spec as a dot", function() {
|
||||
var reporter = new j$.ConsoleReporter({
|
||||
print: out.print
|
||||
});
|
||||
|
||||
reporter.specDone({status: "passed"});
|
||||
|
||||
expect(out.getOutput()).toEqual(".");
|
||||
});
|
||||
|
||||
it("does not report a disabled spec", function() {
|
||||
var reporter = new j$.ConsoleReporter({
|
||||
print: out.print
|
||||
});
|
||||
|
||||
reporter.specDone({status: "disabled"});
|
||||
|
||||
expect(out.getOutput()).toEqual("");
|
||||
});
|
||||
|
||||
it("reports a failing spec as an 'F'", function() {
|
||||
var reporter = new j$.ConsoleReporter({
|
||||
print: out.print
|
||||
});
|
||||
|
||||
reporter.specDone({status: "failed"});
|
||||
|
||||
expect(out.getOutput()).toEqual("F");
|
||||
});
|
||||
|
||||
it("reports a pending spec as a '*'", function() {
|
||||
var reporter = new j$.ConsoleReporter({
|
||||
print: out.print
|
||||
});
|
||||
|
||||
reporter.specDone({status: "pending"});
|
||||
|
||||
expect(out.getOutput()).toEqual("*");
|
||||
});
|
||||
|
||||
it("alerts user if there are no specs", function(){
|
||||
var reporter = new j$.ConsoleReporter({
|
||||
print: out.print
|
||||
});
|
||||
|
||||
reporter.jasmineStarted();
|
||||
out.clear();
|
||||
reporter.jasmineDone();
|
||||
|
||||
expect(out.getOutput()).toMatch(/No specs found/);
|
||||
});
|
||||
|
||||
it("reports a summary when done (singular spec and time)", function() {
|
||||
var timerSpy = jasmine.createSpyObj('timer', ['start', 'elapsed']),
|
||||
reporter = new j$.ConsoleReporter({
|
||||
print: out.print,
|
||||
timer: timerSpy
|
||||
});
|
||||
|
||||
reporter.jasmineStarted();
|
||||
reporter.specDone({status: "passed"});
|
||||
|
||||
timerSpy.elapsed.and.returnValue(1000);
|
||||
|
||||
out.clear();
|
||||
reporter.jasmineDone();
|
||||
|
||||
expect(out.getOutput()).toMatch(/1 spec, 0 failures/);
|
||||
expect(out.getOutput()).not.toMatch(/0 pending specs/);
|
||||
expect(out.getOutput()).toMatch("Finished in 1 second\n");
|
||||
});
|
||||
|
||||
it("reports a summary when done (pluralized specs and seconds)", function() {
|
||||
var timerSpy = jasmine.createSpyObj('timer', ['start', 'elapsed']),
|
||||
reporter = new j$.ConsoleReporter({
|
||||
print: out.print,
|
||||
timer: timerSpy
|
||||
});
|
||||
|
||||
reporter.jasmineStarted();
|
||||
reporter.specDone({status: "passed"});
|
||||
reporter.specDone({status: "pending"});
|
||||
reporter.specDone({
|
||||
status: "failed",
|
||||
description: "with a failing spec",
|
||||
fullName: "A suite with a failing spec",
|
||||
failedExpectations: [
|
||||
{
|
||||
passed: false,
|
||||
message: "Expected true to be false.",
|
||||
expected: false,
|
||||
actual: true,
|
||||
stack: "foo\nbar\nbaz"
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
out.clear();
|
||||
|
||||
timerSpy.elapsed.and.returnValue(100);
|
||||
|
||||
reporter.jasmineDone();
|
||||
|
||||
expect(out.getOutput()).toMatch(/3 specs, 1 failure, 1 pending spec/);
|
||||
expect(out.getOutput()).toMatch("Finished in 0.1 seconds\n");
|
||||
});
|
||||
|
||||
it("reports a summary when done that includes stack traces for a failing suite", function() {
|
||||
var reporter = new j$.ConsoleReporter({
|
||||
print: out.print
|
||||
});
|
||||
|
||||
reporter.jasmineStarted();
|
||||
reporter.specDone({status: "passed"});
|
||||
reporter.specDone({
|
||||
status: "failed",
|
||||
description: "with a failing spec",
|
||||
fullName: "A suite with a failing spec",
|
||||
failedExpectations: [
|
||||
{
|
||||
passed: false,
|
||||
message: "Expected true to be false.",
|
||||
expected: false,
|
||||
actual: true,
|
||||
stack: "foo bar baz"
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
out.clear();
|
||||
|
||||
reporter.jasmineDone();
|
||||
|
||||
expect(out.getOutput()).toMatch(/true to be false/);
|
||||
expect(out.getOutput()).toMatch(/foo bar baz/);
|
||||
});
|
||||
|
||||
describe('onComplete callback', function(){
|
||||
var onComplete, reporter;
|
||||
|
||||
beforeEach(function() {
|
||||
reporter.reportRunnerStarting();
|
||||
onComplete = jasmine.createSpy('onComplete');
|
||||
reporter = new j$.ConsoleReporter({
|
||||
print: out.print,
|
||||
onComplete: onComplete
|
||||
});
|
||||
reporter.jasmineStarted();
|
||||
});
|
||||
|
||||
it("should print 'Started' to the console", function() {
|
||||
expect(out.getOutput()).toEqual("Started" + newline);
|
||||
it("is called when the suite is done", function() {
|
||||
reporter.jasmineDone();
|
||||
expect(onComplete).toHaveBeenCalledWith(true);
|
||||
});
|
||||
|
||||
describe('when a spec reports', function() {
|
||||
beforeEach(function() {
|
||||
out.clear();
|
||||
});
|
||||
|
||||
it("prints a green dot if the spec passes", function() {
|
||||
reporter.reportSpecResults(passingSpec);
|
||||
|
||||
expect(out.getOutput()).toMatch(/\./);
|
||||
});
|
||||
|
||||
it("prints a red dot if the spec fails", function() {
|
||||
reporter.reportSpecResults(failingSpec);
|
||||
|
||||
expect(out.getOutput()).toMatch(/F/);
|
||||
});
|
||||
|
||||
it("prints a yellow star if the spec was skipped", function() {
|
||||
reporter.reportSpecResults(skippedSpec);
|
||||
|
||||
expect(out.getOutput()).toMatch(/\*/);
|
||||
});
|
||||
it('calls it with false if there are spec failures', function() {
|
||||
reporter.specDone({status: "failed", failedExpectations: []});
|
||||
reporter.jasmineDone();
|
||||
expect(onComplete).toHaveBeenCalledWith(false);
|
||||
});
|
||||
|
||||
describe('when a suite reports', function() {
|
||||
var emptyResults;
|
||||
beforeEach(function() {
|
||||
emptyResults = function() {
|
||||
return {
|
||||
items_:[]
|
||||
};
|
||||
};
|
||||
});
|
||||
|
||||
it("remembers suite results", function() {
|
||||
reporter.reportSuiteResults({description: "Oven", results: emptyResults});
|
||||
reporter.reportSuiteResults({description: "Mixer", results: emptyResults});
|
||||
|
||||
expect(reporter.suiteResults[0].description).toEqual('Oven');
|
||||
expect(reporter.suiteResults[1].description).toEqual('Mixer');
|
||||
});
|
||||
|
||||
it("creates a description out of the current suite and any parent suites", function() {
|
||||
var grandparentSuite = {
|
||||
description: "My house",
|
||||
results: emptyResults
|
||||
};
|
||||
var parentSuite = {
|
||||
description: "kitchen",
|
||||
parentSuite: grandparentSuite,
|
||||
results: emptyResults
|
||||
};
|
||||
reporter.reportSuiteResults({ description: "oven", parentSuite: parentSuite, results: emptyResults });
|
||||
|
||||
expect(reporter.suiteResults[0].description).toEqual("My house kitchen oven");
|
||||
});
|
||||
|
||||
it("gathers failing spec results from the suite - the spec must have a description.", function() {
|
||||
reporter.reportSuiteResults({description:"Oven",
|
||||
results: function() {
|
||||
return {
|
||||
items_:[
|
||||
{ failedCount: 0, description: "specOne" },
|
||||
{ failedCount: 99, description: "specTwo" },
|
||||
{ failedCount: 0, description: "specThree" },
|
||||
{ failedCount: 88, description: "specFour" },
|
||||
{ failedCount: 3 }
|
||||
]
|
||||
};
|
||||
}});
|
||||
|
||||
expect(reporter.suiteResults[0].failedSpecResults).
|
||||
toEqual([
|
||||
{ failedCount: 99, description: "specTwo" },
|
||||
{ failedCount: 88, description: "specFour" }
|
||||
]);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('and finishes', function() {
|
||||
|
||||
describe('when reporting spec failure information', function() {
|
||||
|
||||
it("prints suite and spec descriptions together as a sentence", function() {
|
||||
reporter.suiteResults = [
|
||||
{description:"The oven", failedSpecResults:[
|
||||
{description:"heats up", items_:[]},
|
||||
{description:"cleans itself", items_:[]}
|
||||
]},
|
||||
{description:"The mixer", failedSpecResults:[
|
||||
{description:"blends things together", items_:[]}
|
||||
]}
|
||||
];
|
||||
|
||||
reporter.reportRunnerResults(failingRun);
|
||||
|
||||
expect(out.getOutput()).toContain("The oven heats up");
|
||||
expect(out.getOutput()).toContain("The oven cleans itself");
|
||||
expect(out.getOutput()).toContain("The mixer blends things together");
|
||||
});
|
||||
|
||||
it("prints stack trace of spec failure", function() {
|
||||
reporter.suiteResults = [
|
||||
{description:"The oven", failedSpecResults:[
|
||||
{description:"heats up",
|
||||
items_:[
|
||||
{trace:{stack:"stack trace one"}},
|
||||
{trace:{stack:"stack trace two"}}
|
||||
]}
|
||||
]}
|
||||
];
|
||||
|
||||
reporter.reportRunnerResults(failingRun);
|
||||
|
||||
expect(out.getOutput()).toContain("The oven heats up");
|
||||
expect(out.getOutput()).toContain("stack trace one");
|
||||
expect(out.getOutput()).toContain("stack trace two");
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('when reporting the execution time', function() {
|
||||
|
||||
it("prints the full finished message", function() {
|
||||
reporter.now = function() {
|
||||
return 1000;
|
||||
};
|
||||
reporter.reportRunnerStarting();
|
||||
reporter.now = function() {
|
||||
return 1777;
|
||||
};
|
||||
reporter.reportRunnerResults(failingRun);
|
||||
expect(out.getOutput()).toContain("Finished in 0.777 seconds");
|
||||
});
|
||||
|
||||
it("prints round time numbers correctly", function() {
|
||||
function run(startTime, endTime) {
|
||||
out.clear();
|
||||
reporter.runnerStartTime = startTime;
|
||||
reporter.now = function() {
|
||||
return endTime;
|
||||
};
|
||||
reporter.reportRunnerResults(passingRun);
|
||||
}
|
||||
|
||||
run(1000, 11000);
|
||||
expect(out.getOutput()).toContain("10 seconds");
|
||||
|
||||
run(1000, 2000);
|
||||
expect(out.getOutput()).toContain("1 seconds");
|
||||
|
||||
run(1000, 1100);
|
||||
expect(out.getOutput()).toContain("0.1 seconds");
|
||||
|
||||
run(1000, 1010);
|
||||
expect(out.getOutput()).toContain("0.01 seconds");
|
||||
|
||||
run(1000, 1001);
|
||||
expect(out.getOutput()).toContain("0.001 seconds");
|
||||
});
|
||||
});
|
||||
|
||||
describe("when reporting the results summary", function() {
|
||||
it("prints statistics in green if there were no failures", function() {
|
||||
reporter.reportRunnerResults({
|
||||
specs: function() {
|
||||
return [null, null, null];
|
||||
},
|
||||
results:function() {
|
||||
return {items_: [null, null, null], totalCount: 7, failedCount: 0};
|
||||
}
|
||||
});
|
||||
expect(out.getOutput()).
|
||||
toContain("3 specs, 0 failures");
|
||||
});
|
||||
|
||||
it("prints statistics in red if there was a failure", function() {
|
||||
reporter.reportRunnerResults({
|
||||
specs: function() {
|
||||
return [null, null, null];
|
||||
},
|
||||
results:function() {
|
||||
return {items_: [null, null, null], totalCount: 7, failedCount: 3};
|
||||
}
|
||||
});
|
||||
expect(out.getOutput()).
|
||||
toContain("3 specs, 3 failures");
|
||||
});
|
||||
|
||||
it("handles pluralization with 1's ones appropriately", function() {
|
||||
reporter.reportRunnerResults({
|
||||
specs: function() {
|
||||
return [null];
|
||||
},
|
||||
results:function() {
|
||||
return {items_: [null], totalCount: 1, failedCount: 1};
|
||||
}
|
||||
});
|
||||
expect(out.getOutput()).
|
||||
toContain("1 spec, 1 failure");
|
||||
});
|
||||
});
|
||||
|
||||
describe("done callback", function() {
|
||||
it("calls back when done", function() {
|
||||
expect(done).toBeFalsy();
|
||||
reporter.reportRunnerResults({
|
||||
specs: function() {
|
||||
return [null, null, null];
|
||||
},
|
||||
results:function() {
|
||||
return {items_: [null, null, null], totalCount: 7, failedCount: 0};
|
||||
}
|
||||
});
|
||||
expect(done).toBeTruthy();
|
||||
});
|
||||
});
|
||||
it('calls it with false if there are suite failures', function() {
|
||||
reporter.specDone({status: "passed"});
|
||||
reporter.suiteDone({failedExpectations: [{ message: 'bananas' }] });
|
||||
reporter.jasmineDone();
|
||||
expect(onComplete).toHaveBeenCalledWith(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("with color", function() {
|
||||
it("reports that the suite has started to the console", function() {
|
||||
var reporter = new j$.ConsoleReporter({
|
||||
print: out.print,
|
||||
showColors: true
|
||||
});
|
||||
|
||||
reporter.jasmineStarted();
|
||||
|
||||
expect(out.getOutput()).toEqual("Started\n");
|
||||
});
|
||||
|
||||
it("reports a passing spec as a dot", function() {
|
||||
var reporter = new j$.ConsoleReporter({
|
||||
print: out.print,
|
||||
showColors: true
|
||||
});
|
||||
|
||||
reporter.specDone({status: "passed"});
|
||||
|
||||
expect(out.getOutput()).toEqual("\x1B[32m.\x1B[0m");
|
||||
});
|
||||
|
||||
it("does not report a disabled spec", function() {
|
||||
var reporter = new j$.ConsoleReporter({
|
||||
print: out.print,
|
||||
showColors: true
|
||||
});
|
||||
|
||||
reporter.specDone({status: 'disabled'});
|
||||
|
||||
expect(out.getOutput()).toEqual("");
|
||||
});
|
||||
|
||||
it("reports a failing spec as an 'F'", function() {
|
||||
var reporter = new j$.ConsoleReporter({
|
||||
print: out.print,
|
||||
showColors: true
|
||||
});
|
||||
|
||||
reporter.specDone({status: 'failed'});
|
||||
|
||||
expect(out.getOutput()).toEqual("\x1B[31mF\x1B[0m");
|
||||
});
|
||||
|
||||
it("displays all afterAll exceptions", function() {
|
||||
var reporter = new j$.ConsoleReporter({
|
||||
print: out.print,
|
||||
showColors: true
|
||||
});
|
||||
|
||||
reporter.suiteDone({ failedExpectations: [{ message: 'After All Exception' }] });
|
||||
reporter.suiteDone({ failedExpectations: [{ message: 'Some Other Exception' }] });
|
||||
reporter.jasmineDone();
|
||||
|
||||
expect(out.getOutput()).toMatch(/After All Exception/);
|
||||
expect(out.getOutput()).toMatch(/Some Other Exception/);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
46
spec/core/AnySpec.js
Normal file
46
spec/core/AnySpec.js
Normal file
@@ -0,0 +1,46 @@
|
||||
describe("Any", function() {
|
||||
it("matches a string", function() {
|
||||
var any = new j$.Any(String);
|
||||
|
||||
expect(any.jasmineMatches("foo")).toBe(true);
|
||||
});
|
||||
|
||||
it("matches a number", function() {
|
||||
var any = new j$.Any(Number);
|
||||
|
||||
expect(any.jasmineMatches(1)).toBe(true);
|
||||
});
|
||||
|
||||
it("matches a function", function() {
|
||||
var any = new j$.Any(Function);
|
||||
|
||||
expect(any.jasmineMatches(function(){})).toBe(true);
|
||||
});
|
||||
|
||||
it("matches an Object", function() {
|
||||
var any = new j$.Any(Object);
|
||||
|
||||
expect(any.jasmineMatches({})).toBe(true);
|
||||
});
|
||||
|
||||
it("matches a Boolean", function() {
|
||||
var any = new j$.Any(Boolean);
|
||||
|
||||
expect(any.jasmineMatches(true)).toBe(true);
|
||||
});
|
||||
|
||||
it("matches another constructed object", function() {
|
||||
var Thing = function() {},
|
||||
any = new j$.Any(Thing);
|
||||
|
||||
expect(any.jasmineMatches(new Thing())).toBe(true);
|
||||
});
|
||||
|
||||
it("jasmineToString's itself", function() {
|
||||
var any = new j$.Any(Number);
|
||||
|
||||
expect(any.jasmineToString()).toMatch('<jasmine.any');
|
||||
expect(any.jasmineToString()).toMatch('Number');
|
||||
});
|
||||
|
||||
});
|
||||
@@ -1,27 +0,0 @@
|
||||
describe("base.js", function() {
|
||||
describe("jasmine.MessageResult", function() {
|
||||
it("#toString should pretty-print and concatenate each part of the message", function() {
|
||||
var values = ["log", "message", 123, {key: "value"}, "FTW!"];
|
||||
var messageResult = new jasmine.MessageResult(values);
|
||||
expect(messageResult.toString()).toEqual("log message 123 { key : 'value' } FTW!");
|
||||
});
|
||||
});
|
||||
|
||||
describe("jasmine.log", function() {
|
||||
it("should accept n arguments", function() {
|
||||
spyOn(jasmine.getEnv().currentSpec, 'log');
|
||||
jasmine.log(1, 2, 3);
|
||||
expect(jasmine.getEnv().currentSpec.log).toHaveBeenCalledWith(1, 2, 3);
|
||||
});
|
||||
});
|
||||
|
||||
describe("jasmine.getGlobal", function() {
|
||||
it("should return the global object", function() {
|
||||
var globalObject = (function() {
|
||||
return this;
|
||||
})();
|
||||
|
||||
expect(jasmine.getGlobal()).toBe(globalObject);
|
||||
});
|
||||
});
|
||||
});
|
||||
105
spec/core/CallTrackerSpec.js
Normal file
105
spec/core/CallTrackerSpec.js
Normal file
@@ -0,0 +1,105 @@
|
||||
describe("CallTracker", function() {
|
||||
it("tracks that it was called when executed", function() {
|
||||
var callTracker = new j$.CallTracker();
|
||||
|
||||
expect(callTracker.any()).toBe(false);
|
||||
|
||||
callTracker.track();
|
||||
|
||||
expect(callTracker.any()).toBe(true);
|
||||
});
|
||||
|
||||
it("tracks that number of times that it is executed", function() {
|
||||
var callTracker = new j$.CallTracker();
|
||||
|
||||
expect(callTracker.count()).toEqual(0);
|
||||
|
||||
callTracker.track();
|
||||
|
||||
expect(callTracker.count()).toEqual(1);
|
||||
});
|
||||
|
||||
it("tracks the params from each execution", function() {
|
||||
var callTracker = new j$.CallTracker();
|
||||
|
||||
callTracker.track({object: void 0, args: []});
|
||||
callTracker.track({object: {}, args: [0, "foo"]});
|
||||
|
||||
expect(callTracker.argsFor(0)).toEqual([]);
|
||||
|
||||
expect(callTracker.argsFor(1)).toEqual([0, "foo"]);
|
||||
});
|
||||
|
||||
it("returns any empty array when there was no call", function() {
|
||||
var callTracker = new j$.CallTracker();
|
||||
|
||||
expect(callTracker.argsFor(0)).toEqual([]);
|
||||
});
|
||||
|
||||
it("allows access for the arguments for all calls", function() {
|
||||
var callTracker = new j$.CallTracker();
|
||||
|
||||
callTracker.track({object: {}, args: []});
|
||||
callTracker.track({object: {}, args: [0, "foo"]});
|
||||
|
||||
expect(callTracker.allArgs()).toEqual([[], [0, "foo"]]);
|
||||
});
|
||||
|
||||
it("tracks the context and arguments for each call", function() {
|
||||
var callTracker = new j$.CallTracker();
|
||||
|
||||
callTracker.track({object: {}, args: []});
|
||||
callTracker.track({object: {}, args: [0, "foo"]});
|
||||
|
||||
expect(callTracker.all()[0]).toEqual({object: {}, args: []});
|
||||
|
||||
expect(callTracker.all()[1]).toEqual({object: {}, args: [0, "foo"]});
|
||||
});
|
||||
|
||||
it("simplifies access to the arguments for the last (most recent) call", function() {
|
||||
var callTracker = new j$.CallTracker();
|
||||
|
||||
callTracker.track();
|
||||
callTracker.track({object: {}, args: [0, "foo"]});
|
||||
|
||||
expect(callTracker.mostRecent()).toEqual({
|
||||
object: {},
|
||||
args: [0, "foo"]
|
||||
});
|
||||
});
|
||||
|
||||
it("returns a useful falsy value when there isn't a last (most recent) call", function() {
|
||||
var callTracker = new j$.CallTracker();
|
||||
|
||||
expect(callTracker.mostRecent()).toBeFalsy();
|
||||
});
|
||||
|
||||
it("simplifies access to the arguments for the first (oldest) call", function() {
|
||||
var callTracker = new j$.CallTracker();
|
||||
|
||||
callTracker.track({object: {}, args: [0, "foo"]});
|
||||
|
||||
expect(callTracker.first()).toEqual({object: {}, args: [0, "foo"]})
|
||||
});
|
||||
|
||||
it("returns a useful falsy value when there isn't a first (oldest) call", function() {
|
||||
var callTracker = new j$.CallTracker();
|
||||
|
||||
expect(callTracker.first()).toBeFalsy();
|
||||
});
|
||||
|
||||
|
||||
it("allows the tracking to be reset", function() {
|
||||
var callTracker = new j$.CallTracker();
|
||||
|
||||
callTracker.track();
|
||||
callTracker.track({object: {}, args: [0, "foo"]});
|
||||
callTracker.reset();
|
||||
|
||||
expect(callTracker.any()).toBe(false);
|
||||
expect(callTracker.count()).toEqual(0);
|
||||
expect(callTracker.argsFor(0)).toEqual([]);
|
||||
expect(callTracker.all()).toEqual([]);
|
||||
expect(callTracker.mostRecent()).toBeFalsy();
|
||||
});
|
||||
});
|
||||
463
spec/core/ClockSpec.js
Normal file
463
spec/core/ClockSpec.js
Normal file
@@ -0,0 +1,463 @@
|
||||
describe("Clock", function() {
|
||||
|
||||
it("does not replace setTimeout until it is installed", function() {
|
||||
var fakeSetTimeout = jasmine.createSpy("global setTimeout"),
|
||||
fakeGlobal = { setTimeout: fakeSetTimeout },
|
||||
delayedFunctionScheduler = jasmine.createSpyObj("delayedFunctionScheduler", ["scheduleFunction"]),
|
||||
delayedFn = jasmine.createSpy("delayedFn"),
|
||||
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
|
||||
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler, mockDate);
|
||||
|
||||
fakeGlobal.setTimeout(delayedFn, 0);
|
||||
|
||||
expect(fakeSetTimeout).toHaveBeenCalledWith(delayedFn, 0);
|
||||
expect(delayedFunctionScheduler.scheduleFunction).not.toHaveBeenCalled();
|
||||
|
||||
fakeSetTimeout.calls.reset();
|
||||
|
||||
clock.install();
|
||||
fakeGlobal.setTimeout(delayedFn, 0);
|
||||
|
||||
expect(delayedFunctionScheduler.scheduleFunction).toHaveBeenCalled();
|
||||
expect(fakeSetTimeout).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("does not replace clearTimeout until it is installed", function() {
|
||||
var fakeClearTimeout = jasmine.createSpy("global cleartimeout"),
|
||||
fakeGlobal = { clearTimeout: fakeClearTimeout },
|
||||
delayedFunctionScheduler = jasmine.createSpyObj("delayedFunctionScheduler", ["removeFunctionWithId"]),
|
||||
delayedFn = jasmine.createSpy("delayedFn"),
|
||||
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
|
||||
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler, mockDate);
|
||||
|
||||
fakeGlobal.clearTimeout("foo");
|
||||
|
||||
expect(fakeClearTimeout).toHaveBeenCalledWith("foo");
|
||||
expect(delayedFunctionScheduler.removeFunctionWithId).not.toHaveBeenCalled();
|
||||
|
||||
fakeClearTimeout.calls.reset();
|
||||
|
||||
clock.install();
|
||||
fakeGlobal.clearTimeout("foo");
|
||||
|
||||
expect(delayedFunctionScheduler.removeFunctionWithId).toHaveBeenCalled();
|
||||
expect(fakeClearTimeout).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("does not replace setInterval until it is installed", function() {
|
||||
var fakeSetInterval = jasmine.createSpy("global setInterval"),
|
||||
fakeGlobal = { setInterval: fakeSetInterval },
|
||||
delayedFunctionScheduler = jasmine.createSpyObj("delayedFunctionScheduler", ["scheduleFunction"]),
|
||||
delayedFn = jasmine.createSpy("delayedFn"),
|
||||
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
|
||||
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler, mockDate);
|
||||
|
||||
fakeGlobal.setInterval(delayedFn, 0);
|
||||
|
||||
expect(fakeSetInterval).toHaveBeenCalledWith(delayedFn, 0);
|
||||
expect(delayedFunctionScheduler.scheduleFunction).not.toHaveBeenCalled();
|
||||
|
||||
fakeSetInterval.calls.reset();
|
||||
|
||||
clock.install();
|
||||
fakeGlobal.setInterval(delayedFn, 0);
|
||||
|
||||
expect(delayedFunctionScheduler.scheduleFunction).toHaveBeenCalled();
|
||||
expect(fakeSetInterval).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("does not replace clearInterval until it is installed", function() {
|
||||
var fakeClearInterval = jasmine.createSpy("global clearinterval"),
|
||||
fakeGlobal = { clearInterval: fakeClearInterval },
|
||||
delayedFunctionScheduler = jasmine.createSpyObj("delayedFunctionScheduler", ["removeFunctionWithId"]),
|
||||
delayedFn = jasmine.createSpy("delayedFn"),
|
||||
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
|
||||
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler, mockDate);
|
||||
|
||||
fakeGlobal.clearInterval("foo");
|
||||
|
||||
expect(fakeClearInterval).toHaveBeenCalledWith("foo");
|
||||
expect(delayedFunctionScheduler.removeFunctionWithId).not.toHaveBeenCalled();
|
||||
|
||||
fakeClearInterval.calls.reset();
|
||||
|
||||
clock.install();
|
||||
fakeGlobal.clearInterval("foo");
|
||||
|
||||
expect(delayedFunctionScheduler.removeFunctionWithId).toHaveBeenCalled();
|
||||
expect(fakeClearInterval).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("replaces the global timer functions on uninstall", function() {
|
||||
var fakeSetTimeout = jasmine.createSpy("global setTimeout"),
|
||||
fakeClearTimeout = jasmine.createSpy("global clearTimeout"),
|
||||
fakeSetInterval = jasmine.createSpy("global setInterval"),
|
||||
fakeClearInterval = jasmine.createSpy("global clearInterval"),
|
||||
fakeGlobal = {
|
||||
setTimeout: fakeSetTimeout,
|
||||
clearTimeout: fakeClearTimeout,
|
||||
setInterval: fakeSetInterval,
|
||||
clearInterval: fakeClearInterval
|
||||
},
|
||||
delayedFunctionScheduler = jasmine.createSpyObj("delayedFunctionScheduler", ["scheduleFunction", "reset"]),
|
||||
delayedFn = jasmine.createSpy("delayedFn"),
|
||||
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
|
||||
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler, mockDate);
|
||||
|
||||
clock.install();
|
||||
clock.uninstall();
|
||||
fakeGlobal.setTimeout(delayedFn, 0);
|
||||
fakeGlobal.clearTimeout("foo");
|
||||
fakeGlobal.setInterval(delayedFn, 10);
|
||||
fakeGlobal.clearInterval("bar");
|
||||
|
||||
expect(fakeSetTimeout).toHaveBeenCalledWith(delayedFn, 0);
|
||||
expect(fakeClearTimeout).toHaveBeenCalledWith("foo");
|
||||
expect(fakeSetInterval).toHaveBeenCalledWith(delayedFn, 10);
|
||||
expect(fakeClearInterval).toHaveBeenCalledWith("bar");
|
||||
expect(delayedFunctionScheduler.scheduleFunction).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("schedules the delayed function (via setTimeout) with the fake timer", function() {
|
||||
var fakeSetTimeout = jasmine.createSpy('setTimeout'),
|
||||
scheduleFunction = jasmine.createSpy('scheduleFunction'),
|
||||
delayedFunctionScheduler = { scheduleFunction: scheduleFunction },
|
||||
fakeGlobal = { setTimeout: fakeSetTimeout },
|
||||
delayedFn = jasmine.createSpy('delayedFn'),
|
||||
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
|
||||
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler, mockDate);
|
||||
|
||||
clock.install();
|
||||
clock.setTimeout(delayedFn, 0, 'a', 'b');
|
||||
|
||||
expect(fakeSetTimeout).not.toHaveBeenCalled();
|
||||
expect(delayedFunctionScheduler.scheduleFunction).toHaveBeenCalledWith(delayedFn, 0, ['a', 'b']);
|
||||
});
|
||||
|
||||
it("returns an id for the delayed function", function() {
|
||||
var fakeSetTimeout = jasmine.createSpy('setTimeout'),
|
||||
scheduleId = 123,
|
||||
scheduleFunction = jasmine.createSpy('scheduleFunction').and.returnValue(scheduleId),
|
||||
delayedFunctionScheduler = {scheduleFunction: scheduleFunction},
|
||||
fakeGlobal = { setTimeout: fakeSetTimeout },
|
||||
delayedFn = jasmine.createSpy('delayedFn'),
|
||||
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
|
||||
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler, mockDate),
|
||||
timeoutId;
|
||||
|
||||
clock.install();
|
||||
timeoutId = clock.setTimeout(delayedFn, 0);
|
||||
|
||||
expect(timeoutId).toEqual(123);
|
||||
});
|
||||
|
||||
it("clears the scheduled function with the scheduler", function() {
|
||||
var fakeClearTimeout = jasmine.createSpy('clearTimeout'),
|
||||
delayedFunctionScheduler = jasmine.createSpyObj('delayedFunctionScheduler', ['removeFunctionWithId']),
|
||||
fakeGlobal = { setTimeout: fakeClearTimeout },
|
||||
delayedFn = jasmine.createSpy('delayedFn'),
|
||||
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
|
||||
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler, mockDate);
|
||||
|
||||
clock.install();
|
||||
clock.clearTimeout(123);
|
||||
|
||||
expect(fakeClearTimeout).not.toHaveBeenCalled();
|
||||
expect(delayedFunctionScheduler.removeFunctionWithId).toHaveBeenCalledWith(123);
|
||||
});
|
||||
|
||||
it("schedules the delayed function with the fake timer", function() {
|
||||
var fakeSetInterval = jasmine.createSpy('setInterval'),
|
||||
scheduleFunction = jasmine.createSpy('scheduleFunction'),
|
||||
delayedFunctionScheduler = {scheduleFunction: scheduleFunction},
|
||||
fakeGlobal = { setInterval: fakeSetInterval },
|
||||
delayedFn = jasmine.createSpy('delayedFn'),
|
||||
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
|
||||
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler, mockDate);
|
||||
|
||||
clock.install();
|
||||
clock.setInterval(delayedFn, 0, 'a', 'b');
|
||||
|
||||
expect(fakeSetInterval).not.toHaveBeenCalled();
|
||||
expect(delayedFunctionScheduler.scheduleFunction).toHaveBeenCalledWith(delayedFn, 0, ['a', 'b'], true);
|
||||
});
|
||||
|
||||
it("returns an id for the delayed function", function() {
|
||||
var fakeSetInterval = jasmine.createSpy('setInterval'),
|
||||
scheduleId = 123,
|
||||
scheduleFunction = jasmine.createSpy('scheduleFunction').and.returnValue(scheduleId),
|
||||
delayedFunctionScheduler = {scheduleFunction: scheduleFunction},
|
||||
fakeGlobal = { setInterval: fakeSetInterval },
|
||||
delayedFn = jasmine.createSpy('delayedFn'),
|
||||
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
|
||||
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler, mockDate),
|
||||
intervalId;
|
||||
|
||||
clock.install();
|
||||
intervalId = clock.setInterval(delayedFn, 0);
|
||||
|
||||
expect(intervalId).toEqual(123);
|
||||
});
|
||||
|
||||
it("clears the scheduled function with the scheduler", function() {
|
||||
var clearInterval = jasmine.createSpy('clearInterval'),
|
||||
delayedFunctionScheduler = jasmine.createSpyObj('delayedFunctionScheduler', ['removeFunctionWithId']),
|
||||
fakeGlobal = { setInterval: clearInterval },
|
||||
delayedFn = jasmine.createSpy('delayedFn'),
|
||||
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
|
||||
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler, mockDate);
|
||||
|
||||
clock.install();
|
||||
clock.clearInterval(123);
|
||||
|
||||
expect(clearInterval).not.toHaveBeenCalled();
|
||||
expect(delayedFunctionScheduler.removeFunctionWithId).toHaveBeenCalledWith(123);
|
||||
});
|
||||
|
||||
it("gives you a friendly reminder if the Clock is not installed and you tick", function() {
|
||||
var clock = new j$.Clock({}, jasmine.createSpyObj('delayedFunctionScheduler', ['tick']));
|
||||
expect(function() {
|
||||
clock.tick(50);
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
it("on IE < 9, fails if extra args are passed to fake clock", function() {
|
||||
//fail, because this would break in IE9.
|
||||
var fakeSetTimeout = jasmine.createSpy('setTimeout'),
|
||||
fakeSetInterval = jasmine.createSpy('setInterval'),
|
||||
delayedFunctionScheduler = jasmine.createSpyObj('delayedFunctionScheduler', ['scheduleFunction']),
|
||||
fn = jasmine.createSpy('fn'),
|
||||
fakeGlobal = {
|
||||
setTimeout: fakeSetTimeout,
|
||||
setInterval: fakeSetInterval
|
||||
},
|
||||
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
|
||||
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler, mockDate);
|
||||
|
||||
fakeSetTimeout.apply = null;
|
||||
fakeSetInterval.apply = null;
|
||||
|
||||
clock.install();
|
||||
|
||||
clock.setTimeout(fn, 0);
|
||||
expect(delayedFunctionScheduler.scheduleFunction).toHaveBeenCalledWith(fn, 0, []);
|
||||
expect(function() {
|
||||
clock.setTimeout(fn, 0, 'extra');
|
||||
}).toThrow();
|
||||
|
||||
clock.setInterval(fn, 0);
|
||||
expect(delayedFunctionScheduler.scheduleFunction).toHaveBeenCalledWith(fn, 0, [], true);
|
||||
expect(function() {
|
||||
clock.setInterval(fn, 0, 'extra');
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe("Clock (acceptance)", function() {
|
||||
it("can run setTimeouts/setIntervals synchronously", function() {
|
||||
var delayedFn1 = jasmine.createSpy('delayedFn1'),
|
||||
delayedFn2 = jasmine.createSpy('delayedFn2'),
|
||||
delayedFn3 = jasmine.createSpy('delayedFn3'),
|
||||
recurring1 = jasmine.createSpy('recurring1'),
|
||||
delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
|
||||
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
|
||||
clock = new j$.Clock({setTimeout: setTimeout}, delayedFunctionScheduler, mockDate);
|
||||
|
||||
clock.install();
|
||||
|
||||
clock.setTimeout(delayedFn1, 0);
|
||||
var intervalId = clock.setInterval(recurring1, 50);
|
||||
clock.setTimeout(delayedFn2, 100);
|
||||
clock.setTimeout(delayedFn3, 200);
|
||||
|
||||
expect(delayedFn1).not.toHaveBeenCalled();
|
||||
expect(delayedFn2).not.toHaveBeenCalled();
|
||||
expect(delayedFn3).not.toHaveBeenCalled();
|
||||
|
||||
clock.tick(0);
|
||||
|
||||
expect(delayedFn1).toHaveBeenCalled();
|
||||
expect(delayedFn2).not.toHaveBeenCalled();
|
||||
expect(delayedFn3).not.toHaveBeenCalled();
|
||||
|
||||
clock.tick(50);
|
||||
|
||||
expect(recurring1).toHaveBeenCalled();
|
||||
expect(recurring1.calls.count()).toBe(1);
|
||||
expect(delayedFn2).not.toHaveBeenCalled();
|
||||
expect(delayedFn3).not.toHaveBeenCalled();
|
||||
|
||||
clock.tick(50);
|
||||
|
||||
expect(recurring1.calls.count()).toBe(2);
|
||||
expect(delayedFn2).toHaveBeenCalled();
|
||||
expect(delayedFn3).not.toHaveBeenCalled();
|
||||
|
||||
clock.tick(100);
|
||||
|
||||
expect(recurring1.calls.count()).toBe(4);
|
||||
expect(delayedFn3).toHaveBeenCalled();
|
||||
|
||||
clock.clearInterval(intervalId);
|
||||
clock.tick(50);
|
||||
|
||||
expect(recurring1.calls.count()).toBe(4);
|
||||
});
|
||||
|
||||
it("can clear a previously set timeout", function() {
|
||||
var clearedFn = jasmine.createSpy('clearedFn'),
|
||||
delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
|
||||
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
|
||||
clock = new j$.Clock({setTimeout: function() {}}, delayedFunctionScheduler, mockDate),
|
||||
timeoutId;
|
||||
|
||||
clock.install();
|
||||
|
||||
timeoutId = clock.setTimeout(clearedFn, 100);
|
||||
expect(clearedFn).not.toHaveBeenCalled();
|
||||
|
||||
clock.clearTimeout(timeoutId);
|
||||
clock.tick(100);
|
||||
|
||||
expect(clearedFn).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("can clear a previously set interval using that interval's handler", function() {
|
||||
var spy = jasmine.createSpy('spy'),
|
||||
delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
|
||||
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
|
||||
clock = new j$.Clock({setInterval: function() {}}, delayedFunctionScheduler, mockDate),
|
||||
intervalId;
|
||||
|
||||
clock.install();
|
||||
|
||||
intervalId = clock.setInterval(function() {
|
||||
spy();
|
||||
clock.clearInterval(intervalId);
|
||||
}, 100);
|
||||
clock.tick(200);
|
||||
|
||||
expect(spy.calls.count()).toEqual(1);
|
||||
});
|
||||
|
||||
it("correctly schedules functions after the Clock has advanced", function() {
|
||||
var delayedFn1 = jasmine.createSpy('delayedFn1'),
|
||||
delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
|
||||
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
|
||||
clock = new j$.Clock({setTimeout: function() {}}, delayedFunctionScheduler, mockDate);
|
||||
|
||||
clock.install();
|
||||
|
||||
clock.tick(100);
|
||||
clock.setTimeout(delayedFn1, 10, ['some', 'arg']);
|
||||
clock.tick(5);
|
||||
expect(delayedFn1).not.toHaveBeenCalled();
|
||||
clock.tick(5);
|
||||
expect(delayedFn1).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("correctly schedules functions while the Clock is advancing", function() {
|
||||
var delayedFn1 = jasmine.createSpy('delayedFn1'),
|
||||
delayedFn2 = jasmine.createSpy('delayedFn2'),
|
||||
delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
|
||||
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
|
||||
clock = new j$.Clock({setTimeout: function() {}}, delayedFunctionScheduler, mockDate);
|
||||
|
||||
delayedFn1.and.callFake(function() { clock.setTimeout(delayedFn2, 0); });
|
||||
clock.install();
|
||||
clock.setTimeout(delayedFn1, 5);
|
||||
|
||||
clock.tick(5);
|
||||
expect(delayedFn1).toHaveBeenCalled();
|
||||
expect(delayedFn2).not.toHaveBeenCalled();
|
||||
|
||||
clock.tick();
|
||||
expect(delayedFn2).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("correctly calls functions scheduled while the Clock is advancing", function() {
|
||||
var delayedFn1 = jasmine.createSpy('delayedFn1'),
|
||||
delayedFn2 = jasmine.createSpy('delayedFn2'),
|
||||
delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
|
||||
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
|
||||
clock = new j$.Clock({setTimeout: function() {}}, delayedFunctionScheduler, mockDate);
|
||||
|
||||
delayedFn1.and.callFake(function() { clock.setTimeout(delayedFn2, 1); });
|
||||
clock.install();
|
||||
clock.setTimeout(delayedFn1, 5);
|
||||
|
||||
clock.tick(6);
|
||||
expect(delayedFn1).toHaveBeenCalled();
|
||||
expect(delayedFn2).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("does not mock the Date object by default", function() {
|
||||
var delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
|
||||
global = {Date: Date},
|
||||
mockDate = new j$.MockDate(global),
|
||||
clock = new j$.Clock({setTimeout: setTimeout}, delayedFunctionScheduler, mockDate);
|
||||
|
||||
clock.install();
|
||||
|
||||
expect(global.Date).toEqual(Date);
|
||||
|
||||
var now = new global.Date().getTime();
|
||||
|
||||
clock.tick(50);
|
||||
|
||||
expect(new global.Date().getTime() - now).not.toEqual(50);
|
||||
});
|
||||
|
||||
it("mocks the Date object and sets it to current time", function() {
|
||||
var delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
|
||||
global = {Date: Date},
|
||||
mockDate = new j$.MockDate(global),
|
||||
clock = new j$.Clock({setTimeout: setTimeout}, delayedFunctionScheduler, mockDate);
|
||||
|
||||
clock.install().mockDate();
|
||||
|
||||
var now = new global.Date().getTime();
|
||||
|
||||
clock.tick(50);
|
||||
|
||||
expect(new global.Date().getTime() - now).toEqual(50);
|
||||
|
||||
var timeoutDate = 0;
|
||||
clock.setTimeout(function() {
|
||||
timeoutDate = new global.Date().getTime();
|
||||
}, 100);
|
||||
|
||||
clock.tick(100);
|
||||
|
||||
expect(timeoutDate - now).toEqual(150);
|
||||
});
|
||||
|
||||
it("mocks the Date object and sets it to a given time", function() {
|
||||
var delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
|
||||
global = {Date: Date},
|
||||
mockDate = new j$.MockDate(global),
|
||||
clock = new j$.Clock({setTimeout: setTimeout}, delayedFunctionScheduler, mockDate),
|
||||
baseTime = new Date(2013, 9, 23);
|
||||
|
||||
|
||||
clock.install().mockDate(baseTime);
|
||||
|
||||
var now = new global.Date().getTime();
|
||||
|
||||
expect(now).toEqual(baseTime.getTime());
|
||||
|
||||
clock.tick(50);
|
||||
|
||||
expect(new global.Date().getTime()).toEqual(baseTime.getTime() + 50);
|
||||
|
||||
var timeoutDate = 0;
|
||||
clock.setTimeout(function() {
|
||||
timeoutDate = new global.Date().getTime();
|
||||
}, 100);
|
||||
|
||||
clock.tick(100);
|
||||
|
||||
expect(timeoutDate).toEqual(baseTime.getTime() + 150);
|
||||
});
|
||||
});
|
||||
@@ -1,97 +0,0 @@
|
||||
describe("Custom Matchers", function() {
|
||||
var env;
|
||||
var fakeTimer;
|
||||
|
||||
beforeEach(function() {
|
||||
env = new jasmine.Env();
|
||||
env.updateInterval = 0;
|
||||
});
|
||||
|
||||
it("should be easy to add more matchers local to a spec, suite, etc.", function() {
|
||||
var spec1, spec2, spec1Matcher, spec2Matcher;
|
||||
var suite = env.describe('some suite', function() {
|
||||
env.beforeEach(function() {
|
||||
this.addMatchers({
|
||||
matcherForSuite: function(expected) {
|
||||
this.message = "matcherForSuite: actual: " + this.actual + "; expected: " + expected;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
spec1 = env.it('spec with an expectation').runs(function () {
|
||||
this.addMatchers({
|
||||
matcherForSpec: function(expected) {
|
||||
this.message = "matcherForSpec: actual: " + this.actual + "; expected: " + expected;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
spec1Matcher = this.expect("xxx");
|
||||
});
|
||||
|
||||
spec2 = env.it('spec with failing expectation').runs(function () {
|
||||
spec2Matcher = this.expect("yyy");
|
||||
});
|
||||
});
|
||||
|
||||
suite.execute();
|
||||
|
||||
spec1Matcher.matcherForSuite("expected");
|
||||
expect(spec1Matcher.message).toEqual("matcherForSuite: actual: xxx; expected: expected");
|
||||
spec1Matcher.matcherForSpec("expected");
|
||||
expect(spec1Matcher.message).toEqual("matcherForSpec: actual: xxx; expected: expected");
|
||||
|
||||
spec2Matcher.matcherForSuite("expected");
|
||||
expect(spec2Matcher.message).toEqual("matcherForSuite: actual: yyy; expected: expected");
|
||||
expect(spec2Matcher.matcherForSpec).toBe(jasmine.undefined);
|
||||
});
|
||||
|
||||
it("should generate messages with the same rules as for regular matchers when this.report() is not called", function() {
|
||||
var spec;
|
||||
var suite = env.describe('some suite', function() {
|
||||
spec = env.it('spec with an expectation').runs(function () {
|
||||
this.addMatchers({
|
||||
toBeTrue: function() {
|
||||
return this.actual === true;
|
||||
}
|
||||
});
|
||||
this.expect(true).toBeTrue();
|
||||
this.expect(false).toBeTrue();
|
||||
});
|
||||
});
|
||||
|
||||
suite.execute();
|
||||
var passResult = new jasmine.ExpectationResult({passed: true, matcherName: 'toBeTrue',
|
||||
actual: true, expected: jasmine.undefined, message: "Passed." });
|
||||
var failResult = new jasmine.ExpectationResult({passed: false, matcherName: 'toBeTrue',
|
||||
actual: false, expected: jasmine.undefined, message: "Expected false to be true." });
|
||||
failResult.trace = jasmine.any(Object);
|
||||
expect(spec.results().getItems()).toEqual([passResult, failResult]);
|
||||
});
|
||||
|
||||
it("should pass args", function() {
|
||||
var matcherCallArgs = [];
|
||||
var spec;
|
||||
var suite = env.describe('some suite', function() {
|
||||
spec = env.it('spec with an expectation').runs(function () {
|
||||
this.addMatchers({
|
||||
toBeTrue: function() {
|
||||
matcherCallArgs.push(jasmine.util.argsToArray(arguments));
|
||||
return this.actual === true;
|
||||
}
|
||||
});
|
||||
this.expect(true).toBeTrue();
|
||||
this.expect(false).toBeTrue('arg');
|
||||
this.expect(true).toBeTrue('arg1', 'arg2');
|
||||
});
|
||||
});
|
||||
|
||||
suite.execute();
|
||||
var results = spec.results().getItems();
|
||||
expect(results[0].expected).toEqual(jasmine.undefined);
|
||||
expect(results[1].expected).toEqual('arg');
|
||||
expect(results[2].expected).toEqual(['arg1', 'arg2']);
|
||||
|
||||
expect(matcherCallArgs).toEqual([[], ['arg'], ['arg1', 'arg2']]);
|
||||
});
|
||||
});
|
||||
259
spec/core/DelayedFunctionSchedulerSpec.js
Normal file
259
spec/core/DelayedFunctionSchedulerSpec.js
Normal file
@@ -0,0 +1,259 @@
|
||||
describe("DelayedFunctionScheduler", function() {
|
||||
it("schedules a function for later execution", function() {
|
||||
var scheduler = new j$.DelayedFunctionScheduler(),
|
||||
fn = jasmine.createSpy('fn');
|
||||
|
||||
scheduler.scheduleFunction(fn, 0);
|
||||
|
||||
expect(fn).not.toHaveBeenCalled();
|
||||
|
||||
scheduler.tick(0);
|
||||
|
||||
expect(fn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("schedules a string for later execution", function() {
|
||||
var scheduler = new j$.DelayedFunctionScheduler(),
|
||||
strfn = "horrible = true;";
|
||||
|
||||
scheduler.scheduleFunction(strfn, 0);
|
||||
|
||||
scheduler.tick(0);
|
||||
|
||||
expect(horrible).toEqual(true);
|
||||
});
|
||||
|
||||
it("#tick defaults to 0", function() {
|
||||
var scheduler = new j$.DelayedFunctionScheduler(),
|
||||
fn = jasmine.createSpy('fn');
|
||||
|
||||
scheduler.scheduleFunction(fn, 0);
|
||||
|
||||
expect(fn).not.toHaveBeenCalled();
|
||||
|
||||
scheduler.tick();
|
||||
|
||||
expect(fn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("defaults delay to 0", function() {
|
||||
var scheduler = new j$.DelayedFunctionScheduler(),
|
||||
fn = jasmine.createSpy('fn');
|
||||
|
||||
scheduler.scheduleFunction(fn);
|
||||
|
||||
expect(fn).not.toHaveBeenCalled();
|
||||
|
||||
scheduler.tick(0);
|
||||
|
||||
expect(fn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("optionally passes params to scheduled functions", function() {
|
||||
var scheduler = new j$.DelayedFunctionScheduler(),
|
||||
fn = jasmine.createSpy('fn');
|
||||
|
||||
scheduler.scheduleFunction(fn, 0, ['foo', 'bar']);
|
||||
|
||||
expect(fn).not.toHaveBeenCalled();
|
||||
|
||||
scheduler.tick(0);
|
||||
|
||||
expect(fn).toHaveBeenCalledWith('foo', 'bar');
|
||||
});
|
||||
|
||||
it("scheduled fns can optionally reoccur", function() {
|
||||
var scheduler = new j$.DelayedFunctionScheduler(),
|
||||
fn = jasmine.createSpy('fn');
|
||||
|
||||
scheduler.scheduleFunction(fn, 20, [], true);
|
||||
|
||||
expect(fn).not.toHaveBeenCalled();
|
||||
|
||||
scheduler.tick(20);
|
||||
|
||||
expect(fn.calls.count()).toBe(1);
|
||||
|
||||
scheduler.tick(40);
|
||||
|
||||
expect(fn.calls.count()).toBe(3);
|
||||
|
||||
scheduler.tick(21);
|
||||
|
||||
expect(fn.calls.count()).toBe(4);
|
||||
|
||||
});
|
||||
|
||||
it("increments scheduled fns ids unless one is passed", function() {
|
||||
var scheduler = new j$.DelayedFunctionScheduler();
|
||||
|
||||
expect(scheduler.scheduleFunction(function() {
|
||||
}, 0)).toBe(1);
|
||||
expect(scheduler.scheduleFunction(function() {
|
||||
}, 0)).toBe(2);
|
||||
expect(scheduler.scheduleFunction(function() {
|
||||
}, 0, [], false, 123)).toBe(123);
|
||||
expect(scheduler.scheduleFunction(function() {
|
||||
}, 0)).toBe(3);
|
||||
});
|
||||
|
||||
it("#removeFunctionWithId removes a previously scheduled function with a given id", function() {
|
||||
var scheduler = new j$.DelayedFunctionScheduler(),
|
||||
fn = jasmine.createSpy('fn'),
|
||||
timeoutKey;
|
||||
|
||||
timeoutKey = scheduler.scheduleFunction(fn, 0);
|
||||
|
||||
expect(fn).not.toHaveBeenCalled();
|
||||
|
||||
scheduler.removeFunctionWithId(timeoutKey);
|
||||
|
||||
scheduler.tick(0);
|
||||
|
||||
expect(fn).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("reset removes scheduled functions", function() {
|
||||
var scheduler = new j$.DelayedFunctionScheduler(),
|
||||
fn = jasmine.createSpy('fn');
|
||||
|
||||
scheduler.scheduleFunction(fn, 0);
|
||||
|
||||
expect(fn).not.toHaveBeenCalled();
|
||||
|
||||
scheduler.reset();
|
||||
|
||||
scheduler.tick(0);
|
||||
|
||||
expect(fn).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("reset resets the returned ids", function() {
|
||||
var scheduler = new j$.DelayedFunctionScheduler();
|
||||
expect(scheduler.scheduleFunction(function() { }, 0)).toBe(1);
|
||||
expect(scheduler.scheduleFunction(function() { }, 0, [], false, 123)).toBe(123);
|
||||
|
||||
scheduler.reset();
|
||||
expect(scheduler.scheduleFunction(function() { }, 0)).toBe(1);
|
||||
expect(scheduler.scheduleFunction(function() { }, 0, [], false, 123)).toBe(123);
|
||||
});
|
||||
|
||||
it("reset resets the current tick time", function() {
|
||||
var scheduler = new j$.DelayedFunctionScheduler(),
|
||||
fn = jasmine.createSpy('fn');
|
||||
|
||||
expect(fn).not.toHaveBeenCalled();
|
||||
|
||||
scheduler.tick(15);
|
||||
scheduler.reset();
|
||||
|
||||
scheduler.scheduleFunction(fn, 20, [], false, 1, 20);
|
||||
|
||||
scheduler.tick(5);
|
||||
|
||||
expect(fn).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("executes recurring functions interleaved with regular functions in the correct order", function() {
|
||||
var scheduler = new j$.DelayedFunctionScheduler(),
|
||||
fn = jasmine.createSpy('fn'),
|
||||
recurringCallCount = 0,
|
||||
recurring = jasmine.createSpy('recurring').and.callFake(function() {
|
||||
recurringCallCount++;
|
||||
if (recurringCallCount < 5) {
|
||||
expect(fn).not.toHaveBeenCalled();
|
||||
}
|
||||
});
|
||||
|
||||
scheduler.scheduleFunction(recurring, 10, [], true);
|
||||
scheduler.scheduleFunction(fn, 50);
|
||||
|
||||
scheduler.tick(60);
|
||||
|
||||
expect(recurring).toHaveBeenCalled();
|
||||
expect(recurring.calls.count()).toBe(6);
|
||||
expect(fn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("schedules a function for later execution during a tick", function () {
|
||||
var scheduler = new j$.DelayedFunctionScheduler(),
|
||||
fn = jasmine.createSpy('fn'),
|
||||
fnDelay = 10;
|
||||
|
||||
scheduler.scheduleFunction(function () {
|
||||
scheduler.scheduleFunction(fn, fnDelay);
|
||||
}, 0);
|
||||
|
||||
expect(fn).not.toHaveBeenCalled();
|
||||
|
||||
scheduler.tick(fnDelay);
|
||||
|
||||
expect(fn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("#removeFunctionWithId removes a previously scheduled function with a given id during a tick", function () {
|
||||
var scheduler = new j$.DelayedFunctionScheduler(),
|
||||
fn = jasmine.createSpy('fn'),
|
||||
fnDelay = 10,
|
||||
timeoutKey;
|
||||
|
||||
scheduler.scheduleFunction(function () {
|
||||
scheduler.removeFunctionWithId(timeoutKey);
|
||||
}, 0);
|
||||
timeoutKey = scheduler.scheduleFunction(fn, fnDelay);
|
||||
|
||||
expect(fn).not.toHaveBeenCalled();
|
||||
|
||||
scheduler.tick(fnDelay);
|
||||
|
||||
expect(fn).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("executes recurring functions interleaved with regular functions and functions scheduled during a tick in the correct order", function () {
|
||||
var scheduler = new j$.DelayedFunctionScheduler(),
|
||||
fn = jasmine.createSpy('fn'),
|
||||
recurringCallCount = 0,
|
||||
recurring = jasmine.createSpy('recurring').and.callFake(function() {
|
||||
recurringCallCount++;
|
||||
if (recurringCallCount < 5) {
|
||||
expect(fn).not.toHaveBeenCalled();
|
||||
}
|
||||
}),
|
||||
innerFn = jasmine.createSpy('innerFn').and.callFake(function() {
|
||||
expect(recurring.calls.count()).toBe(4);
|
||||
expect(fn).not.toHaveBeenCalled();
|
||||
}),
|
||||
scheduling = jasmine.createSpy('scheduling').and.callFake(function() {
|
||||
expect(recurring.calls.count()).toBe(3);
|
||||
expect(fn).not.toHaveBeenCalled();
|
||||
scheduler.scheduleFunction(innerFn, 10); // 41ms absolute
|
||||
});
|
||||
|
||||
scheduler.scheduleFunction(recurring, 10, [], true);
|
||||
scheduler.scheduleFunction(fn, 50);
|
||||
scheduler.scheduleFunction(scheduling, 31);
|
||||
|
||||
scheduler.tick(60);
|
||||
|
||||
expect(recurring).toHaveBeenCalled();
|
||||
expect(recurring.calls.count()).toBe(6);
|
||||
expect(fn).toHaveBeenCalled();
|
||||
expect(scheduling).toHaveBeenCalled();
|
||||
expect(innerFn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("executes recurring functions after rescheduling them", function () {
|
||||
var scheduler = new j$.DelayedFunctionScheduler(),
|
||||
recurring = function() {
|
||||
expect(scheduler.scheduleFunction).toHaveBeenCalled();
|
||||
};
|
||||
|
||||
scheduler.scheduleFunction(recurring, 10, [], true);
|
||||
|
||||
spyOn(scheduler, "scheduleFunction");
|
||||
|
||||
scheduler.tick(10);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -1,159 +1,22 @@
|
||||
describe("jasmine.Env", function() {
|
||||
// TODO: Fix these unit tests!
|
||||
describe("Env", function() {
|
||||
var env;
|
||||
beforeEach(function() {
|
||||
env = new jasmine.Env();
|
||||
env.updateInterval = 0;
|
||||
env = new j$.Env();
|
||||
});
|
||||
|
||||
describe('ids', function () {
|
||||
it('nextSpecId should return consecutive integers, starting at 0', function () {
|
||||
expect(env.nextSpecId()).toEqual(0);
|
||||
expect(env.nextSpecId()).toEqual(1);
|
||||
expect(env.nextSpecId()).toEqual(2);
|
||||
describe("#pending", function() {
|
||||
it("throws the Pending Spec exception", function() {
|
||||
expect(function() {
|
||||
env.pending();
|
||||
}).toThrow(j$.Spec.pendingSpecExceptionMessage);
|
||||
});
|
||||
});
|
||||
|
||||
describe("reporting", function() {
|
||||
var fakeReporter;
|
||||
|
||||
beforeEach(function() {
|
||||
fakeReporter = jasmine.createSpyObj("fakeReporter", ["log"]);
|
||||
});
|
||||
|
||||
describe('version', function () {
|
||||
var oldVersion;
|
||||
|
||||
beforeEach(function () {
|
||||
oldVersion = jasmine.version_;
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
jasmine.version_ = oldVersion;
|
||||
});
|
||||
|
||||
it('should raise an error if version is not set', function () {
|
||||
jasmine.version_ = null;
|
||||
var exception;
|
||||
try {
|
||||
env.version();
|
||||
}
|
||||
catch (e) {
|
||||
exception = e;
|
||||
}
|
||||
expect(exception.message).toEqual('Version not set');
|
||||
});
|
||||
|
||||
it("version should return the current version as an int", function() {
|
||||
jasmine.version_ = {
|
||||
"major": 1,
|
||||
"minor": 9,
|
||||
"build": 7,
|
||||
"revision": 8
|
||||
};
|
||||
expect(env.version()).toEqual({
|
||||
"major": 1,
|
||||
"minor": 9,
|
||||
"build": 7,
|
||||
"revision": 8
|
||||
});
|
||||
});
|
||||
|
||||
describe("versionString", function() {
|
||||
it("should return a stringified version number", function() {
|
||||
jasmine.version_ = {
|
||||
"major": 1,
|
||||
"minor": 9,
|
||||
"build": 7,
|
||||
"release_candidate": "1",
|
||||
"revision": 8
|
||||
};
|
||||
expect(env.versionString()).toEqual("1.9.7.rc1 revision 8");
|
||||
});
|
||||
|
||||
it("should return a nice string when version is unknown", function() {
|
||||
jasmine.version_ = null;
|
||||
expect(env.versionString()).toEqual("version unknown");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("should allow reporters to be registered", function() {
|
||||
env.addReporter(fakeReporter);
|
||||
env.reporter.log("message");
|
||||
expect(fakeReporter.log).toHaveBeenCalledWith("message");
|
||||
});
|
||||
});
|
||||
|
||||
describe("equality testing", function() {
|
||||
describe("with custom equality testers", function() {
|
||||
var aObj, bObj, isEqual;
|
||||
|
||||
beforeEach(function() {
|
||||
env.addEqualityTester(function(a, b) {
|
||||
aObj = a;
|
||||
bObj = b;
|
||||
return isEqual;
|
||||
});
|
||||
});
|
||||
|
||||
it("should call the custom equality tester with two objects for comparison", function() {
|
||||
env.equals_("1", "2");
|
||||
expect(aObj).toEqual("1");
|
||||
expect(bObj).toEqual("2");
|
||||
});
|
||||
|
||||
describe("when the custom equality tester returns false", function() {
|
||||
beforeEach(function() {
|
||||
isEqual = false;
|
||||
});
|
||||
|
||||
it("should give custom equality testers precedence", function() {
|
||||
expect(env.equals_('abc', 'abc')).toBeFalsy();
|
||||
var o = {};
|
||||
expect(env.equals_(o, o)).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe("when the custom equality tester returns true", function() {
|
||||
beforeEach(function() {
|
||||
isEqual = true;
|
||||
});
|
||||
|
||||
it("should give custom equality testers precedence", function() {
|
||||
expect(env.equals_('abc', 'def')).toBeTruthy();
|
||||
expect(env.equals_(true, false)).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe("when the custom equality tester returns undefined", function() {
|
||||
beforeEach(function() {
|
||||
isEqual = jasmine.undefined;
|
||||
});
|
||||
|
||||
it("should use normal equality rules", function() {
|
||||
expect(env.equals_('abc', 'abc')).toBeTruthy();
|
||||
expect(env.equals_('abc', 'def')).toBeFalsy();
|
||||
});
|
||||
|
||||
describe("even if there are several", function() {
|
||||
beforeEach(function() {
|
||||
env.addEqualityTester(function(a, b) { return jasmine.undefined; });
|
||||
env.addEqualityTester(function(a, b) { return jasmine.undefined; });
|
||||
});
|
||||
|
||||
it("should use normal equality rules", function() {
|
||||
expect(env.equals_('abc', 'abc')).toBeTruthy();
|
||||
expect(env.equals_('abc', 'def')).toBeFalsy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("should evaluate custom equality testers in the order they are declared", function() {
|
||||
isEqual = false;
|
||||
env.addEqualityTester(function(a, b) { return true; });
|
||||
expect(env.equals_('abc', 'abc')).toBeFalsy();
|
||||
});
|
||||
describe("#topSuite", function() {
|
||||
it("returns the Jasmine top suite for users to traverse the spec tree", function() {
|
||||
var suite = env.topSuite();
|
||||
expect(suite.description).toEqual('Jasmine__TopLevel__Suite');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
63
spec/core/ExceptionFormatterSpec.js
Normal file
63
spec/core/ExceptionFormatterSpec.js
Normal file
@@ -0,0 +1,63 @@
|
||||
describe("ExceptionFormatter", function() {
|
||||
describe("#message", function() {
|
||||
it('formats Firefox exception messages', function() {
|
||||
var sampleFirefoxException = {
|
||||
fileName: 'foo.js',
|
||||
lineNumber: '1978',
|
||||
message: 'you got your foo in my bar',
|
||||
name: 'A Classic Mistake'
|
||||
},
|
||||
exceptionFormatter = new j$.ExceptionFormatter(),
|
||||
message = exceptionFormatter.message(sampleFirefoxException);
|
||||
|
||||
expect(message).toEqual('A Classic Mistake: you got your foo in my bar in foo.js (line 1978)');
|
||||
});
|
||||
|
||||
it('formats Webkit exception messages', function() {
|
||||
var sampleWebkitException = {
|
||||
sourceURL: 'foo.js',
|
||||
line: '1978',
|
||||
message: 'you got your foo in my bar',
|
||||
name: 'A Classic Mistake'
|
||||
},
|
||||
exceptionFormatter = new j$.ExceptionFormatter(),
|
||||
message = exceptionFormatter.message(sampleWebkitException);
|
||||
|
||||
expect(message).toEqual('A Classic Mistake: you got your foo in my bar in foo.js (line 1978)');
|
||||
});
|
||||
|
||||
it('formats V8 exception messages', function() {
|
||||
var sampleV8 = {
|
||||
message: 'you got your foo in my bar',
|
||||
name: 'A Classic Mistake'
|
||||
},
|
||||
exceptionFormatter = new j$.ExceptionFormatter(),
|
||||
message = exceptionFormatter.message(sampleV8);
|
||||
|
||||
expect(message).toEqual('A Classic Mistake: you got your foo in my bar');
|
||||
});
|
||||
|
||||
it("formats thrown exceptions that aren't errors", function() {
|
||||
var thrown = "crazy error",
|
||||
exceptionFormatter = new j$.ExceptionFormatter(),
|
||||
message = exceptionFormatter.message(thrown);
|
||||
|
||||
expect(message).toEqual("crazy error thrown");
|
||||
});
|
||||
});
|
||||
|
||||
describe("#stack", function() {
|
||||
it("formats stack traces from Webkit, Firefox, node.js or IE10+", function() {
|
||||
if (jasmine.getEnv().ieVersion < 10 || jasmine.getEnv().safariVersion < 6) { return; }
|
||||
|
||||
var error;
|
||||
try { throw new Error("an error") } catch(e) { error = e; }
|
||||
|
||||
expect(new j$.ExceptionFormatter().stack(error)).toMatch(/ExceptionFormatterSpec\.js.*\d+/)
|
||||
});
|
||||
|
||||
it("returns null if no Error provided", function() {
|
||||
expect(new j$.ExceptionFormatter().stack()).toBeNull();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -2,148 +2,67 @@ describe('Exceptions:', function() {
|
||||
var env;
|
||||
|
||||
beforeEach(function() {
|
||||
env = new jasmine.Env();
|
||||
env.updateInterval = 0;
|
||||
env = new j$.Env();
|
||||
});
|
||||
|
||||
it('jasmine.formatException formats Firefox exception messages as expected', function() {
|
||||
var sampleFirefoxException = {
|
||||
fileName: 'foo.js',
|
||||
line: '1978',
|
||||
message: 'you got your foo in my bar',
|
||||
name: 'A Classic Mistake'
|
||||
};
|
||||
describe('with break on exception', function() {
|
||||
it('should not catch the exception', function() {
|
||||
env.catchExceptions(false);
|
||||
env.describe('suite for break on exceptions', function() {
|
||||
env.it('should break when an exception is thrown', function() {
|
||||
throw new Error('I should hit a breakpoint!');
|
||||
});
|
||||
});
|
||||
var spy = jasmine.createSpy('spy');
|
||||
|
||||
var expected = 'A Classic Mistake: you got your foo in my bar in foo.js (line 1978)';
|
||||
try {
|
||||
env.execute();
|
||||
spy();
|
||||
}
|
||||
catch (e) {}
|
||||
|
||||
expect(jasmine.util.formatException(sampleFirefoxException)).toEqual(expected);
|
||||
expect(spy).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
it('jasmine.formatException formats Webkit exception messages as expected', function() {
|
||||
var sampleWebkitException = {
|
||||
sourceURL: 'foo.js',
|
||||
lineNumber: '1978',
|
||||
message: 'you got your foo in my bar',
|
||||
name: 'A Classic Mistake'
|
||||
};
|
||||
|
||||
var expected = 'A Classic Mistake: you got your foo in my bar in foo.js (line 1978)';
|
||||
|
||||
expect(jasmine.util.formatException(sampleWebkitException)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should handle exceptions thrown, but continue', function() {
|
||||
var fakeTimer = new jasmine.FakeTimer();
|
||||
env.setTimeout = fakeTimer.setTimeout;
|
||||
env.clearTimeout = fakeTimer.clearTimeout;
|
||||
env.setInterval = fakeTimer.setInterval;
|
||||
env.clearInterval = fakeTimer.clearInterval;
|
||||
|
||||
//we run two exception tests to make sure we continue after throwing an exception
|
||||
var suite = env.describe('Suite for handles exceptions', function () {
|
||||
env.it('should be a test that fails because it throws an exception', function() {
|
||||
throw new Error('fake error 1');
|
||||
});
|
||||
|
||||
env.it('should be another test that fails because it throws an exception', function() {
|
||||
this.runs(function () {
|
||||
throw new Error('fake error 2');
|
||||
});
|
||||
this.runs(function () {
|
||||
this.expect(true).toEqual(true);
|
||||
describe("with catch on exception", function() {
|
||||
it('should handle exceptions thrown, but continue', function(done) {
|
||||
var secondTest = jasmine.createSpy('second test');
|
||||
env.describe('Suite for handles exceptions', function () {
|
||||
env.it('should be a test that fails because it throws an exception', function() {
|
||||
throw new Error();
|
||||
});
|
||||
env.it('should be a passing test that runs after exceptions are thrown from a async test', secondTest);
|
||||
});
|
||||
|
||||
env.it('should be a passing test that runs after exceptions are thrown', function() {
|
||||
this.expect(true).toEqual(true);
|
||||
});
|
||||
var expectations = function() {
|
||||
expect(secondTest).toHaveBeenCalled();
|
||||
done();
|
||||
};
|
||||
|
||||
env.it('should be another test that fails because it throws an exception after a wait', function() {
|
||||
this.runs(function () {
|
||||
var foo = 'foo';
|
||||
});
|
||||
this.waits(250);
|
||||
this.runs(function () {
|
||||
throw new Error('fake error 3');
|
||||
});
|
||||
});
|
||||
|
||||
env.it('should be a passing test that runs after exceptions are thrown from a async test', function() {
|
||||
this.expect(true).toEqual(true);
|
||||
});
|
||||
env.addReporter({ jasmineDone: expectations });
|
||||
env.execute();
|
||||
});
|
||||
|
||||
var runner = env.currentRunner();
|
||||
suite.execute();
|
||||
fakeTimer.tick(2500);
|
||||
|
||||
var suiteResults = suite.results();
|
||||
var specResults = suiteResults.getItems();
|
||||
|
||||
expect(suiteResults.passed()).toEqual(false);
|
||||
//
|
||||
expect(specResults.length).toEqual(5);
|
||||
expect(specResults[0].passed()).toMatch(false);
|
||||
var blockResults = specResults[0].getItems();
|
||||
expect(blockResults[0].passed()).toEqual(false);
|
||||
expect(blockResults[0].message).toMatch(/fake error 1/);
|
||||
|
||||
expect(specResults[1].passed()).toEqual(false);
|
||||
blockResults = specResults[1].getItems();
|
||||
expect(blockResults[0].passed()).toEqual(false);
|
||||
expect(blockResults[0].message).toMatch(/fake error 2/);
|
||||
expect(blockResults[1].passed()).toEqual(true);
|
||||
|
||||
expect(specResults[2].passed()).toEqual(true);
|
||||
|
||||
expect(specResults[3].passed()).toEqual(false);
|
||||
blockResults = specResults[3].getItems();
|
||||
expect(blockResults[0].message).toMatch(/fake error 3/);
|
||||
|
||||
expect(specResults[4].passed()).toEqual(true);
|
||||
});
|
||||
|
||||
|
||||
it("should handle exceptions thrown directly in top-level describe blocks and continue", function () {
|
||||
var suite = env.describe("a top level describe block that throws an exception", function () {
|
||||
env.it("is a test that should pass", function () {
|
||||
it("should handle exceptions thrown directly in top-level describe blocks and continue", function(done) {
|
||||
var secondDescribe = jasmine.createSpy("second describe");
|
||||
env.describe("a suite that throws an exception", function () {
|
||||
env.it("is a test that should pass", function () {
|
||||
this.expect(true).toEqual(true);
|
||||
});
|
||||
});
|
||||
|
||||
throw new Error("top level error");
|
||||
});
|
||||
throw new Error("top level error");
|
||||
});
|
||||
env.describe("a suite that doesn't throw an exception", secondDescribe);
|
||||
|
||||
suite.execute();
|
||||
var suiteResults = suite.results();
|
||||
var specResults = suiteResults.getItems();
|
||||
var expectations = function() {
|
||||
expect(secondDescribe).toHaveBeenCalled();
|
||||
done();
|
||||
};
|
||||
|
||||
expect(suiteResults.passed()).toEqual(false);
|
||||
expect(specResults.length).toEqual(2);
|
||||
env.addReporter({ jasmineDone: expectations });
|
||||
env.execute();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
expect(specResults[1].description).toMatch(/encountered a declaration exception/);
|
||||
});
|
||||
|
||||
it("should handle exceptions thrown directly in nested describe blocks and continue", function () {
|
||||
var suite = env.describe("a top level describe", function () {
|
||||
env.describe("a mid-level describe that throws an exception", function () {
|
||||
env.it("is a test that should pass", function () {
|
||||
this.expect(true).toEqual(true);
|
||||
});
|
||||
|
||||
throw new Error("a mid-level error");
|
||||
});
|
||||
});
|
||||
|
||||
suite.execute();
|
||||
var suiteResults = suite.results();
|
||||
var specResults = suiteResults.getItems();
|
||||
|
||||
expect(suiteResults.passed()).toEqual(false);
|
||||
expect(specResults.length).toEqual(1);
|
||||
|
||||
var nestedSpecResults = specResults[0].getItems();
|
||||
|
||||
expect(nestedSpecResults.length).toEqual(2);
|
||||
expect(nestedSpecResults[1].description).toMatch(/encountered a declaration exception/);
|
||||
});
|
||||
});
|
||||
61
spec/core/ExpectationResultSpec.js
Normal file
61
spec/core/ExpectationResultSpec.js
Normal file
@@ -0,0 +1,61 @@
|
||||
describe("buildExpectationResult", function() {
|
||||
it("defaults to passed", function() {
|
||||
var result = j$.buildExpectationResult({passed: 'some-value'});
|
||||
expect(result.passed).toBe('some-value');
|
||||
});
|
||||
|
||||
it("message defaults to Passed for passing specs", function() {
|
||||
var result = j$.buildExpectationResult({passed: true, message: 'some-value'});
|
||||
expect(result.message).toBe('Passed.');
|
||||
});
|
||||
|
||||
it("message returns the message for failing expectations", function() {
|
||||
var result = j$.buildExpectationResult({passed: false, message: 'some-value'});
|
||||
expect(result.message).toBe('some-value');
|
||||
});
|
||||
|
||||
it("delegates message formatting to the provided formatter if there was an Error", function() {
|
||||
var fakeError = {message: 'foo'},
|
||||
messageFormatter = jasmine.createSpy("exception message formatter").and.returnValue(fakeError.message);
|
||||
|
||||
var result = j$.buildExpectationResult(
|
||||
{
|
||||
passed: false,
|
||||
error: fakeError,
|
||||
messageFormatter: messageFormatter
|
||||
});
|
||||
|
||||
expect(messageFormatter).toHaveBeenCalledWith(fakeError);
|
||||
expect(result.message).toEqual('foo');
|
||||
});
|
||||
|
||||
it("delegates stack formatting to the provided formatter if there was an Error", function() {
|
||||
var fakeError = {stack: 'foo'},
|
||||
stackFormatter = jasmine.createSpy("stack formatter").and.returnValue(fakeError.stack);
|
||||
|
||||
var result = j$.buildExpectationResult(
|
||||
{
|
||||
passed: false,
|
||||
error: fakeError,
|
||||
stackFormatter: stackFormatter
|
||||
});
|
||||
|
||||
expect(stackFormatter).toHaveBeenCalledWith(fakeError);
|
||||
expect(result.stack).toEqual('foo');
|
||||
});
|
||||
|
||||
it("matcherName returns passed matcherName", function() {
|
||||
var result = j$.buildExpectationResult({matcherName: 'some-value'});
|
||||
expect(result.matcherName).toBe('some-value');
|
||||
});
|
||||
|
||||
it("expected returns passed expected", function() {
|
||||
var result = j$.buildExpectationResult({expected: 'some-value'});
|
||||
expect(result.expected).toBe('some-value');
|
||||
});
|
||||
|
||||
it("actual returns passed actual", function() {
|
||||
var result = j$.buildExpectationResult({actual: 'some-value'});
|
||||
expect(result.actual).toBe('some-value');
|
||||
});
|
||||
});
|
||||
389
spec/core/ExpectationSpec.js
Normal file
389
spec/core/ExpectationSpec.js
Normal file
@@ -0,0 +1,389 @@
|
||||
describe("Expectation", function() {
|
||||
it("makes custom matchers available to this expectation", function() {
|
||||
var matchers = {
|
||||
toFoo: function() {},
|
||||
toBar: function() {}
|
||||
},
|
||||
expectation;
|
||||
|
||||
expectation = new j$.Expectation({
|
||||
customMatchers: matchers
|
||||
});
|
||||
|
||||
expect(expectation.toFoo).toBeDefined();
|
||||
expect(expectation.toBar).toBeDefined();
|
||||
});
|
||||
|
||||
it(".addCoreMatchers makes matchers available to any expectation", function() {
|
||||
var coreMatchers = {
|
||||
toQuux: function() {}
|
||||
},
|
||||
expectation;
|
||||
|
||||
j$.Expectation.addCoreMatchers(coreMatchers);
|
||||
|
||||
expectation = new j$.Expectation({});
|
||||
|
||||
expect(expectation.toQuux).toBeDefined();
|
||||
});
|
||||
|
||||
it("Factory builds an expectation/negative expectation", function() {
|
||||
var builtExpectation = j$.Expectation.Factory();
|
||||
|
||||
expect(builtExpectation instanceof j$.Expectation).toBe(true);
|
||||
expect(builtExpectation.not instanceof j$.Expectation).toBe(true);
|
||||
expect(builtExpectation.not.isNot).toBe(true);
|
||||
});
|
||||
|
||||
it("wraps matchers's compare functions, passing in matcher dependencies", function() {
|
||||
var fakeCompare = function() { return { pass: true }; },
|
||||
matcherFactory = jasmine.createSpy("matcher").and.returnValue({ compare: fakeCompare }),
|
||||
matchers = {
|
||||
toFoo: matcherFactory
|
||||
},
|
||||
util = {},
|
||||
customEqualityTesters = ['a'],
|
||||
addExpectationResult = jasmine.createSpy("addExpectationResult"),
|
||||
expectation;
|
||||
|
||||
expectation = new j$.Expectation({
|
||||
util: util,
|
||||
customMatchers: matchers,
|
||||
customEqualityTesters: customEqualityTesters,
|
||||
actual: "an actual",
|
||||
addExpectationResult: addExpectationResult
|
||||
});
|
||||
|
||||
expectation.toFoo("hello");
|
||||
|
||||
expect(matcherFactory).toHaveBeenCalledWith(util, customEqualityTesters)
|
||||
});
|
||||
|
||||
it("wraps matchers's compare functions, passing the actual and expected", function() {
|
||||
var fakeCompare = jasmine.createSpy('fake-compare').and.returnValue({pass: true}),
|
||||
matchers = {
|
||||
toFoo: function() {
|
||||
return {
|
||||
compare: fakeCompare
|
||||
};
|
||||
}
|
||||
},
|
||||
util = {
|
||||
buildFailureMessage: jasmine.createSpy('buildFailureMessage')
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy("addExpectationResult"),
|
||||
expectation;
|
||||
|
||||
expectation = new j$.Expectation({
|
||||
util: util,
|
||||
customMatchers: matchers,
|
||||
actual: "an actual",
|
||||
addExpectationResult: addExpectationResult
|
||||
});
|
||||
|
||||
expectation.toFoo("hello");
|
||||
|
||||
expect(fakeCompare).toHaveBeenCalledWith("an actual", "hello");
|
||||
});
|
||||
|
||||
it("reports a passing result to the spec when the comparison passes", function() {
|
||||
var matchers = {
|
||||
toFoo: function() {
|
||||
return {
|
||||
compare: function() { return { pass: true }; }
|
||||
};
|
||||
}
|
||||
},
|
||||
util = {
|
||||
buildFailureMessage: jasmine.createSpy('buildFailureMessage')
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy("addExpectationResult"),
|
||||
expectation;
|
||||
|
||||
expectation = new j$.Expectation({
|
||||
customMatchers: matchers,
|
||||
util: util,
|
||||
actual: "an actual",
|
||||
addExpectationResult: addExpectationResult
|
||||
});
|
||||
|
||||
expectation.toFoo("hello");
|
||||
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(true, {
|
||||
matcherName: "toFoo",
|
||||
passed: true,
|
||||
message: "",
|
||||
expected: "hello",
|
||||
actual: "an actual"
|
||||
});
|
||||
});
|
||||
|
||||
it("reports a failing result to the spec when the comparison fails", function() {
|
||||
var matchers = {
|
||||
toFoo: function() {
|
||||
return {
|
||||
compare: function() { return { pass: false }; }
|
||||
};
|
||||
}
|
||||
},
|
||||
util = {
|
||||
buildFailureMessage: function() { return ""; }
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy("addExpectationResult"),
|
||||
expectation;
|
||||
|
||||
expectation = new j$.Expectation({
|
||||
customMatchers: matchers,
|
||||
util: util,
|
||||
actual: "an actual",
|
||||
addExpectationResult: addExpectationResult
|
||||
});
|
||||
|
||||
expectation.toFoo("hello");
|
||||
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(false, {
|
||||
matcherName: "toFoo",
|
||||
passed: false,
|
||||
expected: "hello",
|
||||
actual: "an actual",
|
||||
message: ""
|
||||
});
|
||||
});
|
||||
|
||||
it("reports a failing result and a custom fail message to the spec when the comparison fails", function() {
|
||||
var matchers = {
|
||||
toFoo: function() {
|
||||
return {
|
||||
compare: function() {
|
||||
return {
|
||||
pass: false,
|
||||
message: "I am a custom message"
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy("addExpectationResult"),
|
||||
expectation;
|
||||
|
||||
expectation = new j$.Expectation({
|
||||
actual: "an actual",
|
||||
customMatchers: matchers,
|
||||
addExpectationResult: addExpectationResult
|
||||
});
|
||||
|
||||
expectation.toFoo("hello");
|
||||
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(false, {
|
||||
matcherName: "toFoo",
|
||||
passed: false,
|
||||
expected: "hello",
|
||||
actual: "an actual",
|
||||
message: "I am a custom message"
|
||||
});
|
||||
});
|
||||
|
||||
it("reports a failing result with a custom fail message function to the spec when the comparison fails", function() {
|
||||
var matchers = {
|
||||
toFoo: function() {
|
||||
return {
|
||||
compare: function() {
|
||||
return {
|
||||
pass: false,
|
||||
message: function() { return "I am a custom message"; }
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy("addExpectationResult"),
|
||||
expectation;
|
||||
|
||||
expectation = new j$.Expectation({
|
||||
customMatchers: matchers,
|
||||
actual: "an actual",
|
||||
addExpectationResult: addExpectationResult
|
||||
});
|
||||
|
||||
expectation.toFoo("hello");
|
||||
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(false, {
|
||||
matcherName: "toFoo",
|
||||
passed: false,
|
||||
expected: "hello",
|
||||
actual: "an actual",
|
||||
message: "I am a custom message"
|
||||
});
|
||||
});
|
||||
|
||||
it("reports a passing result to the spec when the comparison fails for a negative expectation", function() {
|
||||
var matchers = {
|
||||
toFoo: function() {
|
||||
return {
|
||||
compare: function() { return { pass: false }; }
|
||||
};
|
||||
}
|
||||
},
|
||||
util = {
|
||||
buildFailureMessage: function() { return ""; }
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy("addExpectationResult"),
|
||||
actual = "an actual",
|
||||
expectation;
|
||||
|
||||
expectation = new j$.Expectation({
|
||||
customMatchers: matchers,
|
||||
actual: "an actual",
|
||||
addExpectationResult: addExpectationResult,
|
||||
isNot: true
|
||||
});
|
||||
|
||||
expectation.toFoo("hello");
|
||||
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(true, {
|
||||
matcherName: "toFoo",
|
||||
passed: true,
|
||||
message: "",
|
||||
expected: "hello",
|
||||
actual: actual
|
||||
});
|
||||
});
|
||||
|
||||
it("reports a failing result to the spec when the comparison passes for a negative expectation", function() {
|
||||
var matchers = {
|
||||
toFoo: function() {
|
||||
return {
|
||||
compare: function() { return { pass: true }; }
|
||||
};
|
||||
}
|
||||
},
|
||||
util = {
|
||||
buildFailureMessage: function() { return "default message"; }
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy("addExpectationResult"),
|
||||
actual = "an actual",
|
||||
expectation;
|
||||
|
||||
expectation = new j$.Expectation({
|
||||
customMatchers: matchers,
|
||||
actual: "an actual",
|
||||
util: util,
|
||||
addExpectationResult: addExpectationResult,
|
||||
isNot: true
|
||||
});
|
||||
|
||||
expectation.toFoo("hello");
|
||||
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(false, {
|
||||
matcherName: "toFoo",
|
||||
passed: false,
|
||||
expected: "hello",
|
||||
actual: actual,
|
||||
message: "default message"
|
||||
});
|
||||
});
|
||||
|
||||
it("reports a failing result and a custom fail message to the spec when the comparison passes for a negative expectation", function() {
|
||||
var matchers = {
|
||||
toFoo: function() {
|
||||
return {
|
||||
compare: function() {
|
||||
return {
|
||||
pass: true,
|
||||
message: "I am a custom message"
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy("addExpectationResult"),
|
||||
actual = "an actual",
|
||||
expectation;
|
||||
|
||||
expectation = new j$.Expectation({
|
||||
customMatchers: matchers,
|
||||
actual: "an actual",
|
||||
addExpectationResult: addExpectationResult,
|
||||
isNot: true
|
||||
});
|
||||
|
||||
expectation.toFoo("hello");
|
||||
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(false, {
|
||||
matcherName: "toFoo",
|
||||
passed: false,
|
||||
expected: "hello",
|
||||
actual: actual,
|
||||
message: "I am a custom message"
|
||||
});
|
||||
});
|
||||
|
||||
it("reports a passing result to the spec when the 'not' comparison passes, given a negativeCompare", function() {
|
||||
var matchers = {
|
||||
toFoo: function() {
|
||||
return {
|
||||
compare: function() { return { pass: true }; },
|
||||
negativeCompare: function() { return { pass: true }; }
|
||||
};
|
||||
}
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy("addExpectationResult"),
|
||||
actual = "an actual",
|
||||
expectation;
|
||||
|
||||
expectation = new j$.Expectation({
|
||||
customMatchers: matchers,
|
||||
actual: "an actual",
|
||||
addExpectationResult: addExpectationResult,
|
||||
isNot: true
|
||||
});
|
||||
|
||||
expectation.toFoo("hello");
|
||||
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(true, {
|
||||
matcherName: "toFoo",
|
||||
passed: true,
|
||||
expected: "hello",
|
||||
actual: actual,
|
||||
message: ""
|
||||
});
|
||||
});
|
||||
|
||||
it("reports a failing result and a custom fail message to the spec when the 'not' comparison fails, given a negativeCompare", function() {
|
||||
var matchers = {
|
||||
toFoo: function() {
|
||||
return {
|
||||
compare: function() { return { pass: true }; },
|
||||
negativeCompare: function() {
|
||||
return {
|
||||
pass: false,
|
||||
message: "I'm a custom message"
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy("addExpectationResult"),
|
||||
actual = "an actual",
|
||||
expectation;
|
||||
|
||||
expectation = new j$.Expectation({
|
||||
customMatchers: matchers,
|
||||
actual: "an actual",
|
||||
addExpectationResult: addExpectationResult,
|
||||
isNot: true
|
||||
});
|
||||
|
||||
expectation.toFoo("hello");
|
||||
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(false, {
|
||||
matcherName: "toFoo",
|
||||
passed: false,
|
||||
expected: "hello",
|
||||
actual: actual,
|
||||
message: "I'm a custom message"
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
describe('jasmine.jsApiReporter', function() {
|
||||
describe('results', function () {
|
||||
var reporter, spec1, spec2, spec3, expectedSpec1Results, expectedSpec2Results;
|
||||
xdescribe('JsApiReporter (integration specs)', function() {
|
||||
describe('results', function() {
|
||||
var reporter, spec1, spec2;
|
||||
var env;
|
||||
var suite, nestedSuite, nestedSpec;
|
||||
|
||||
beforeEach(function() {
|
||||
env = new jasmine.Env();
|
||||
env.updateInterval = 0;
|
||||
env = new j$.Env();
|
||||
|
||||
suite = env.describe("top-level suite", function() {
|
||||
spec1 = env.it("spec 1", function() {
|
||||
@@ -24,34 +23,24 @@ describe('jasmine.jsApiReporter', function() {
|
||||
});
|
||||
});
|
||||
|
||||
spec3 = env.it("spec 3", function() {
|
||||
this.log('some debug message');
|
||||
});
|
||||
});
|
||||
|
||||
reporter = new jasmine.JsApiReporter();
|
||||
reporter = new j$.JsApiReporter({});
|
||||
env.addReporter(reporter);
|
||||
|
||||
env.execute();
|
||||
|
||||
expectedSpec1Results = {
|
||||
messages: spec1.results().getItems(),
|
||||
result: "passed"
|
||||
};
|
||||
expectedSpec2Results = {
|
||||
messages: spec2.results().getItems(),
|
||||
result: "failed"
|
||||
};
|
||||
});
|
||||
|
||||
it('resultForSpec() should return the result for the given spec', function () {
|
||||
expect(reporter.resultsForSpec(spec1.id)).toEqual(expectedSpec1Results);
|
||||
expect(reporter.resultsForSpec(spec2.id)).toEqual(expectedSpec2Results);
|
||||
});
|
||||
|
||||
it('results() should return a hash of all results, indexed by spec id', function () {
|
||||
expect(reporter.results()[spec1.id]).toEqual(expectedSpec1Results);
|
||||
expect(reporter.results()[spec2.id]).toEqual(expectedSpec2Results);
|
||||
it('results() should return a hash of all results, indexed by spec id', function() {
|
||||
var expectedSpec1Results = {
|
||||
result: "passed"
|
||||
},
|
||||
expectedSpec2Results = {
|
||||
result: "failed"
|
||||
};
|
||||
expect(reporter.results()[spec1.id].result).toEqual('passed');
|
||||
expect(reporter.results()[spec2.id].result).toEqual('failed');
|
||||
});
|
||||
|
||||
it("should return nested suites as children of their parents", function() {
|
||||
@@ -65,7 +54,6 @@ describe('jasmine.jsApiReporter', function() {
|
||||
{ id: 2, name: 'nested spec', type: 'spec', children: [ ] }
|
||||
]
|
||||
},
|
||||
{ id: 3, name: 'spec 3', type: 'spec', children: [ ] }
|
||||
]
|
||||
}
|
||||
]);
|
||||
@@ -76,12 +64,7 @@ describe('jasmine.jsApiReporter', function() {
|
||||
var result = reporter.results()[spec1.id];
|
||||
var summarizedResult = reporter.summarizeResult_(result);
|
||||
expect(summarizedResult.result).toEqual('passed');
|
||||
expect(summarizedResult.messages.length).toEqual(1);
|
||||
expect(summarizedResult.messages[0].message).toEqual(result.messages[0].message);
|
||||
expect(summarizedResult.messages[0].passed).toBeTruthy();
|
||||
expect(summarizedResult.messages[0].type).toEqual('expect');
|
||||
expect(summarizedResult.messages[0].text).toBeUndefined();
|
||||
expect(summarizedResult.messages[0].trace.stack).toBeUndefined();
|
||||
expect(summarizedResult.messages.length).toEqual(0);
|
||||
});
|
||||
|
||||
it("should have a stack trace for failing specs", function() {
|
||||
@@ -91,13 +74,178 @@ describe('jasmine.jsApiReporter', function() {
|
||||
expect(summarizedResult.messages[0].trace.stack).toEqual(result.messages[0].trace.stack);
|
||||
});
|
||||
|
||||
it("should have messages for specs with messages", function() {
|
||||
var result = reporter.results()[spec3.id];
|
||||
var summarizedResult = reporter.summarizeResult_(result);
|
||||
expect(summarizedResult.result).toEqual('passed');
|
||||
expect(summarizedResult.messages[0].type).toEqual('log');
|
||||
expect(summarizedResult.messages[0].text).toEqual('some debug message');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe("JsApiReporter", function() {
|
||||
|
||||
it("knows when a full environment is started", function() {
|
||||
var reporter = new j$.JsApiReporter({});
|
||||
|
||||
expect(reporter.started).toBe(false);
|
||||
expect(reporter.finished).toBe(false);
|
||||
|
||||
reporter.jasmineStarted();
|
||||
|
||||
expect(reporter.started).toBe(true);
|
||||
expect(reporter.finished).toBe(false);
|
||||
});
|
||||
|
||||
it("knows when a full environment is done", function() {
|
||||
var reporter = new j$.JsApiReporter({});
|
||||
|
||||
expect(reporter.started).toBe(false);
|
||||
expect(reporter.finished).toBe(false);
|
||||
|
||||
reporter.jasmineStarted();
|
||||
reporter.jasmineDone({});
|
||||
|
||||
expect(reporter.finished).toBe(true);
|
||||
});
|
||||
|
||||
it("defaults to 'loaded' status", function() {
|
||||
var reporter = new j$.JsApiReporter({});
|
||||
|
||||
expect(reporter.status()).toEqual('loaded');
|
||||
});
|
||||
|
||||
it("reports 'started' when Jasmine has started", function() {
|
||||
var reporter = new j$.JsApiReporter({});
|
||||
|
||||
reporter.jasmineStarted();
|
||||
|
||||
expect(reporter.status()).toEqual('started');
|
||||
});
|
||||
|
||||
it("reports 'done' when Jasmine is done", function() {
|
||||
var reporter = new j$.JsApiReporter({});
|
||||
|
||||
reporter.jasmineDone({});
|
||||
|
||||
expect(reporter.status()).toEqual('done');
|
||||
});
|
||||
|
||||
it("tracks a suite", function() {
|
||||
var reporter = new j$.JsApiReporter({});
|
||||
|
||||
reporter.suiteStarted({
|
||||
id: 123,
|
||||
description: "A suite"
|
||||
});
|
||||
|
||||
var suites = reporter.suites();
|
||||
|
||||
expect(suites).toEqual({123: {id: 123, description: "A suite"}});
|
||||
|
||||
reporter.suiteDone({
|
||||
id: 123,
|
||||
description: "A suite",
|
||||
status: 'passed'
|
||||
});
|
||||
|
||||
expect(suites).toEqual({123: {id: 123, description: "A suite", status: 'passed'}});
|
||||
});
|
||||
|
||||
describe("#specResults", function() {
|
||||
var reporter, specResult1, specResult2;
|
||||
beforeEach(function() {
|
||||
reporter = new j$.JsApiReporter({});
|
||||
specResult1 = {
|
||||
id: 1,
|
||||
description: "A spec"
|
||||
};
|
||||
specResult2 = {
|
||||
id: 2,
|
||||
description: "Another spec"
|
||||
};
|
||||
|
||||
reporter.specDone(specResult1);
|
||||
reporter.specDone(specResult2);
|
||||
});
|
||||
|
||||
it("should return a slice of results", function() {
|
||||
expect(reporter.specResults(0, 1)).toEqual([specResult1]);
|
||||
expect(reporter.specResults(1, 1)).toEqual([specResult2]);
|
||||
});
|
||||
|
||||
describe("when the results do not exist", function() {
|
||||
it("should return a slice of shorter length", function() {
|
||||
expect(reporter.specResults(0, 3)).toEqual([specResult1, specResult2]);
|
||||
expect(reporter.specResults(2, 3)).toEqual([]);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("#suiteResults", function(){
|
||||
var reporter, suiteResult1, suiteResult2;
|
||||
beforeEach(function() {
|
||||
reporter = new j$.JsApiReporter({});
|
||||
suiteStarted1 = {
|
||||
id: 1
|
||||
};
|
||||
suiteResult1 = {
|
||||
id: 1,
|
||||
status: 'failed',
|
||||
failedExpectations: [{ message: 'My After All Exception' }]
|
||||
};
|
||||
suiteResult2 = {
|
||||
id: 2,
|
||||
status: 'finished'
|
||||
};
|
||||
|
||||
reporter.suiteStarted(suiteStarted1);
|
||||
reporter.suiteDone(suiteResult1);
|
||||
reporter.suiteDone(suiteResult2);
|
||||
});
|
||||
|
||||
it('should not include suite starts', function(){
|
||||
expect(reporter.suiteResults(0,3).length).toEqual(2);
|
||||
});
|
||||
|
||||
it("should return a slice of results", function() {
|
||||
expect(reporter.suiteResults(0, 1)).toEqual([suiteResult1]);
|
||||
expect(reporter.suiteResults(1, 1)).toEqual([suiteResult2]);
|
||||
});
|
||||
|
||||
it("returns nothing for out of bounds indicies", function() {
|
||||
expect(reporter.suiteResults(0, 3)).toEqual([suiteResult1, suiteResult2]);
|
||||
expect(reporter.suiteResults(2, 3)).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#executionTime", function() {
|
||||
it("should start the timer when jasmine starts", function() {
|
||||
var timerSpy = jasmine.createSpyObj('timer', ['start', 'elapsed']),
|
||||
reporter = new j$.JsApiReporter({
|
||||
timer: timerSpy
|
||||
});
|
||||
|
||||
reporter.jasmineStarted();
|
||||
expect(timerSpy.start).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should return the time it took the specs to run, in ms", function() {
|
||||
var timerSpy = jasmine.createSpyObj('timer', ['start', 'elapsed']),
|
||||
reporter = new j$.JsApiReporter({
|
||||
timer: timerSpy
|
||||
});
|
||||
|
||||
timerSpy.elapsed.and.returnValue(1000);
|
||||
reporter.jasmineDone();
|
||||
expect(reporter.executionTime()).toEqual(1000);
|
||||
});
|
||||
|
||||
describe("when the specs haven't finished being run", function() {
|
||||
it("should return undefined", function() {
|
||||
var timerSpy = jasmine.createSpyObj('timer', ['start', 'elapsed']),
|
||||
reporter = new j$.JsApiReporter({
|
||||
timer: timerSpy
|
||||
});
|
||||
|
||||
expect(reporter.executionTime()).toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,838 +0,0 @@
|
||||
describe("jasmine.Matchers", function() {
|
||||
var env, spec;
|
||||
|
||||
beforeEach(function() {
|
||||
env = new jasmine.Env();
|
||||
env.updateInterval = 0;
|
||||
|
||||
var suite = env.describe("suite", function() {
|
||||
spec = env.it("spec", function() {
|
||||
});
|
||||
});
|
||||
spyOn(spec, 'addMatcherResult');
|
||||
|
||||
this.addMatchers({
|
||||
toPass: function() {
|
||||
return lastResult().passed();
|
||||
},
|
||||
toFail: function() {
|
||||
return !lastResult().passed();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function match(value) {
|
||||
return spec.expect(value);
|
||||
}
|
||||
|
||||
function lastResult() {
|
||||
return spec.addMatcherResult.mostRecentCall.args[0];
|
||||
}
|
||||
|
||||
function catchException(fn) {
|
||||
try {
|
||||
fn.call();
|
||||
} catch (e) {
|
||||
return e;
|
||||
}
|
||||
throw new Error("expected function to throw an exception");
|
||||
}
|
||||
|
||||
it("toEqual with primitives, objects, dates, etc.", function() {
|
||||
expect(match(true).toEqual(true)).toPass();
|
||||
|
||||
expect(match({foo:'bar'}).toEqual(null)).toFail();
|
||||
|
||||
var functionA = function() {
|
||||
return 'hi';
|
||||
};
|
||||
var functionB = function() {
|
||||
return 'hi';
|
||||
};
|
||||
expect(match({foo:functionA}).toEqual({foo:functionB})).toFail();
|
||||
expect(match({foo:functionA}).toEqual({foo:functionA})).toPass();
|
||||
|
||||
expect((match(false).toEqual(true))).toFail();
|
||||
|
||||
var circularGraph = {};
|
||||
circularGraph.referenceToSelf = circularGraph;
|
||||
expect((match(circularGraph).toEqual(circularGraph))).toPass();
|
||||
|
||||
expect((match(new Date(2008, 1, 3, 15, 17, 19, 1234)).toEqual(new Date(2009, 1, 3, 15, 17, 19, 1234)))).toFail();
|
||||
expect((match(new Date(2008, 1, 3, 15, 17, 19, 1234)).toEqual(new Date(2008, 1, 3, 15, 17, 19, 1234)))).toPass();
|
||||
|
||||
|
||||
expect(match(true).toNotEqual(false)).toPass();
|
||||
expect((match(true).toNotEqual(true))).toFail();
|
||||
|
||||
expect((match(['a', 'b']).toEqual(['a', jasmine.undefined]))).toFail();
|
||||
expect((match(['a', 'b']).toEqual(['a', 'b', jasmine.undefined]))).toFail();
|
||||
|
||||
expect((match("cat").toEqual("cat"))).toPass();
|
||||
expect((match("cat").toNotEqual("cat"))).toFail();
|
||||
|
||||
expect((match(5).toEqual(5))).toPass();
|
||||
expect((match(parseInt('5', 10)).toEqual(5))).toPass();
|
||||
expect((match(5).toNotEqual(5))).toFail();
|
||||
expect((match(parseInt('5', 10)).toNotEqual(5))).toFail();
|
||||
});
|
||||
|
||||
it("toEqual to build an Expectation Result", function() {
|
||||
var actual = 'a';
|
||||
var matcher = match(actual);
|
||||
var expected = 'b';
|
||||
matcher.toEqual(expected);
|
||||
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toEqual");
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toMatch(jasmine.pp(actual));
|
||||
expect(result.message).toMatch(jasmine.pp(expected));
|
||||
expect(result.expected).toEqual(expected);
|
||||
expect(result.actual).toEqual(actual);
|
||||
});
|
||||
|
||||
it("toNotEqual to build an Expectation Result", function() {
|
||||
var str = 'a';
|
||||
var matcher = match(str);
|
||||
matcher.toNotEqual(str);
|
||||
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toNotEqual");
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toMatch(jasmine.pp(str));
|
||||
expect(result.message).toMatch('not');
|
||||
expect(result.expected).toEqual(str);
|
||||
expect(result.actual).toEqual(str);
|
||||
});
|
||||
|
||||
it('toBe should return true only if the expected and actual items === each other', function() {
|
||||
var a = {};
|
||||
var b = {};
|
||||
//noinspection UnnecessaryLocalVariableJS
|
||||
var c = a;
|
||||
expect((match(a).toBe(b))).toFail();
|
||||
expect((match(a).toBe(a))).toPass();
|
||||
expect((match(a).toBe(c))).toPass();
|
||||
expect((match(a).toNotBe(b))).toPass();
|
||||
expect((match(a).toNotBe(a))).toFail();
|
||||
expect((match(a).toNotBe(c))).toFail();
|
||||
});
|
||||
|
||||
it("toBe to build an ExpectationResult", function() {
|
||||
var expected = 'b';
|
||||
var actual = 'a';
|
||||
var matcher = match(actual);
|
||||
matcher.toBe(expected);
|
||||
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toBe");
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toMatch(jasmine.pp(actual));
|
||||
expect(result.message).toMatch(jasmine.pp(expected));
|
||||
expect(result.expected).toEqual(expected);
|
||||
expect(result.actual).toEqual(actual);
|
||||
});
|
||||
|
||||
it("toNotBe to build an ExpectationResult", function() {
|
||||
var str = 'a';
|
||||
var matcher = match(str);
|
||||
matcher.toNotBe(str);
|
||||
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toNotBe");
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toMatch(str);
|
||||
expect(result.expected).toEqual(str);
|
||||
expect(result.actual).toEqual(str);
|
||||
});
|
||||
|
||||
it("toMatch and #toNotMatch should perform regular expression matching on strings", function() {
|
||||
expect((match('foobarbel').toMatch(/bar/))).toPass();
|
||||
expect((match('foobazbel').toMatch(/bar/))).toFail();
|
||||
|
||||
expect((match('foobarbel').toMatch("bar"))).toPass();
|
||||
expect((match('foobazbel').toMatch("bar"))).toFail();
|
||||
|
||||
expect((match('foobarbel').toNotMatch(/bar/))).toFail();
|
||||
expect((match('foobazbel').toNotMatch(/bar/))).toPass();
|
||||
|
||||
expect((match('foobarbel').toNotMatch("bar"))).toFail();
|
||||
expect((match('foobazbel').toNotMatch("bar"))).toPass();
|
||||
});
|
||||
|
||||
it("toMatch w/ RegExp to build an ExpectationResult", function() {
|
||||
var actual = 'a';
|
||||
var matcher = match(actual);
|
||||
var expected = /b/;
|
||||
matcher.toMatch(expected);
|
||||
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toMatch");
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toMatch(jasmine.pp(actual));
|
||||
expect(result.message).toMatch(expected.toString());
|
||||
expect(result.expected).toEqual(expected);
|
||||
expect(result.actual).toEqual(actual);
|
||||
});
|
||||
|
||||
it("toMatch w/ String to build an ExpectationResult", function() {
|
||||
var actual = 'a';
|
||||
var matcher = match(actual);
|
||||
var expected = 'b';
|
||||
matcher.toMatch(expected);
|
||||
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toMatch");
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toEqual("Expected 'a' to match 'b'.");
|
||||
expect(result.expected).toEqual(expected);
|
||||
expect(result.actual).toEqual(actual);
|
||||
});
|
||||
|
||||
it("toNotMatch w/ RegExp to build an ExpectationResult", function() {
|
||||
var actual = 'a';
|
||||
var matcher = match(actual);
|
||||
var expected = /a/;
|
||||
matcher.toNotMatch(expected);
|
||||
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toNotMatch");
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toEqual("Expected 'a' to not match /a/.");
|
||||
expect(result.expected).toEqual(expected);
|
||||
expect(result.actual).toEqual(actual);
|
||||
});
|
||||
|
||||
it("toNotMatch w/ String to build an ExpectationResult", function() {
|
||||
var str = 'a';
|
||||
var matcher = match(str);
|
||||
matcher.toNotMatch(str);
|
||||
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toNotMatch");
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toEqual("Expected 'a' to not match 'a'.");
|
||||
expect(result.expected).toEqual(str);
|
||||
expect(result.actual).toEqual(str);
|
||||
});
|
||||
|
||||
it("toBeDefined", function() {
|
||||
expect(match('foo').toBeDefined()).toPass();
|
||||
expect(match(jasmine.undefined).toBeDefined()).toFail();
|
||||
});
|
||||
|
||||
it("toBeDefined to build an ExpectationResult", function() {
|
||||
var matcher = match(jasmine.undefined);
|
||||
matcher.toBeDefined();
|
||||
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toBeDefined");
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toEqual('Expected undefined to be defined.');
|
||||
expect(result.actual).toEqual(jasmine.undefined);
|
||||
});
|
||||
|
||||
it("toBeUndefined", function() {
|
||||
expect(match('foo').toBeUndefined()).toFail();
|
||||
expect(match(jasmine.undefined).toBeUndefined()).toPass();
|
||||
});
|
||||
|
||||
it("toBeNull", function() {
|
||||
expect(match(null).toBeNull()).toPass();
|
||||
expect(match(jasmine.undefined).toBeNull()).toFail();
|
||||
expect(match("foo").toBeNull()).toFail();
|
||||
});
|
||||
|
||||
it("toBeNull w/ String to build an ExpectationResult", function() {
|
||||
var actual = 'a';
|
||||
var matcher = match(actual);
|
||||
matcher.toBeNull();
|
||||
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toBeNull");
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toMatch(jasmine.pp(actual));
|
||||
expect(result.message).toMatch('null');
|
||||
expect(result.actual).toEqual(actual);
|
||||
});
|
||||
|
||||
it("toBeNull w/ Object to build an ExpectationResult", function() {
|
||||
var actual = {a: 'b'};
|
||||
var matcher = match(actual);
|
||||
matcher.toBeNull();
|
||||
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toBeNull");
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toMatch(jasmine.pp(actual));
|
||||
expect(result.message).toMatch('null');
|
||||
expect(result.actual).toEqual(actual);
|
||||
});
|
||||
|
||||
it("toBeFalsy", function() {
|
||||
expect(match(false).toBeFalsy()).toPass();
|
||||
expect(match(true).toBeFalsy()).toFail();
|
||||
expect(match(jasmine.undefined).toBeFalsy()).toPass();
|
||||
expect(match(0).toBeFalsy()).toPass();
|
||||
expect(match("").toBeFalsy()).toPass();
|
||||
});
|
||||
|
||||
it("toBeFalsy to build an ExpectationResult", function() {
|
||||
var actual = 'a';
|
||||
var matcher = match(actual);
|
||||
matcher.toBeFalsy();
|
||||
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toBeFalsy");
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toMatch(jasmine.pp(actual));
|
||||
expect(result.message).toMatch('falsy');
|
||||
expect(result.actual).toEqual(actual);
|
||||
});
|
||||
|
||||
it("toBeTruthy", function() {
|
||||
expect(match(false).toBeTruthy()).toFail();
|
||||
expect(match(true).toBeTruthy()).toPass();
|
||||
expect(match(jasmine.undefined).toBeTruthy()).toFail();
|
||||
expect(match(0).toBeTruthy()).toFail();
|
||||
expect(match("").toBeTruthy()).toFail();
|
||||
expect(match("hi").toBeTruthy()).toPass();
|
||||
expect(match(5).toBeTruthy()).toPass();
|
||||
expect(match({foo: 1}).toBeTruthy()).toPass();
|
||||
});
|
||||
|
||||
it("toBeTruthy to build an ExpectationResult", function() {
|
||||
var matcher = match(false);
|
||||
matcher.toBeTruthy();
|
||||
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toBeTruthy");
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toEqual("Expected false to be truthy.");
|
||||
expect(result.actual).toFail();
|
||||
});
|
||||
|
||||
it("toEqual", function() {
|
||||
expect(match(jasmine.undefined).toEqual(jasmine.undefined)).toPass();
|
||||
expect(match({foo:'bar'}).toEqual({foo:'bar'})).toPass();
|
||||
expect(match("foo").toEqual({bar: jasmine.undefined})).toFail();
|
||||
expect(match({foo: jasmine.undefined}).toEqual("goo")).toFail();
|
||||
expect(match({foo: {bar :jasmine.undefined}}).toEqual("goo")).toFail();
|
||||
});
|
||||
|
||||
it("toEqual with jasmine.any()", function() {
|
||||
expect(match("foo").toEqual(jasmine.any(String))).toPass();
|
||||
expect(match(3).toEqual(jasmine.any(Number))).toPass();
|
||||
expect(match("foo").toEqual(jasmine.any(Function))).toFail();
|
||||
expect(match("foo").toEqual(jasmine.any(Object))).toFail();
|
||||
expect(match({someObj:'foo'}).toEqual(jasmine.any(Object))).toPass();
|
||||
expect(match({someObj:'foo'}).toEqual(jasmine.any(Function))).toFail();
|
||||
expect(match(
|
||||
function() {
|
||||
}).toEqual(jasmine.any(Object))).toFail();
|
||||
expect(match(["foo", "goo"]).toEqual(["foo", jasmine.any(String)])).toPass();
|
||||
expect(match(
|
||||
function() {
|
||||
}).toEqual(jasmine.any(Function))).toPass();
|
||||
expect(match(["a", function() {
|
||||
}]).toEqual(["a", jasmine.any(Function)])).toPass();
|
||||
});
|
||||
|
||||
it("toEqual handles circular objects ok", function() {
|
||||
expect(match({foo: "bar", baz: jasmine.undefined}).toEqual({foo: "bar", baz: jasmine.undefined})).toPass();
|
||||
expect(match({foo:['bar','baz','quux']}).toEqual({foo:['bar','baz','quux']})).toPass();
|
||||
expect(match({foo: {bar:'baz'}, quux:'corge'}).toEqual({foo:{bar:'baz'}, quux:'corge'})).toPass();
|
||||
|
||||
var circularObject = {};
|
||||
var secondCircularObject = {};
|
||||
circularObject.field = circularObject;
|
||||
secondCircularObject.field = secondCircularObject;
|
||||
expect(match(circularObject).toEqual(secondCircularObject)).toPass();
|
||||
});
|
||||
|
||||
it("toNotEqual as slightly surprising behavior, but is it intentional?", function() {
|
||||
expect(match({x:"x", y:"y", z:"w"}).toNotEqual({x:"x", y:"y", z:"z"})).toPass();
|
||||
expect(match({x:"x", y:"y", w:"z"}).toNotEqual({x:"x", y:"y", z:"z"})).toPass();
|
||||
expect(match({x:"x", y:"y", z:"z"}).toNotEqual({w: "w", x:"x", y:"y", z:"z"})).toPass();
|
||||
expect(match({w: "w", x:"x", y:"y", z:"z"}).toNotEqual({x:"x", y:"y", z:"z"})).toPass();
|
||||
});
|
||||
|
||||
it("toEqual handles arrays", function() {
|
||||
expect(match([1, "A"]).toEqual([1, "A"])).toPass();
|
||||
});
|
||||
|
||||
it("toContain and toNotContain", function() {
|
||||
expect(match('ABC').toContain('A')).toPass();
|
||||
expect(match('ABC').toContain('X')).toFail();
|
||||
|
||||
expect(match(['A', 'B', 'C']).toContain('A')).toPass();
|
||||
expect(match(['A', 'B', 'C']).toContain('F')).toFail();
|
||||
expect(match(['A', 'B', 'C']).toNotContain('F')).toPass();
|
||||
expect(match(['A', 'B', 'C']).toNotContain('A')).toFail();
|
||||
|
||||
expect(match(['A', {some:'object'}, 'C']).toContain({some:'object'})).toPass();
|
||||
expect(match(['A', {some:'object'}, 'C']).toContain({some:'other object'})).toFail();
|
||||
});
|
||||
|
||||
it("toContain to build an ExpectationResult", function() {
|
||||
var actual = ['a','b','c'];
|
||||
var matcher = match(actual);
|
||||
var expected = 'x';
|
||||
matcher.toContain(expected);
|
||||
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toContain");
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toMatch(jasmine.pp(actual));
|
||||
expect(result.message).toMatch('contain');
|
||||
expect(result.message).toMatch(jasmine.pp(expected));
|
||||
expect(result.actual).toEqual(actual);
|
||||
expect(result.expected).toEqual(expected);
|
||||
});
|
||||
|
||||
it("toNotContain to build an ExpectationResult", function() {
|
||||
var actual = ['a','b','c'];
|
||||
var matcher = match(actual);
|
||||
var expected = 'b';
|
||||
matcher.toNotContain(expected);
|
||||
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toNotContain");
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toMatch(jasmine.pp(actual));
|
||||
expect(result.message).toMatch('not contain');
|
||||
expect(result.message).toMatch(jasmine.pp(expected));
|
||||
expect(result.actual).toEqual(actual);
|
||||
expect(result.expected).toEqual(expected);
|
||||
});
|
||||
|
||||
it("toBeLessThan should pass if actual is less than expected", function() {
|
||||
expect(match(37).toBeLessThan(42)).toPass();
|
||||
expect(match(37).toBeLessThan(-42)).toFail();
|
||||
expect(match(37).toBeLessThan(37)).toFail();
|
||||
});
|
||||
|
||||
it("toBeLessThan to build an ExpectationResult", function() {
|
||||
var actual = 3;
|
||||
var matcher = match(actual);
|
||||
var expected = 1;
|
||||
matcher.toBeLessThan(expected);
|
||||
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toBeLessThan");
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toMatch(jasmine.pp(actual) + ' to be less than');
|
||||
expect(result.message).toMatch(jasmine.pp(expected));
|
||||
expect(result.actual).toEqual(actual);
|
||||
expect(result.expected).toEqual(expected);
|
||||
});
|
||||
|
||||
it("toBeGreaterThan should pass if actual is greater than expected", function() {
|
||||
expect(match(37).toBeGreaterThan(42)).toFail();
|
||||
expect(match(37).toBeGreaterThan(-42)).toPass();
|
||||
expect(match(37).toBeGreaterThan(37)).toFail();
|
||||
});
|
||||
|
||||
it("toBeGreaterThan to build an ExpectationResult", function() {
|
||||
var actual = 1;
|
||||
var matcher = match(actual);
|
||||
var expected = 3;
|
||||
matcher.toBeGreaterThan(expected);
|
||||
|
||||
var result = lastResult();
|
||||
|
||||
expect(result.matcherName).toEqual("toBeGreaterThan");
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toMatch(jasmine.pp(actual) + ' to be greater than');
|
||||
expect(result.message).toMatch(jasmine.pp(expected));
|
||||
expect(result.actual).toEqual(actual);
|
||||
expect(result.expected).toEqual(expected);
|
||||
});
|
||||
|
||||
describe("toBeCloseTo", function() {
|
||||
it("returns 'true' iff actual and expected are equal within 2 decimal points of precision", function() {
|
||||
expect(0).toBeCloseTo(0);
|
||||
expect(1).toBeCloseTo(1);
|
||||
expect(1).not.toBeCloseTo(1.1);
|
||||
expect(1).not.toBeCloseTo(1.01);
|
||||
expect(1).toBeCloseTo(1.001);
|
||||
|
||||
expect(1.23).toBeCloseTo(1.234);
|
||||
expect(1.23).toBeCloseTo(1.233);
|
||||
expect(1.23).toBeCloseTo(1.232);
|
||||
expect(1.23).not.toBeCloseTo(1.24);
|
||||
|
||||
expect(-1.23).toBeCloseTo(-1.234);
|
||||
expect(-1.23).not.toBeCloseTo(-1.24);
|
||||
});
|
||||
|
||||
it("accepts an optional precision argument", function() {
|
||||
expect(1).toBeCloseTo(1.1, 0);
|
||||
expect(1.2).toBeCloseTo(1.23, 1);
|
||||
|
||||
expect(1.234).toBeCloseTo(1.2343, 3);
|
||||
expect(1.234).not.toBeCloseTo(1.233, 3);
|
||||
});
|
||||
|
||||
it("rounds", function() {
|
||||
expect(1.23).toBeCloseTo(1.229);
|
||||
expect(1.23).toBeCloseTo(1.226);
|
||||
expect(1.23).toBeCloseTo(1.225);
|
||||
expect(1.23).not.toBeCloseTo(1.2249999);
|
||||
|
||||
expect(1.23).toBeCloseTo(1.234);
|
||||
expect(1.23).toBeCloseTo(1.2349999);
|
||||
expect(1.23).not.toBeCloseTo(1.235);
|
||||
|
||||
expect(-1.23).toBeCloseTo(-1.234);
|
||||
expect(-1.23).not.toBeCloseTo(-1.235);
|
||||
expect(-1.23).not.toBeCloseTo(-1.236);
|
||||
});
|
||||
});
|
||||
|
||||
describe("toThrow", function() {
|
||||
describe("when code block throws an exception", function() {
|
||||
var throwingFn;
|
||||
|
||||
beforeEach(function() {
|
||||
throwingFn = function() {
|
||||
throw new Error("Fake Error");
|
||||
};
|
||||
});
|
||||
|
||||
it("should match any exception", function() {
|
||||
expect(match(throwingFn).toThrow()).toPass();
|
||||
});
|
||||
|
||||
it("should match exceptions specified by message", function() {
|
||||
expect(match(throwingFn).toThrow("Fake Error")).toPass();
|
||||
expect(match(throwingFn).toThrow("Other Error")).toFail();
|
||||
expect(lastResult().message).toMatch("Other Error");
|
||||
});
|
||||
|
||||
it("should match exceptions specified by Error", function() {
|
||||
expect(match(throwingFn).toThrow(new Error("Fake Error"))).toPass();
|
||||
expect(match(throwingFn).toThrow(new Error("Other Error"))).toFail();
|
||||
expect(lastResult().message).toMatch("Other Error");
|
||||
});
|
||||
|
||||
describe("and matcher is inverted with .not", function() {
|
||||
it("should match any exception", function() {
|
||||
expect(match(throwingFn).not.toThrow()).toFail();
|
||||
expect(lastResult().message).toMatch(/Expected function not to throw an exception/);
|
||||
});
|
||||
|
||||
it("should match exceptions specified by message", function() {
|
||||
expect(match(throwingFn).not.toThrow("Fake Error")).toFail();
|
||||
// expect(lastResult().message).toMatch(/Expected function not to throw Fake Error./);
|
||||
expect(match(throwingFn).not.toThrow("Other Error")).toPass();
|
||||
});
|
||||
|
||||
it("should match exceptions specified by Error", function() {
|
||||
expect(match(throwingFn).not.toThrow(new Error("Fake Error"))).toFail();
|
||||
// expect(lastResult().message).toMatch("Other Error");
|
||||
expect(match(throwingFn).not.toThrow(new Error("Other Error"))).toPass();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("when actual is not a function", function() {
|
||||
it("should fail with an exception", function() {
|
||||
var exception = catchException(function() {
|
||||
match('not-a-function').toThrow();
|
||||
});
|
||||
expect(exception).toBeDefined();
|
||||
expect(exception.message).toEqual('Actual is not a function');
|
||||
});
|
||||
|
||||
describe("and matcher is inverted with .not", function() {
|
||||
it("should fail with an exception", function() {
|
||||
var exception = catchException(function() {
|
||||
match('not-a-function').not.toThrow();
|
||||
});
|
||||
expect(exception).toBeDefined();
|
||||
expect(exception.message).toEqual('Actual is not a function');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe("when code block does not throw an exception", function() {
|
||||
it("should fail (or pass when inverted with .not)", function() {
|
||||
expect(match(
|
||||
function() {
|
||||
}).toThrow()).toFail();
|
||||
expect(lastResult().message).toEqual('Expected function to throw an exception.');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe(".not.matcher", function() {
|
||||
it("should invert the sense of any matcher", function() {
|
||||
expect(match(37).not.toBeGreaterThan(42)).toPass();
|
||||
expect(match(42).not.toBeGreaterThan(37)).toFail();
|
||||
expect(match("abc").not.toEqual("def")).toPass();
|
||||
expect(match("abc").not.toEqual("abc")).toFail();
|
||||
});
|
||||
|
||||
it("should provide an inverted default message", function() {
|
||||
match(37).not.toBeGreaterThan(42);
|
||||
expect(lastResult().message).toEqual("Passed.");
|
||||
|
||||
match(42).not.toBeGreaterThan(37);
|
||||
expect(lastResult().message).toEqual("Expected 42 not to be greater than 37.");
|
||||
});
|
||||
|
||||
it("should use the second message when the matcher sets an array of custom messages", function() {
|
||||
spec.addMatchers({
|
||||
custom: function() {
|
||||
this.message = function() {
|
||||
return ['Expected it was called.', 'Expected it wasn\'t called.'];
|
||||
};
|
||||
return this.actual;
|
||||
}
|
||||
});
|
||||
|
||||
match(true).custom();
|
||||
expect(lastResult().message).toEqual("Passed.");
|
||||
match(false).custom();
|
||||
expect(lastResult().message).toEqual("Expected it was called.");
|
||||
match(true).not.custom();
|
||||
expect(lastResult().message).toEqual("Expected it wasn't called.");
|
||||
match(false).not.custom();
|
||||
expect(lastResult().message).toEqual("Passed.");
|
||||
});
|
||||
});
|
||||
|
||||
describe("spy matchers >>", function() {
|
||||
var TestClass;
|
||||
beforeEach(function() {
|
||||
TestClass = {
|
||||
normalFunction: function() {
|
||||
},
|
||||
spyFunction: jasmine.createSpy("My spy")
|
||||
};
|
||||
});
|
||||
|
||||
function shouldThrowAnExceptionWhenInvokedOnANonSpy(methodName) {
|
||||
return function() {
|
||||
expect(
|
||||
function() {
|
||||
match(TestClass.normalFunction)[methodName]();
|
||||
}).toThrow('Expected a spy, but got Function.');
|
||||
|
||||
expect(
|
||||
function() {
|
||||
match(jasmine.undefined)[methodName]();
|
||||
}).toThrow('Expected a spy, but got undefined.');
|
||||
|
||||
expect(
|
||||
function() {
|
||||
match({some:'object'})[methodName]();
|
||||
}).toThrow('Expected a spy, but got { some : \'object\' }.');
|
||||
|
||||
expect(
|
||||
function() {
|
||||
match("<b>")[methodName]();
|
||||
}).toThrow('Expected a spy, but got \'<b>\'.');
|
||||
};
|
||||
}
|
||||
|
||||
describe("toHaveBeenCalled", function() {
|
||||
it("should pass if the spy was called", function() {
|
||||
expect(match(TestClass.spyFunction).toHaveBeenCalled()).toFail();
|
||||
|
||||
TestClass.spyFunction();
|
||||
expect(match(TestClass.spyFunction).toHaveBeenCalled()).toPass();
|
||||
});
|
||||
|
||||
it("should throw an exception when invoked with any arguments", function() {
|
||||
expect(
|
||||
function() {
|
||||
match(TestClass.normalFunction).toHaveBeenCalled("unwanted argument");
|
||||
}).toThrow('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith');
|
||||
});
|
||||
|
||||
it('should throw an exception when invoked on a non-spy', shouldThrowAnExceptionWhenInvokedOnANonSpy('toHaveBeenCalled'));
|
||||
});
|
||||
|
||||
describe("wasCalled", function() {
|
||||
it("should alias toHaveBeenCalled", function() {
|
||||
spyOn(TestClass, 'normalFunction');
|
||||
|
||||
TestClass.normalFunction();
|
||||
|
||||
expect(TestClass.normalFunction).wasCalled();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe("wasNotCalled", function() {
|
||||
it("should pass iff the spy was not called", function() {
|
||||
expect(match(TestClass.spyFunction).wasNotCalled()).toPass();
|
||||
|
||||
TestClass.spyFunction();
|
||||
expect(match(TestClass.spyFunction).wasNotCalled()).toFail();
|
||||
});
|
||||
|
||||
it("should throw an exception when invoked with any arguments", function() {
|
||||
expect(
|
||||
function() {
|
||||
match(TestClass.normalFunction).wasNotCalled("unwanted argument");
|
||||
}).toThrow('wasNotCalled does not take arguments');
|
||||
});
|
||||
|
||||
it('should throw an exception when invoked on a non-spy', shouldThrowAnExceptionWhenInvokedOnANonSpy('wasNotCalled'));
|
||||
});
|
||||
|
||||
describe("toHaveBeenCalledWith", function() {
|
||||
it('toHaveBeenCalledWith should return true if it was called with the expected args', function() {
|
||||
TestClass.spyFunction('a', 'b', 'c');
|
||||
expect(match(TestClass.spyFunction).toHaveBeenCalledWith('a', 'b', 'c')).toPass();
|
||||
});
|
||||
|
||||
it('should return false if it was not called with the expected args', function() {
|
||||
TestClass.spyFunction('a', 'b', 'c');
|
||||
var expected = match(TestClass.spyFunction);
|
||||
expect(expected.toHaveBeenCalledWith('c', 'b', 'a')).toFail();
|
||||
var result = lastResult();
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.expected).toEqual(['c', 'b', 'a']);
|
||||
expect(result.actual.mostRecentCall.args).toEqual(['a', 'b', 'c']);
|
||||
expect(result.message).toContain(jasmine.pp(result.expected));
|
||||
expect(result.message).toContain(jasmine.pp(result.actual.mostRecentCall.args));
|
||||
});
|
||||
|
||||
it('should return false if it was not called', function() {
|
||||
var expected = match(TestClass.spyFunction);
|
||||
expect(expected.toHaveBeenCalledWith('c', 'b', 'a')).toFail();
|
||||
var result = lastResult();
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.expected).toEqual(['c', 'b', 'a']);
|
||||
expect(result.actual.argsForCall).toEqual([]);
|
||||
expect(result.message).toContain(jasmine.pp(result.expected));
|
||||
});
|
||||
|
||||
it('should allow matches across multiple calls', function() {
|
||||
TestClass.spyFunction('a', 'b', 'c');
|
||||
TestClass.spyFunction('d', 'e', 'f');
|
||||
var expected = match(TestClass.spyFunction);
|
||||
expect(expected.toHaveBeenCalledWith('a', 'b', 'c')).toPass();
|
||||
expect(expected.toHaveBeenCalledWith('d', 'e', 'f')).toPass();
|
||||
expect(expected.toHaveBeenCalledWith('x', 'y', 'z')).toFail();
|
||||
});
|
||||
|
||||
it("should return a decent message", function() {
|
||||
TestClass.spyFunction('a', 'b', 'c');
|
||||
TestClass.spyFunction('d', 'e', 'f');
|
||||
var expected = match(TestClass.spyFunction);
|
||||
expect(expected.toHaveBeenCalledWith('a', 'b')).toFail();
|
||||
expect(lastResult().message).toEqual("Expected spy My spy to have been called with [ 'a', 'b' ] but was called with [ [ 'a', 'b', 'c' ], [ 'd', 'e', 'f' ] ]");
|
||||
});
|
||||
|
||||
it("should return a decent message when inverted", function() {
|
||||
TestClass.spyFunction('a', 'b', 'c');
|
||||
TestClass.spyFunction('d', 'e', 'f');
|
||||
var expected = match(TestClass.spyFunction);
|
||||
expect(expected.not.toHaveBeenCalledWith('a', 'b', 'c')).toFail();
|
||||
expect(lastResult().message).toEqual("Expected spy My spy not to have been called with [ 'a', 'b', 'c' ] but was called with [ [ 'a', 'b', 'c' ], [ 'd', 'e', 'f' ] ]");
|
||||
});
|
||||
|
||||
it('should throw an exception when invoked on a non-spy', shouldThrowAnExceptionWhenInvokedOnANonSpy('toHaveBeenCalledWith'));
|
||||
|
||||
describe("to build an ExpectationResult", function () {
|
||||
beforeEach(function() {
|
||||
var currentSuite;
|
||||
var spec;
|
||||
currentSuite = env.describe('default current suite', function() {
|
||||
spec = env.it();
|
||||
}, spec);
|
||||
TestClass = { someFunction: function(a, b) {
|
||||
} };
|
||||
spec.spyOn(TestClass, 'someFunction');
|
||||
});
|
||||
|
||||
it("should should handle the case of a spy", function() {
|
||||
TestClass.someFunction('a', 'c');
|
||||
var matcher = match(TestClass.someFunction);
|
||||
matcher.toHaveBeenCalledWith('a', 'b');
|
||||
|
||||
var result = lastResult();
|
||||
expect(result.matcherName).toEqual("toHaveBeenCalledWith");
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.message).toContain(jasmine.pp(['a', 'b']));
|
||||
expect(result.message).toContain(jasmine.pp(['a', 'c']));
|
||||
expect(result.actual).toEqual(TestClass.someFunction);
|
||||
expect(result.expected).toEqual(['a','b']);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("wasCalledWith", function() {
|
||||
it("should alias toHaveBeenCalledWith", function() {
|
||||
spyOn(TestClass, 'normalFunction');
|
||||
|
||||
TestClass.normalFunction(123);
|
||||
|
||||
expect(TestClass.normalFunction).wasCalledWith(123);
|
||||
});
|
||||
});
|
||||
|
||||
describe("wasNotCalledWith", function() {
|
||||
it('should return true if the spy was NOT called with the expected args', function() {
|
||||
TestClass.spyFunction('a', 'b', 'c');
|
||||
expect(match(TestClass.spyFunction).wasNotCalledWith('c', 'b', 'a')).toPass();
|
||||
});
|
||||
|
||||
it('should return false if it WAS called with the expected args', function() {
|
||||
TestClass.spyFunction('a', 'b', 'c');
|
||||
var expected = match(TestClass.spyFunction);
|
||||
expect(expected.wasNotCalledWith('a', 'b', 'c')).toFail();
|
||||
var result = lastResult();
|
||||
expect(result.passed()).toFail();
|
||||
expect(result.expected).toEqual(['a', 'b', 'c']);
|
||||
expect(result.actual.mostRecentCall.args).toEqual(['a', 'b', 'c']);
|
||||
expect(result.message).toContain(jasmine.pp(result.expected));
|
||||
});
|
||||
|
||||
it('should return true if it was not called', function() {
|
||||
var expected = match(TestClass.spyFunction);
|
||||
expect(expected.wasNotCalledWith('c', 'b', 'a')).toPass();
|
||||
});
|
||||
|
||||
it('should allow matches across multiple calls', function() {
|
||||
var expected = match(TestClass.spyFunction);
|
||||
TestClass.spyFunction('a', 'b', 'c');
|
||||
TestClass.spyFunction('d', 'e', 'f');
|
||||
expect(expected.wasNotCalledWith('a', 'b', 'c')).toFail();
|
||||
expect(expected.wasNotCalledWith('d', 'e', 'f')).toFail();
|
||||
expect(expected.wasNotCalledWith('x', 'y', 'z')).toPass();
|
||||
});
|
||||
|
||||
it('should throw an exception when invoked on a non-spy', shouldThrowAnExceptionWhenInvokedOnANonSpy('wasNotCalledWith'));
|
||||
});
|
||||
});
|
||||
|
||||
describe("all matchers", function() {
|
||||
it("should return null, for future-proofing, since we might eventually allow matcher chaining", function() {
|
||||
expect(match(true).toBe(true)).toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user