Compare commits
830 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e86a7f00a6 | ||
|
|
504ef27899 | ||
|
|
572452a15a | ||
|
|
896412367a | ||
|
|
503a7409f0 | ||
|
|
bb9175cb66 | ||
|
|
469b557828 | ||
|
|
503715c275 | ||
|
|
4482355885 | ||
|
|
6542364381 | ||
|
|
1fc911e0fa | ||
|
|
fdad8849df | ||
|
|
7a289f1de7 | ||
|
|
ef981bb794 | ||
|
|
c3fb3e985a | ||
|
|
7fc3408051 | ||
|
|
af1b43eeff | ||
|
|
4c043717a9 | ||
|
|
40be00310d | ||
|
|
1f318c3c93 | ||
|
|
be29aa95eb | ||
|
|
e3c9a59c6c | ||
|
|
b312ed4940 | ||
|
|
00f6708e1f | ||
|
|
3a47a3bd04 | ||
|
|
1c9382c990 | ||
|
|
394be99832 | ||
|
|
62a667a8e3 | ||
|
|
d277827d5e | ||
|
|
644c175338 | ||
|
|
a6d7eb2a06 | ||
|
|
dd8a65cb60 | ||
|
|
e72d161fab | ||
|
|
dcaac62a6c | ||
|
|
b696bec9e3 | ||
|
|
43073b3bc5 | ||
|
|
286524959b | ||
|
|
2c32dd5703 | ||
|
|
c1d1d69be2 | ||
|
|
3513249d73 | ||
|
|
21bfbbb721 | ||
|
|
88b90ec258 | ||
|
|
50c88e7774 | ||
|
|
3e64ce3310 | ||
|
|
00586e50e0 | ||
|
|
dc80a282ba | ||
|
|
27c650ec08 | ||
|
|
56daa6f461 | ||
|
|
e4c7d8af45 | ||
|
|
ee88ecc614 | ||
|
|
ec038273f1 | ||
|
|
c5bdd79a1e | ||
|
|
dbc1a0aa56 | ||
|
|
5862b22aef | ||
|
|
163f93d6ff | ||
|
|
1893bf6c16 | ||
|
|
095745ab12 | ||
|
|
68db3f6fcf | ||
|
|
1e4f0d1545 | ||
|
|
c546d2cb6d | ||
|
|
6e097528f5 | ||
|
|
4e1f36cbb0 | ||
|
|
0aee81cfb9 | ||
|
|
1e50b49092 | ||
|
|
6aecf16cde | ||
|
|
f2de1be96a | ||
|
|
5f4a1c4276 | ||
|
|
a4ef3687ee | ||
|
|
9065b4c3b7 | ||
|
|
140225e7c3 | ||
|
|
8b38389d56 | ||
|
|
b7c2a2f6fb | ||
|
|
c5d4a40219 | ||
|
|
c7c8b6b93e | ||
|
|
8a42437059 | ||
|
|
cacc6f4278 | ||
|
|
d815e99456 | ||
|
|
5e3f937221 | ||
|
|
d666f1efbb | ||
|
|
4515b76f07 | ||
|
|
0897e31a2d | ||
|
|
9555cb9842 | ||
|
|
d6fa9dd1a0 | ||
|
|
25fbe0646a | ||
|
|
316ce1e2d3 | ||
|
|
82cc1083b6 | ||
|
|
c2f04ba627 | ||
|
|
97a46f4560 | ||
|
|
113134cdbd | ||
|
|
dad5f5fd6b | ||
|
|
fa72544974 | ||
|
|
e303de52ed | ||
|
|
5f9315731e | ||
|
|
ce850c472a | ||
|
|
2fc5182ddc | ||
|
|
6be2102b64 | ||
|
|
c6a79d3ab7 | ||
|
|
3f232fba80 | ||
|
|
cde6ea79a3 | ||
|
|
0782a73a98 | ||
|
|
37073e2768 | ||
|
|
f7f928fdd3 | ||
|
|
503b653a10 | ||
|
|
cb044aa273 | ||
|
|
5c17456925 | ||
|
|
592fba22b8 | ||
|
|
58ef707bc6 | ||
|
|
050c1f051c | ||
|
|
8d0c52e2ec | ||
|
|
de91427356 | ||
|
|
324bc201c2 | ||
|
|
76f34e90dc | ||
|
|
46e7158c77 | ||
|
|
9ab039e330 | ||
|
|
3f5c47dff3 | ||
|
|
1320b0614f | ||
|
|
905e3fc3f9 | ||
|
|
89331bb1bb | ||
|
|
88de272c89 | ||
|
|
60bbe68148 | ||
|
|
623e638cd4 | ||
|
|
b1bcd6e825 | ||
|
|
204acf7297 | ||
|
|
cd1131354b | ||
|
|
c24aef15b1 | ||
|
|
d5d5d1965f | ||
|
|
d27bb8fa96 | ||
|
|
7d5ca27b9d | ||
|
|
795651d3b6 | ||
|
|
e7daa429a1 | ||
|
|
51ad18cb28 | ||
|
|
0b81705c11 | ||
|
|
00feef8632 | ||
|
|
5a715aecee | ||
|
|
8cb44582bc | ||
|
|
53d8073707 | ||
|
|
e0eb4755cb | ||
|
|
6277046213 | ||
|
|
6b9739030d | ||
|
|
b0d949e0d5 | ||
|
|
dfdcfc5be5 | ||
|
|
e5bb89847f | ||
|
|
1f68ed836e | ||
|
|
c4e65e4a9a | ||
|
|
0cfeb0b9c3 | ||
|
|
d51da18808 | ||
|
|
6f3e85f755 | ||
|
|
d04b813cab | ||
|
|
70c416d5c9 | ||
|
|
226d3ba939 | ||
|
|
aa6cc31057 | ||
|
|
f8ae3eaeaa | ||
|
|
db6aa8f3f8 | ||
|
|
4e2f703615 | ||
|
|
ba2aae63be | ||
|
|
fb23277367 | ||
|
|
8cd4873e48 | ||
|
|
11b63e4e3e | ||
|
|
b3ab9fad9d | ||
|
|
13b967b59c | ||
|
|
0253d4fb71 | ||
|
|
44875673c1 | ||
|
|
3943cc2ddb | ||
|
|
f4753ac0a4 | ||
|
|
ce2161ca32 | ||
|
|
17eda7a2de | ||
|
|
7119720fc7 | ||
|
|
f4e192a428 | ||
|
|
45ad7fd13c | ||
|
|
0cb304131f | ||
|
|
8a731e17a7 | ||
|
|
7416c176a7 | ||
|
|
0f6ebaa784 | ||
|
|
f14f620e15 | ||
|
|
e94e6c5b75 | ||
|
|
f90d9943fe | ||
|
|
8991b1bba3 | ||
|
|
78c3a007ad | ||
|
|
30b31096b8 | ||
|
|
2b318a6154 | ||
|
|
41293714fd | ||
|
|
08779f2657 | ||
|
|
76a99aef86 | ||
|
|
6b213a958d | ||
|
|
9a7dfb15d2 | ||
|
|
ec9904bf52 | ||
|
|
bcc28d7063 | ||
|
|
79d55216fc | ||
|
|
7e940542f8 | ||
|
|
ec3ebcb7bb | ||
|
|
c521b4d47c | ||
|
|
66fe69a149 | ||
|
|
e13fd13529 | ||
|
|
f1eac6fb04 | ||
|
|
6440ca434d | ||
|
|
93ad31e0af | ||
|
|
a6a9550d1e | ||
|
|
6c68715554 | ||
|
|
258d55469e | ||
|
|
5096d9af4e | ||
|
|
3be797c8d8 | ||
|
|
d10e8c2ddf | ||
|
|
c2ada1af95 | ||
|
|
ea3dd9dffc | ||
|
|
d41139fea2 | ||
|
|
873d1c2945 | ||
|
|
25816a6e77 | ||
|
|
1f23f1e4d2 | ||
|
|
dec67bd535 | ||
|
|
83b336d9d1 | ||
|
|
be3c8275d4 | ||
|
|
bf4694333c | ||
|
|
9febe3159d | ||
|
|
5e98ee951c | ||
|
|
fd5b9ce1ae | ||
|
|
58c63e98bb | ||
|
|
7f392d188e | ||
|
|
6baf3a9270 | ||
|
|
1545112744 | ||
|
|
8a5216401f | ||
|
|
fffb8abb24 | ||
|
|
17e9088ac5 | ||
|
|
d19ffcc231 | ||
|
|
0b4a9edff8 | ||
|
|
e02c24d151 | ||
|
|
913ad50a76 | ||
|
|
c395c525dc | ||
|
|
12fefa4b3d | ||
|
|
88b98277bc | ||
|
|
4eded6ab61 | ||
|
|
6c766b7785 | ||
|
|
13ff1e037e | ||
|
|
a00f995c68 | ||
|
|
795a80ec66 | ||
|
|
3d1a96e020 | ||
|
|
076093c16c | ||
|
|
8d53f4d202 | ||
|
|
71631a6529 | ||
|
|
bed56a76f8 | ||
|
|
97fe2e7c95 | ||
|
|
ef3f127d27 | ||
|
|
472f61ab37 | ||
|
|
10dbf8be98 | ||
|
|
a497d0942a | ||
|
|
9a41154e3b | ||
|
|
fc3eb0fbd8 | ||
|
|
223924a7a1 | ||
|
|
99799f72b3 | ||
|
|
e8263e38aa | ||
|
|
53561ae71f | ||
|
|
68f25a758d | ||
|
|
96ba66ad60 | ||
|
|
ba4a8d1d00 | ||
|
|
65d9e93a88 | ||
|
|
2d3ac38df8 | ||
|
|
5a219da848 | ||
|
|
f056f3b86c | ||
|
|
aeb0b73008 | ||
|
|
7263a38c3f | ||
|
|
e8870db8d3 | ||
|
|
35d15085e3 | ||
|
|
19292e4ea4 | ||
|
|
ba71989d4b | ||
|
|
f8e5ea14bc | ||
|
|
92dfbdcdc9 | ||
|
|
8ad1dd163b | ||
|
|
ded8b760aa | ||
|
|
07318fba37 | ||
|
|
c42358c686 | ||
|
|
f77ee32c56 | ||
|
|
0bd636b5d2 | ||
|
|
008b80adc5 | ||
|
|
1a63ab4677 | ||
|
|
3a7fc63879 | ||
|
|
527619b0aa | ||
|
|
0449b35f5a | ||
|
|
e50a7b6985 | ||
|
|
b2d9aab2b8 | ||
|
|
b01d86840a | ||
|
|
385ad33f60 | ||
|
|
18195a868c | ||
|
|
7c3434723e | ||
|
|
4858a62fdc | ||
|
|
df4b6e58e2 | ||
|
|
d68b47b76d | ||
|
|
c100bb6242 | ||
|
|
c37e9b9db0 | ||
|
|
5e87e1410d | ||
|
|
0cd5d9339b | ||
|
|
6324fda065 | ||
|
|
066162d6bc | ||
|
|
ab01fa1978 | ||
|
|
65e6df55ee | ||
|
|
45475f6d1e | ||
|
|
a536ca19f2 | ||
|
|
9a6262e3cd | ||
|
|
e7d0d742a8 | ||
|
|
031515db23 | ||
|
|
49fd22ffe6 | ||
|
|
5c058b5bc4 | ||
|
|
18dbbca436 | ||
|
|
3e888105f0 | ||
|
|
15f969bee7 | ||
|
|
984018bfdf | ||
|
|
0f4e53d0e6 | ||
|
|
c73c5a9dbd | ||
|
|
243adfd4ce | ||
|
|
e07da96354 | ||
|
|
96786c793f | ||
|
|
d610d0bdad | ||
|
|
0644731680 | ||
|
|
8da1fd1ed1 | ||
|
|
8af669677a | ||
|
|
b4cbe9850f | ||
|
|
cf2c5c9acc | ||
|
|
4e10cf84d5 | ||
|
|
9f875ce666 | ||
|
|
df6a71e37d | ||
|
|
32a3288c9d | ||
|
|
b12981a3e7 | ||
|
|
cbbdd360f8 | ||
|
|
3a89cc92fb | ||
|
|
88c8c905ba | ||
|
|
d1adbdc72b | ||
|
|
8225bb935f | ||
|
|
9f704b6f3a | ||
|
|
69a7449e50 | ||
|
|
b1da6e3960 | ||
|
|
1e855aa9b8 | ||
|
|
e04d3d8a62 | ||
|
|
06814769c6 | ||
|
|
309e6df8fd | ||
|
|
ea1bac5b74 | ||
|
|
befb8995e6 | ||
|
|
1e13039478 | ||
|
|
11b0d95a7d | ||
|
|
95f6ba5fa2 | ||
|
|
d331e9cc38 | ||
|
|
0129a7d007 | ||
|
|
0fded24d35 | ||
|
|
c88c772ffb | ||
|
|
3dde56bbd8 | ||
|
|
e377f1caae | ||
|
|
91fe87ca56 | ||
|
|
ee15309a8f | ||
|
|
49c03d4a22 | ||
|
|
9a18fdca27 | ||
|
|
b2fb92eedd | ||
|
|
df818f3fbc | ||
|
|
4731b4ee4d | ||
|
|
eb30e8179a | ||
|
|
95e1890e64 | ||
|
|
72aa0bbe4d | ||
|
|
17a9a6417a | ||
|
|
d856b0548a | ||
|
|
8ab46566ac | ||
|
|
2745d7d515 | ||
|
|
35968e4a60 | ||
|
|
afb24d1050 | ||
|
|
c6d637dcb3 | ||
|
|
2fbeb201bc | ||
|
|
fd60b5737c | ||
|
|
b994a17039 | ||
|
|
74fa38bdfb | ||
|
|
369e810791 | ||
|
|
8fca3b4c11 | ||
|
|
e636f5f822 | ||
|
|
74fd0e08e7 | ||
|
|
618e24b2f8 | ||
|
|
5c7e25e228 | ||
|
|
54af109d40 | ||
|
|
873a237e3d | ||
|
|
8ca4463e01 | ||
|
|
449eb516cc | ||
|
|
a5df5a6ee9 | ||
|
|
be583232b4 | ||
|
|
d389d3c002 | ||
|
|
994d11d4f3 | ||
|
|
828d14f48e | ||
|
|
f5663a9076 | ||
|
|
a8c2399dd8 | ||
|
|
7c0f013003 | ||
|
|
ca2b62b00e | ||
|
|
4108deca02 | ||
|
|
def278f90f | ||
|
|
6bd4a29360 | ||
|
|
fd037f53a3 | ||
|
|
348242b712 | ||
|
|
b74e0abee1 | ||
|
|
e33b12b17c | ||
|
|
dde93ade18 | ||
|
|
63f900287c | ||
|
|
239a615770 | ||
|
|
92d5957a59 | ||
|
|
4991f2a713 | ||
|
|
0d6db64eb1 | ||
|
|
489fb79d6e | ||
|
|
eba8c775f3 | ||
|
|
c36a005893 | ||
|
|
37dfe50d99 | ||
|
|
c67a5b830c | ||
|
|
d803bd12a6 | ||
|
|
a621d05fa7 | ||
|
|
473f5cd359 | ||
|
|
a81e9626df | ||
|
|
b3ccd4312c | ||
|
|
5524207658 | ||
|
|
1b5e0c0c10 | ||
|
|
2d303a6e46 | ||
|
|
1e47dcf2cc | ||
|
|
ba1e8f8008 | ||
|
|
a91db0dfc2 | ||
|
|
1d130036f4 | ||
|
|
e6a60a7bef | ||
|
|
fe042fdf82 | ||
|
|
06854fe435 | ||
|
|
7b9fc80b8f | ||
|
|
3c47e71619 | ||
|
|
7cbedcdda7 | ||
|
|
3aa0115ae4 | ||
|
|
440b6934aa | ||
|
|
591bf1144b | ||
|
|
3ae61b14ad | ||
|
|
705a6508d4 | ||
|
|
306882f636 | ||
|
|
16fef04629 | ||
|
|
d180c2026e | ||
|
|
92d0882a32 | ||
|
|
04679622b0 | ||
|
|
b4cd1ec1ae | ||
|
|
963b1cca22 | ||
|
|
d4f9b41eda | ||
|
|
1019b045cd | ||
|
|
6b9ae2db7e | ||
|
|
33d8d2d3f4 | ||
|
|
12f56fdb7d | ||
|
|
afa18e554c | ||
|
|
7205d07c67 | ||
|
|
83ba2eb4d6 | ||
|
|
87865f00a3 | ||
|
|
112672c4a9 | ||
|
|
f05ab79731 | ||
|
|
3a52c444f8 | ||
|
|
f62eb3b1a8 | ||
|
|
110c092c9e | ||
|
|
8bb0e2d494 | ||
|
|
8c1b80daae | ||
|
|
ac07c9ea97 | ||
|
|
0842a80c68 | ||
|
|
e2895a92dc | ||
|
|
03998c1b20 | ||
|
|
9472df0db4 | ||
|
|
8a01e1f26c | ||
|
|
321f161ce5 | ||
|
|
202a677637 | ||
|
|
8f7327cb4d | ||
|
|
3636014917 | ||
|
|
92d33c79c7 | ||
|
|
e2897ce619 | ||
|
|
282c436463 | ||
|
|
5cc22740c9 | ||
|
|
533bda5d24 | ||
|
|
9fe9569b24 | ||
|
|
e2d9eefccd | ||
|
|
ced2b114e4 | ||
|
|
f7097281c9 | ||
|
|
01a1113387 | ||
|
|
4d0b47ac4c | ||
|
|
d6cfc4a9b5 | ||
|
|
fbcdbf5ab1 | ||
|
|
7e14a97371 | ||
|
|
c440d13754 | ||
|
|
8e8f09b41f | ||
|
|
1decb14807 | ||
|
|
a978f50f1d | ||
|
|
74287c578c | ||
|
|
7f1cdc2d02 | ||
|
|
847a959b13 | ||
|
|
05015a8b3e | ||
|
|
6f960d8662 | ||
|
|
11b8b59e03 | ||
|
|
f1ebe05f1d | ||
|
|
85b2a8c6c4 | ||
|
|
557fb4ed72 | ||
|
|
ee52023b3d | ||
|
|
91296a44f2 | ||
|
|
1923461b09 | ||
|
|
71116d3957 | ||
|
|
63cc7cafc8 | ||
|
|
fdecf02472 | ||
|
|
11f4d894a6 | ||
|
|
1149d4edde | ||
|
|
9ee85c35d2 | ||
|
|
0367ca5294 | ||
|
|
763a83c833 | ||
|
|
7fb53dcdfa | ||
|
|
a9a112e88f | ||
|
|
0184808a86 | ||
|
|
1ac2a6f608 | ||
|
|
785f62c7a0 | ||
|
|
d8c154a2c6 | ||
|
|
c974c4740c | ||
|
|
2b27bd393f | ||
|
|
3b77f38188 | ||
|
|
11827572d3 | ||
|
|
8326ecf919 | ||
|
|
cd6a0de852 | ||
|
|
148d94558d | ||
|
|
83beca6899 | ||
|
|
3c6308f1dc | ||
|
|
6193bc113b | ||
|
|
fa6a80b76e | ||
|
|
c861f6c6c2 | ||
|
|
4fcd4099ad | ||
|
|
1d495587ff | ||
|
|
c859128537 | ||
|
|
a8a5b839ab | ||
|
|
4e5d947faa | ||
|
|
c2603efeb4 | ||
|
|
fbec3cc230 | ||
|
|
1acbd1ef96 | ||
|
|
3d8e379fa6 | ||
|
|
55267e11f6 | ||
|
|
09a6e3714a | ||
|
|
8ec4d54685 | ||
|
|
516fe68759 | ||
|
|
4530f9431f | ||
|
|
d4b76a4d3b | ||
|
|
764d58a7f5 | ||
|
|
9911d37f06 | ||
|
|
32f99ef99d | ||
|
|
c142490c69 | ||
|
|
24bf3489dc | ||
|
|
5afe1222f4 | ||
|
|
274011ed03 | ||
|
|
42e00b3bc5 | ||
|
|
0eca06a33b | ||
|
|
84953ec210 | ||
|
|
e15f273f06 | ||
|
|
e908b67b19 | ||
|
|
46cc48ccfa | ||
|
|
262a2fe674 | ||
|
|
50cd6fdd68 | ||
|
|
341c6df6ea | ||
|
|
3df9cc26d4 | ||
|
|
6b156ca6d1 | ||
|
|
07996b567f | ||
|
|
9a96396f65 | ||
|
|
12a47f05bf | ||
|
|
414e03bded | ||
|
|
038ab87252 | ||
|
|
f20f78f82b | ||
|
|
70bce55721 | ||
|
|
53529bdc9a | ||
|
|
c82e5947f5 | ||
|
|
f76b452816 | ||
|
|
91aab8e1b8 | ||
|
|
486a64658f | ||
|
|
1dfdc89ba9 | ||
|
|
e2a191b116 | ||
|
|
085a1f8a16 | ||
|
|
cf2f922e30 | ||
|
|
aeeb5b7107 | ||
|
|
170a6dce76 | ||
|
|
4934e420b2 | ||
|
|
1085914a76 | ||
|
|
6f119c4e5a | ||
|
|
298b5ba127 | ||
|
|
16e07a0e99 | ||
|
|
cb6de64e58 | ||
|
|
f69949ebc0 | ||
|
|
1136fddcde | ||
|
|
b943f6b736 | ||
|
|
b439e2fb37 | ||
|
|
c79ce125c0 | ||
|
|
62b815c485 | ||
|
|
65b4499dec | ||
|
|
f38527ff15 | ||
|
|
d742ada71d | ||
|
|
b6cc34d9e9 | ||
|
|
ef9f82a17d | ||
|
|
d3a3cf1ff3 | ||
|
|
c0d0513199 | ||
|
|
86a38fceb9 | ||
|
|
c74af1d900 | ||
|
|
8ea4c6d3a1 | ||
|
|
bdbaebc045 | ||
|
|
2d33765cbf | ||
|
|
bb0992bf5f | ||
|
|
ac5d8708b9 | ||
|
|
eb93d38294 | ||
|
|
0b5dce7d84 | ||
|
|
d90e20eb15 | ||
|
|
d16aa550cb | ||
|
|
2200dd084d | ||
|
|
98ead94c51 | ||
|
|
21655a82c9 | ||
|
|
0183b1642d | ||
|
|
18ed34e9be | ||
|
|
f4caf27208 | ||
|
|
a63172f53f | ||
|
|
9619acf91f | ||
|
|
b7e4c1e779 | ||
|
|
e5ada1d010 | ||
|
|
d35b65cf79 | ||
|
|
db615e4186 | ||
|
|
5906a2c05c | ||
|
|
59ad217954 | ||
|
|
b0ec95c472 | ||
|
|
13b9e669bd | ||
|
|
2eef0747a0 | ||
|
|
7ac1244f58 | ||
|
|
6ef0e93880 | ||
|
|
2be5e0a962 | ||
|
|
a42f28c734 | ||
|
|
d58f3dac56 | ||
|
|
676689b063 | ||
|
|
aaf226b9e3 | ||
|
|
419470e9df | ||
|
|
1526d5e2a8 | ||
|
|
a3cb010971 | ||
|
|
278ef9228b | ||
|
|
82eeed3c85 | ||
|
|
ae9b95269c | ||
|
|
285f06d5c4 | ||
|
|
3aece2ac74 | ||
|
|
3a9d4ee08d | ||
|
|
26a7bc6acf | ||
|
|
7b8edcb401 | ||
|
|
395b2b2d97 | ||
|
|
bd250f27c7 | ||
|
|
b4dfdd7a48 | ||
|
|
12ed3bfacd | ||
|
|
324ad0073e | ||
|
|
9f7a6ef061 | ||
|
|
908583c49b | ||
|
|
e31db20ec7 | ||
|
|
c260c67e7e | ||
|
|
554d0efab7 | ||
|
|
ea3cf14ef8 | ||
|
|
a4bdd47a8a | ||
|
|
89306551a0 | ||
|
|
0e95b04900 | ||
|
|
da91294182 | ||
|
|
bd41a97cd5 | ||
|
|
6d3953356d | ||
|
|
62f769767a | ||
|
|
03f7f76bca | ||
|
|
4c6dadb9b1 | ||
|
|
8973e4e44f | ||
|
|
b7e9594c86 | ||
|
|
6c363f11b3 | ||
|
|
0f650e1d03 | ||
|
|
78fe42ac2d | ||
|
|
20d86b2a00 | ||
|
|
516e00d7ba | ||
|
|
c1957ecd7c | ||
|
|
1f6c91de7c | ||
|
|
f6342ad4fe | ||
|
|
8cf8736cab | ||
|
|
6d0f0ed915 | ||
|
|
7ca571a746 | ||
|
|
4240b3514b | ||
|
|
ab116fbd0f | ||
|
|
da2673e02f | ||
|
|
b2dee5cb1c | ||
|
|
1414281cff | ||
|
|
2588b442e6 | ||
|
|
af41e5ea5c | ||
|
|
8834142198 | ||
|
|
1926fc11ae | ||
|
|
e7049d3183 | ||
|
|
80dba1138a | ||
|
|
9811ff71d2 | ||
|
|
301dd4f6b5 | ||
|
|
090a6234c3 | ||
|
|
8ad9abb19a | ||
|
|
8c0a8a1b33 | ||
|
|
1db81c334d | ||
|
|
8dd0ad531c | ||
|
|
f58002f0a6 | ||
|
|
4d18e63b0f | ||
|
|
4fc177d5ae | ||
|
|
acc8c23bf4 | ||
|
|
fc6ee243e9 | ||
|
|
b256741bec | ||
|
|
1d4a2b5c22 | ||
|
|
b0aac6b852 | ||
|
|
543e056056 | ||
|
|
7dfc5f506c | ||
|
|
4cce7263c4 | ||
|
|
31164106e5 | ||
|
|
f71218a44b | ||
|
|
22e9d6df20 | ||
|
|
6ddf64568e | ||
|
|
aa72b0b7cf | ||
|
|
9f3952ff87 | ||
|
|
c604012793 | ||
|
|
6aa069d586 | ||
|
|
585287b9d6 | ||
|
|
de862f8133 | ||
|
|
4e3ae726aa | ||
|
|
9ee7b4ee0b | ||
|
|
2e737f50ca | ||
|
|
c60d669940 | ||
|
|
4c491b2dc0 | ||
|
|
f9d1e2f280 | ||
|
|
270475bc61 | ||
|
|
acb9989178 | ||
|
|
1fe1bbb6ed | ||
|
|
994878e6f6 | ||
|
|
f7c160d716 | ||
|
|
578f63b9bd | ||
|
|
b1190eefb9 | ||
|
|
271908a2c4 | ||
|
|
3372af1cf1 | ||
|
|
d355fa0806 | ||
|
|
56a79bef98 | ||
|
|
2ea4e9507c | ||
|
|
c848a66faa | ||
|
|
99fd7ddb88 | ||
|
|
5d1d19f494 | ||
|
|
4f49288f31 | ||
|
|
b9adc76dc7 | ||
|
|
9672689d40 | ||
|
|
a237ac5386 | ||
|
|
5ac3e21abb | ||
|
|
88763012e4 | ||
|
|
b1e97cfb09 | ||
|
|
8e5823c0d2 | ||
|
|
e6a7932ec1 | ||
|
|
10f1220e55 | ||
|
|
5ee03f02ed | ||
|
|
2835ca3cce | ||
|
|
120c484419 | ||
|
|
1d62504534 | ||
|
|
055d88eff8 | ||
|
|
d2b33e0c66 | ||
|
|
0c7f36a181 | ||
|
|
686d8157e5 | ||
|
|
b771c083cb | ||
|
|
fbd2ffc08b | ||
|
|
b3c8fb9797 | ||
|
|
ef3cfe7f44 | ||
|
|
0d6ecbec17 | ||
|
|
7e4b8d4531 | ||
|
|
4b696fbf26 | ||
|
|
74511f5425 | ||
|
|
3e912f7f4e | ||
|
|
19b83a7434 | ||
|
|
98569ba0f3 | ||
|
|
7f11ecb62e | ||
|
|
97f8db0616 | ||
|
|
50880fcff7 | ||
|
|
ddcae84480 | ||
|
|
9d6a95d9ba | ||
|
|
0d3b2b2f8e | ||
|
|
08f046c24c | ||
|
|
90c87140ac | ||
|
|
25d9a396aa | ||
|
|
c42b1972e2 | ||
|
|
7f8f2b5e7a | ||
|
|
9cb2f06aa6 | ||
|
|
a37b6c0d32 | ||
|
|
5533d1a920 | ||
|
|
75e652d6a7 | ||
|
|
e1f7ca51da | ||
|
|
538ae7b9ac | ||
|
|
2ea41d3e27 | ||
|
|
bd9ae3a25b | ||
|
|
1042c9a2dd | ||
|
|
92e7436db2 | ||
|
|
74fe7fb85b | ||
|
|
7e0fd79b3b | ||
|
|
8807bbb850 | ||
|
|
c93f35fbc8 | ||
|
|
4cfdd06700 | ||
|
|
19b89d437e | ||
|
|
43f96d3ecd | ||
|
|
ac42bd9b35 | ||
|
|
9fbd0ba551 | ||
|
|
52876a7bf2 | ||
|
|
2eec3427e8 | ||
|
|
ed23254865 | ||
|
|
137e7e94d3 | ||
|
|
923b8fe9c4 | ||
|
|
61cc1eec66 | ||
|
|
04be4c4583 | ||
|
|
b59ac96b51 | ||
|
|
be6ff8b24c | ||
|
|
da2005fe97 | ||
|
|
41a813521b | ||
|
|
54e7a82ef3 | ||
|
|
d5e6bf47ed | ||
|
|
5a76e59d5b | ||
|
|
f5cfa2a4c1 | ||
|
|
c21bdaf35d | ||
|
|
369e8cc08b | ||
|
|
0e9b9a11c3 | ||
|
|
9750ae59e7 | ||
|
|
2f01f64249 | ||
|
|
17c89c69d6 | ||
|
|
d85d6dd4b8 | ||
|
|
ff85714b24 | ||
|
|
0d1a9a72d9 | ||
|
|
63cc6687ff | ||
|
|
75a5681c5e | ||
|
|
9df1edbdc9 | ||
|
|
5279e7a8c4 | ||
|
|
c2e2bd7c91 | ||
|
|
bad9c63bf7 | ||
|
|
05097b3e42 | ||
|
|
1efed4c156 | ||
|
|
f4849f6401 | ||
|
|
ec2ae4d521 | ||
|
|
ac3d64cf84 | ||
|
|
2d3c8c9f26 | ||
|
|
6816bc4252 | ||
|
|
04bb56a5b5 | ||
|
|
ed31b9b844 | ||
|
|
4e47b78f1f | ||
|
|
8e23c26383 | ||
|
|
56191cfb2e | ||
|
|
8624a52ee0 | ||
|
|
de7b7c029e | ||
|
|
7a62969a14 | ||
|
|
2710bdfc5e | ||
|
|
927cc011d6 | ||
|
|
d1a94bcf50 | ||
|
|
90dea9ab38 |
205
.circleci/config.yml
Normal file
205
.circleci/config.yml
Normal file
@@ -0,0 +1,205 @@
|
||||
# Run tests against supported Node versions, and (except for pull requests)
|
||||
# against supported browsers.
|
||||
|
||||
version: 2.1
|
||||
|
||||
orbs:
|
||||
node: circleci/node@3.0.0
|
||||
|
||||
executors:
|
||||
node16:
|
||||
docker:
|
||||
- image: cimg/node:16.1.0-browsers
|
||||
working_directory: ~/workspace
|
||||
node14:
|
||||
docker:
|
||||
- image: circleci/node:14
|
||||
working_directory: ~/workspace
|
||||
node12:
|
||||
docker:
|
||||
- image: circleci/node:12
|
||||
working_directory: ~/workspace
|
||||
node10:
|
||||
docker:
|
||||
- image: circleci/node:10
|
||||
working_directory: ~/workspace
|
||||
|
||||
jobs:
|
||||
build:
|
||||
parameters:
|
||||
executor:
|
||||
type: executor
|
||||
executor: << parameters.executor >>
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Report Node and NPM versions
|
||||
command: echo "Using Node $(node --version) and NPM $(npm --version)"
|
||||
- run:
|
||||
name: Install dependencies
|
||||
command: npm install
|
||||
- run:
|
||||
name: Build
|
||||
command: npm run build
|
||||
- persist_to_workspace:
|
||||
root: .
|
||||
paths:
|
||||
- .
|
||||
|
||||
test_node: &test_node
|
||||
parameters:
|
||||
executor:
|
||||
type: executor
|
||||
executor: << parameters.executor >>
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- run:
|
||||
name: Run tests
|
||||
command: npm test
|
||||
|
||||
test_browsers: &test_browsers
|
||||
executor: node14
|
||||
environment:
|
||||
SKIP_JASMINE_BROWSER_FLAKES: "true"
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- run:
|
||||
name: Install Sauce Connect
|
||||
command: |
|
||||
cd /tmp
|
||||
curl https://saucelabs.com/downloads/sc-4.6.4-linux.tar.gz | tar zxf -
|
||||
chmod +x sc-4.6.4-linux/bin/sc
|
||||
mkdir ~/workspace/bin
|
||||
cp sc-4.6.4-linux/bin/sc ~/workspace/bin
|
||||
~/workspace/bin/sc --version
|
||||
- run:
|
||||
name: Run tests
|
||||
command: |
|
||||
# Do everything in one step because Sauce Connect won't exit
|
||||
# cleanly if we kill it from a different step than it started in.
|
||||
|
||||
export PATH=$PATH:$HOME/workspace/bin
|
||||
export SAUCE_TUNNEL_IDENTIFIER=$CIRCLE_BUILD_NUM
|
||||
scripts/start-sauce-connect sauce-pidfile
|
||||
set +o errexit
|
||||
scripts/run-all-browsers
|
||||
exitcode=$?
|
||||
set -o errexit
|
||||
scripts/stop-sauce-connect $(cat sauce-pidfile)
|
||||
exit $exitcode
|
||||
|
||||
test_browser_flakes:
|
||||
<<: *test_browsers
|
||||
environment:
|
||||
SKIP_JASMINE_BROWSER_FLAKES: "false"
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
cron:
|
||||
triggers:
|
||||
- schedule:
|
||||
# Times are UTC.
|
||||
cron: "0 11 * * *"
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- main
|
||||
- "3.99"
|
||||
- "4.0"
|
||||
jobs:
|
||||
- build:
|
||||
executor: node16
|
||||
name: build_node_16
|
||||
- build:
|
||||
executor: node14
|
||||
name: build_node_14
|
||||
- build:
|
||||
executor: node12
|
||||
name: build_node_12
|
||||
- build:
|
||||
executor: node10
|
||||
name: build_node_10
|
||||
- test_node:
|
||||
executor: node16
|
||||
name: test_node_16
|
||||
requires:
|
||||
- build_node_16
|
||||
- test_node:
|
||||
executor: node12
|
||||
name: test_node_12
|
||||
requires:
|
||||
- build_node_12
|
||||
- test_node:
|
||||
executor: node10
|
||||
name: test_node_10
|
||||
requires:
|
||||
- build_node_10
|
||||
- test_browsers:
|
||||
requires:
|
||||
- build_node_14
|
||||
filters:
|
||||
branches:
|
||||
ignore: /pull\/.*/ # Don't run on pull requests.
|
||||
|
||||
push:
|
||||
jobs:
|
||||
- build:
|
||||
executor: node16
|
||||
name: build_node_16
|
||||
- build:
|
||||
executor: node14
|
||||
name: build_node_14
|
||||
- build:
|
||||
executor: node12
|
||||
name: build_node_12
|
||||
- build:
|
||||
executor: node10
|
||||
name: build_node_10
|
||||
- test_node:
|
||||
executor: node16
|
||||
name: test_node_16
|
||||
requires:
|
||||
- build_node_16
|
||||
- test_node:
|
||||
executor: node14
|
||||
name: test_node_14
|
||||
requires:
|
||||
- build_node_14
|
||||
- test_node:
|
||||
executor: node12
|
||||
name: test_node_12
|
||||
requires:
|
||||
- build_node_12
|
||||
- test_node:
|
||||
executor: node10
|
||||
name: test_node_10
|
||||
requires:
|
||||
- build_node_10
|
||||
- test_browsers:
|
||||
requires:
|
||||
- build_node_14
|
||||
filters:
|
||||
branches:
|
||||
ignore: /pull\/.*/ # Don't run on pull requests.
|
||||
|
||||
browser-flakes:
|
||||
triggers:
|
||||
- schedule:
|
||||
# Times are UTC.
|
||||
cron: "0 10 * * *"
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- browser-flakes
|
||||
jobs:
|
||||
- build:
|
||||
executor: node14
|
||||
name: build_node_14
|
||||
- test_browser_flakes:
|
||||
requires:
|
||||
- build_node_14
|
||||
filters:
|
||||
branches:
|
||||
ignore: /pull\/.*/ # Don't run on pull requests.
|
||||
@@ -1,7 +0,0 @@
|
||||
languages:
|
||||
JavaScript: true
|
||||
exclude_paths:
|
||||
- "lib/*"
|
||||
- "dist/*"
|
||||
- "grunt/*"
|
||||
- "images/*"
|
||||
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
* text=auto eol=lf
|
||||
*.png -text
|
||||
138
.github/CONTRIBUTING.md
vendored
Normal file
138
.github/CONTRIBUTING.md
vendored
Normal file
@@ -0,0 +1,138 @@
|
||||
# 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 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. If you want to contribute but
|
||||
don't know what to work on,
|
||||
[issues tagged help needed](https://github.com/jasmine/jasmine/labels/help%20needed)
|
||||
should have enough detail to get started.
|
||||
|
||||
## Links
|
||||
|
||||
- [Jasmine Google Group](http://groups.google.com/group/jasmine-js)
|
||||
- [Jasmine-dev Google Group](http://groups.google.com/group/jasmine-js-dev)
|
||||
- [Jasmine on PivotalTracker](https://www.pivotaltracker.com/n/projects/10606)
|
||||
|
||||
## General Workflow
|
||||
|
||||
Please submit pull requests via feature branches using the semi-standard workflow of:
|
||||
|
||||
```bash
|
||||
git clone git@github.com:yourUserName/jasmine.git # Clone your fork
|
||||
cd jasmine # Change directory
|
||||
git remote add upstream https://github.com/jasmine/jasmine.git # Assign original repository to a remote named 'upstream'
|
||||
git fetch upstream # Fetch changes not present in your local repository
|
||||
git merge upstream/main # Sync local main with upstream repository
|
||||
git checkout -b my-new-feature # Create your feature branch
|
||||
git commit -am 'Add some feature' # Commit your changes
|
||||
git push origin my-new-feature # Push to the branch
|
||||
```
|
||||
|
||||
Once you've pushed a feature branch to your forked repo, you're ready to open a 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/core` - generic source files
|
||||
* `/src/html` - browser-specific files
|
||||
* `/spec` contains all of the tests
|
||||
* mirrors the source directory
|
||||
* there are some additional files
|
||||
* `/lib` contains the compiled copy of Jasmine. This is used to self-test and
|
||||
distributed as the `jasmine-core` Node, Ruby, and Python packages.
|
||||
|
||||
### 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 `jasmineUnderTest`. So there are two copies of the code loaded under test.
|
||||
|
||||
The tests should always use `jasmineUnderTest` 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.
|
||||
|
||||
### `boot0.js` and `boot1.js`
|
||||
|
||||
These files file does all of the setup necessary for Jasmine to work in a
|
||||
browser. They load all of the code, create an `Env`, attach the global
|
||||
functions, and build 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.
|
||||
|
||||
### Compatibility
|
||||
|
||||
Jasmine runs in both Node and browsers, including some older browsers that do
|
||||
not support the latest JavaScript features. See the README for the list of
|
||||
currently supported environments.
|
||||
|
||||
## 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 depends on a browser (specifically, it expects `window` to be the global or `document` is present) should live in `src/html/`.
|
||||
|
||||
### Install Dev Dependencies
|
||||
|
||||
Jasmine Core relies on Node.js.
|
||||
|
||||
To install the Node dependencies, you will need Node.js and npm.
|
||||
|
||||
$ npm install
|
||||
|
||||
...will install all of the node modules locally. Now run
|
||||
|
||||
$ npm test
|
||||
|
||||
...you should see tests run and eslint checking formatting.
|
||||
|
||||
### 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
|
||||
ESLint. 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
|
||||
|
||||
Be sure to run the tests in at least one supported Node version and at least a
|
||||
couple of supported browsers. It's also a good idea to run the tests in Internet
|
||||
Explorer if you've touched code in `src/html`, if your change involves newer
|
||||
JavaScript language/runtime features, or if you're unfamiliar with writing code
|
||||
for older browsers. To run the tests in Node, simply use `npm test` as described
|
||||
above. To run the tests in a browser, run `npm run serve` and then visit
|
||||
`http://localhost:8888`.
|
||||
|
||||
If you have the necessary Selenium drivers installed, you can also use Jasmine's
|
||||
CI tooling:
|
||||
|
||||
$ JASMINE_BROWSER=<name of browser> node spec/support/ci.js
|
||||
|
||||
The easiest way to run the tests in **Internet Explorer** is to run a VM that has IE installed. It's easy to do this with VirtualBox.
|
||||
|
||||
1. Download and install [VirtualBox](https://www.virtualbox.org/wiki/Downloads).
|
||||
1. Download a VM image [from Microsoft](https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/). Select "VirtualBox" as the platform.
|
||||
1. Unzip the downloaded archive. There should be an OVA file inside.
|
||||
1. In VirtualBox, choose `File > Import Appliance` and select the OVA file. Accept the default settings in the dialog that appears. Now you have a Windows VM!
|
||||
1. Run the VM and start IE.
|
||||
1. With `npm run serve` running on your host machine, navigate to `http://<your IP address>:8888` in IE.
|
||||
|
||||
## Before Committing or Submitting a Pull Request
|
||||
|
||||
1. Ensure all specs are green in browser *and* node.
|
||||
1. Ensure eslint and prettier are clean as part of your `npm test` command. You can run `npm run cleanup` to have prettier re-write the files.
|
||||
1. Build `jasmine.js` with `npm run build` and run all specs again - this ensures that your changes self-test well.
|
||||
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
|
||||
* When we accept your pull request, we will generate these files as a separate commit and merge the entire branch into main
|
||||
|
||||
Note that we use Circle CI for Continuous Integration. We only accept green pull requests.
|
||||
|
||||
47
.github/ISSUE_TEMPLATE.md
vendored
Normal file
47
.github/ISSUE_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
## Are you creating an issue in the correct repository?
|
||||
|
||||
- When in doubt, create an issue here.
|
||||
- If you have an issue with the Jasmine docs, file an issue in the docs repo
|
||||
here: https://github.com/jasmine/jasmine.github.io
|
||||
- If you have an issue with TypeScript typings, start a discussion at
|
||||
[DefinitelyTpyed](https://github.com/DefinitelyTyped/DefinitelyTyped/discussions/new?category=issues-with-a-types-package)
|
||||
- This repository is for the core Jasmine framework
|
||||
- If you are using a test runner that wraps Jasmine, consider filing an issue with that library if appropriate:
|
||||
- [Jasmine npm](https://github.com/jasmine/jasmine-npm/issues)
|
||||
- [Jasmine browser runner](https://github.com/jasmine/jasmine-browser/issues)
|
||||
- [Jasmine gem](https://github.com/jasmine/jasmine-gem/issues)
|
||||
- [Jasmine py](https://github.com/jasmine/jasmine-py/issues)
|
||||
- [Gulp Jasmine Browser](https://github.com/jasmine/gulp-jasmine-browser/issues)
|
||||
- [Karma](https://github.com/karma-runner/karma/issues)
|
||||
- [Grunt Contrib Jasmine](https://github.com/gruntjs/grunt-contrib-jasmine/issues)
|
||||
|
||||
<!--- Provide a general summary of the issue in the Title above -->
|
||||
|
||||
## Expected Behavior
|
||||
<!--- If you're describing a bug, tell us what should happen -->
|
||||
<!--- If you're suggesting a change/improvement, tell us how it should work -->
|
||||
|
||||
## Current Behavior
|
||||
<!--- If describing a bug, tell us what happens instead of the expected behavior -->
|
||||
<!--- If suggesting a change/improvement, explain the difference from current behavior -->
|
||||
|
||||
## Possible Solution
|
||||
<!--- Not obligatory, but suggest a fix/reason for the bug, -->
|
||||
<!--- or ideas how to implement the addition or change -->
|
||||
|
||||
## Suite that reproduces the behavior (for bugs)
|
||||
<!--- Provide a sample suite that reproduces the bug. -->
|
||||
```javascript
|
||||
describe("sample", function() {
|
||||
});
|
||||
```
|
||||
## Context
|
||||
<!--- How has this issue affected you? What are you trying to accomplish? -->
|
||||
<!--- Providing context helps us come up with a solution that is most useful in the real world -->
|
||||
|
||||
## Your Environment
|
||||
<!--- Include as many relevant details about the environment you experienced the bug in -->
|
||||
* Version used:
|
||||
* Environment name and version (e.g. Chrome 39, node.js 5.4):
|
||||
* Operating System and version (desktop or mobile):
|
||||
* Link to your project:
|
||||
30
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
30
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<!--- Provide a general summary of your changes in the Title above -->
|
||||
|
||||
## Description
|
||||
<!--- Describe your changes in detail -->
|
||||
|
||||
## Motivation and Context
|
||||
<!--- Why is this change required? What problem does it solve? -->
|
||||
<!--- If it fixes an open issue, please link to the issue here. -->
|
||||
|
||||
## How Has This Been Tested?
|
||||
<!--- Please describe in detail how you tested your changes. -->
|
||||
<!--- Include details of your testing environment, and the tests you ran to -->
|
||||
<!--- see how your change affects other areas of the code, etc. -->
|
||||
|
||||
## Types of changes
|
||||
<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->
|
||||
- [ ] Bug fix (non-breaking change which fixes an issue)
|
||||
- [ ] New feature (non-breaking change which adds functionality)
|
||||
- [ ] Breaking change (fix or feature that would cause existing functionality to change)
|
||||
|
||||
## Checklist:
|
||||
<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
|
||||
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
|
||||
- [ ] My code follows the code style of this project.
|
||||
- [ ] My change requires a change to the documentation.
|
||||
- [ ] I have updated the documentation accordingly.
|
||||
- [ ] I have read the **CONTRIBUTING** document.
|
||||
- [ ] I have added tests to cover my changes.
|
||||
- [ ] All new and existing tests passed.
|
||||
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -11,6 +11,8 @@ site/
|
||||
.bundle
|
||||
tags
|
||||
Gemfile.lock
|
||||
package-lock.json
|
||||
yarn.lock
|
||||
pkg/*
|
||||
.sass-cache/*
|
||||
src/html/.sass-cache/*
|
||||
@@ -22,3 +24,5 @@ build/
|
||||
*.egg-info/
|
||||
dist
|
||||
nbproject/
|
||||
*.iml
|
||||
.envrc
|
||||
|
||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -1,3 +0,0 @@
|
||||
[submodule "pages"]
|
||||
path = pages
|
||||
url = https://github.com/pivotal/jasmine.git
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"bitwise": true,
|
||||
"curly": true,
|
||||
"immed": true,
|
||||
"newcap": true,
|
||||
"trailing": true,
|
||||
"loopfunc": true,
|
||||
"quotmark": "single"
|
||||
}
|
||||
28
.npmignore
28
.npmignore
@@ -1,28 +0,0 @@
|
||||
dist/
|
||||
grunt/
|
||||
node_modules
|
||||
pkg/
|
||||
release_notes/
|
||||
spec/
|
||||
src/
|
||||
Gemfile
|
||||
Gemfile.lock
|
||||
Rakefile
|
||||
jasmine-core.gemspec
|
||||
.bundle/
|
||||
.gitignore
|
||||
.gitmodules
|
||||
.idea
|
||||
.jshintrc
|
||||
.rspec
|
||||
.sass-cache/
|
||||
.travis.yml
|
||||
*.sh
|
||||
*.py
|
||||
Gruntfile.js
|
||||
lib/jasmine-core.rb
|
||||
lib/jasmine-core/boot/
|
||||
lib/jasmine-core/spec
|
||||
lib/jasmine-core/version.rb
|
||||
lib/jasmine-core/*.py
|
||||
sauce_connect.log
|
||||
70
.travis.yml
70
.travis.yml
@@ -1,70 +0,0 @@
|
||||
language: ruby
|
||||
|
||||
sudo: false
|
||||
|
||||
rvm: 2.2.2
|
||||
|
||||
script: $TEST_COMMAND
|
||||
|
||||
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=
|
||||
|
||||
addons:
|
||||
sauce_connect: true
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- env:
|
||||
- USE_SAUCE=false
|
||||
- TEST_COMMAND="bash travis-node-script.sh"
|
||||
- env:
|
||||
- JASMINE_BROWSER="safari"
|
||||
- SAUCE_OS="OS X 10.11"
|
||||
- SAUCE_BROWSER_VERSION=9
|
||||
- env:
|
||||
- JASMINE_BROWSER="safari"
|
||||
- SAUCE_OS="OS X 10.10"
|
||||
- SAUCE_BROWSER_VERSION=8
|
||||
- env:
|
||||
- JASMINE_BROWSER="safari"
|
||||
- SAUCE_OS="OS X 10.9"
|
||||
- SAUCE_BROWSER_VERSION=7
|
||||
- env:
|
||||
- JASMINE_BROWSER="safari"
|
||||
- SAUCE_OS="OS X 10.8"
|
||||
- SAUCE_BROWSER_VERSION=6
|
||||
- env:
|
||||
- JASMINE_BROWSER="internet explorer"
|
||||
- SAUCE_OS="Windows 8.1"
|
||||
- SAUCE_BROWSER_VERSION=11
|
||||
- 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"
|
||||
46
CODE_OF_CONDUCT.md
Normal file
46
CODE_OF_CONDUCT.md
Normal file
@@ -0,0 +1,46 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at jasmine-maintainers@googlegroups.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
|
||||
|
||||
[homepage]: http://contributor-covenant.org
|
||||
[version]: http://contributor-covenant.org/version/1/4/
|
||||
139
CONTRIBUTING.md
139
CONTRIBUTING.md
@@ -1,139 +0,0 @@
|
||||
# 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 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. If you want to contribute but don't know what to work on, [issues tagged ready for work](https://github.com/jasmine/jasmine/labels/ready%20for%20work) should have enough detail to get started.
|
||||
|
||||
## Links
|
||||
|
||||
- [Jasmine Google Group](http://groups.google.com/group/jasmine-js)
|
||||
- [Jasmine-dev Google Group](http://groups.google.com/group/jasmine-js-dev)
|
||||
- [Jasmine on PivotalTracker](https://www.pivotaltracker.com/n/projects/10606)
|
||||
|
||||
## General Workflow
|
||||
|
||||
Please submit pull requests via feature branches using the semi-standard workflow of:
|
||||
|
||||
```bash
|
||||
git clone git@github.com:yourUserName/jasmine.git # Clone your fork
|
||||
cd jasmine # Change directory
|
||||
git remote add upstream https://github.com/jasmine/jasmine.git # Assign original repository to a remote named 'upstream'
|
||||
git fetch upstream # Pull in changes not present in your local repository
|
||||
git checkout -b my-new-feature # Create your feature branch
|
||||
git commit -am 'Add some feature' # Commit your changes
|
||||
git push origin my-new-feature # Push to the branch
|
||||
```
|
||||
|
||||
Once you've pushed a feature branch to your forked repo, you're ready to open a 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. If the ffi gem fails to build its native extensions, you may need to manually install some system dependencies. On Ubuntu:
|
||||
|
||||
$ apt-get install gcc ruby ruby-dev libxml2 libxml2-dev libxslt1-dev
|
||||
|
||||
...should get you to the point that `bundle` can install everything.
|
||||
|
||||
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. Now run
|
||||
|
||||
$ grunt
|
||||
|
||||
...if 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/jasmine/jasmine-gem) to test itself in browser.
|
||||
|
||||
$ bundle exec rake jasmine
|
||||
|
||||
...and then visit `http://localhost:8888` to run specs.
|
||||
|
||||
Jasmine uses the [Jasmine NPM package](http://github.com/jasmine/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).
|
||||
|
||||
The easiest way to run the tests in **Internet Explorer** is to run a VM that has IE installed. It's easy to do this with VirtualBox.
|
||||
|
||||
1. Download and install [VirtualBox](https://www.virtualbox.org/wiki/Downloads).
|
||||
1. Download a VM image [from Microsoft](https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/). Select "VirtualBox" as the platform.
|
||||
1. Unzip the downloaded archive. There should be an OVA file inside.
|
||||
1. In VirtualBox, choose `File > Import Appliance` and select the OVA file. Accept the default settings in the dialog that appears. Now you have a Windows VM!
|
||||
1. Run the VM and start IE.
|
||||
1. With `bundle exec rake jasmine` running on your host machine, navigate to `http://10.0.2.2:8888` in IE.
|
||||
|
||||
## 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.
|
||||
|
||||
7
Gemfile
7
Gemfile
@@ -1,9 +1,2 @@
|
||||
source 'https://rubygems.org'
|
||||
gem "jasmine", :git => 'https://github.com/jasmine/jasmine-gem.git'
|
||||
# gem "jasmine", path: "../jasmine-gem"
|
||||
|
||||
gemspec
|
||||
|
||||
gem "jasmine_selenium_runner", :github => 'jasmine/jasmine_selenium_runner'
|
||||
|
||||
gem "anchorman"
|
||||
|
||||
16
Gruntfile.js
16
Gruntfile.js
@@ -4,17 +4,17 @@ module.exports = function(grunt) {
|
||||
|
||||
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')
|
||||
sass: require('./grunt/config/sass.js'),
|
||||
compress: require('./grunt/config/compress.js'),
|
||||
cssUrlEmbed: require('./grunt/config/cssUrlEmbed.js')
|
||||
});
|
||||
|
||||
require('load-grunt-tasks')(grunt);
|
||||
|
||||
grunt.loadTasks('grunt/tasks');
|
||||
|
||||
grunt.registerTask('default', ['jshint:all']);
|
||||
grunt.registerTask('default', ['sass:dist', "cssUrlEmbed"]);
|
||||
|
||||
var version = require('./grunt/tasks/version.js');
|
||||
|
||||
@@ -25,11 +25,9 @@ module.exports = function(grunt) {
|
||||
grunt.registerTask('buildDistribution',
|
||||
'Builds and lints jasmine.js, jasmine-html.js, jasmine.css',
|
||||
[
|
||||
'compass',
|
||||
'jshint:beforeConcat',
|
||||
'concat',
|
||||
'jshint:afterConcat',
|
||||
'build:copyVersionToGem'
|
||||
'sass:dist',
|
||||
"cssUrlEmbed",
|
||||
'concat'
|
||||
]
|
||||
);
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
recursive-include . *.py
|
||||
prune node_modules
|
||||
include lib/jasmine-core/*.js
|
||||
include lib/jasmine-core/*.css
|
||||
include images/*.png
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2008-2016 Pivotal Labs
|
||||
Copyright (c) 2008-2019 Pivotal Labs
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
|
||||
88
README.md
88
README.md
@@ -1,79 +1,89 @@
|
||||
<a name="README">[<img src="https://rawgithub.com/jasmine/jasmine/master/images/jasmine-horizontal.svg" width="400px" />](http://jasmine.github.io)</a>
|
||||
<a name="README">[<img src="https://rawgithub.com/jasmine/jasmine/main/images/jasmine-horizontal.svg" width="400px" />](http://jasmine.github.io)</a>
|
||||
|
||||
[](https://travis-ci.org/jasmine/jasmine)
|
||||
[](https://codeclimate.com/github/pivotal/jasmine)
|
||||
[](https://circleci.com/gh/jasmine/jasmine)
|
||||
[](https://www.codetriage.com/jasmine/jasmine)
|
||||
[](https://app.fossa.io/projects/git%2Bgithub.com%2Fjasmine%2Fjasmine?ref=badge_shield)
|
||||
|
||||
=======
|
||||
|
||||
**A JavaScript Testing Framework**
|
||||
# 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/jasmine/jasmine/blob/v2.0.0/release_notes/20.md) for a list of what's new (including breaking interface changes). You can also read the [upgrade guide](http://jasmine.github.io/2.0/upgrading.html).
|
||||
For a quick start guide of Jasmine, see the beginning of [http://jasmine.github.io/edge/introduction.html](http://jasmine.github.io/edge/introduction.html).
|
||||
|
||||
## Contributing
|
||||
|
||||
Please read the [contributors' guide](https://github.com/jasmine/jasmine/blob/master/CONTRIBUTING.md)
|
||||
Please read the [contributors' guide](https://github.com/jasmine/jasmine/blob/main/.github/CONTRIBUTING.md).
|
||||
|
||||
## Installation
|
||||
|
||||
For the Jasmine NPM module:<br>
|
||||
[https://github.com/jasmine/jasmine-npm](https://github.com/jasmine/jasmine-npm)
|
||||
[https://github.com/jasmine/jasmine-npm](https://github.com/jasmine/jasmine-npm).
|
||||
|
||||
For the Jasmine browser runner:<br>
|
||||
[https://github.com/jasmine/jasmine-browser](https://github.com/jasmine/jasmine-browser).
|
||||
|
||||
For the Jasmine Ruby Gem:<br>
|
||||
[https://github.com/jasmine/jasmine-gem](https://github.com/jasmine/jasmine-gem)
|
||||
[https://github.com/jasmine/jasmine-gem](https://github.com/jasmine/jasmine-gem).
|
||||
|
||||
For the Jasmine Python Egg:<br>
|
||||
[https://github.com/jasmine/jasmine-py](https://github.com/jasmine/jasmine-py)
|
||||
To install Jasmine standalone on your local box (where **_{#.#.#}_** below is substituted by the release number downloaded):
|
||||
|
||||
For the Jasmine headless browser gulp plugin:<br>
|
||||
[https://github.com/jasmine/gulp-jasmine-browser](https://github.com/jasmine/gulp-jasmine-browser)
|
||||
|
||||
To install Jasmine standalone on your local box:
|
||||
|
||||
* Download the standalone distribution for your desired release from the [releases page](https://github.com/jasmine/jasmine/releases)
|
||||
* Create a Jasmine directory in your project - `mkdir my-project/jasmine`
|
||||
* Move the 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`
|
||||
* Download the standalone distribution for your desired release from the [releases page](https://github.com/jasmine/jasmine/releases).
|
||||
* Create a Jasmine directory in your project. - `mkdir my-project/jasmine`
|
||||
* Move the dist to your project directory. - `mv jasmine/dist/jasmine-standalone-{#.#.#}.zip my-project/jasmine`
|
||||
* Change directory. - `cd my-project/jasmine`
|
||||
* Unzip the dist. - `unzip jasmine-standalone-{#.#.#}.zip`
|
||||
|
||||
Add the following to your HTML file:
|
||||
|
||||
```html
|
||||
<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">
|
||||
<link rel="shortcut icon" type="image/png" href="lib/jasmine-{#.#.#}/jasmine_favicon.png">
|
||||
<link rel="stylesheet" type="text/css" href="lib/jasmine-{#.#.#}/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>
|
||||
<script type="text/javascript" src="lib/jasmine-{#.#.#}/jasmine.js"></script>
|
||||
<script type="text/javascript" src="lib/jasmine-{#.#.#}/jasmine-html.js"></script>
|
||||
<script type="text/javascript" src="lib/jasmine-{#.#.#}/boot.js"></script>
|
||||
```
|
||||
|
||||
## Supported environments
|
||||
|
||||
Jasmine tests itself across many browsers (Safari, Chrome, Firefox, PhantomJS, and new Internet Explorer) as well as node. To see the exact version tests are run against look at our [.travis.yml](https://github.com/jasmine/jasmine/blob/master/.travis.yml)
|
||||
Jasmine tests itself across many browsers (Safari, Chrome, Firefox, Microsoft Edge, and Internet Explorer) as well as nodejs.
|
||||
|
||||
| Environment | Supported versions |
|
||||
|-------------------|--------------------|
|
||||
| Node | 10, 12, 14, 16 |
|
||||
| Safari | 8-14 |
|
||||
| Chrome | Evergreen |
|
||||
| Firefox | Evergreen, 68, 78 |
|
||||
| Edge | Evergreen |
|
||||
| Internet Explorer | 10, 11 |
|
||||
|
||||
For evergreen browsers, each version of Jasmine is tested against the version of the browser that is available to us
|
||||
at the time of release. Other browsers, as well as older & newer versions of some supported browsers, are likely to work.
|
||||
However, Jasmine isn't tested against them and they aren't actively supported.
|
||||
|
||||
## 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)
|
||||
* 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:gvanhove@pivotal.io), Pivotal Labs
|
||||
* [Greg Cobb](mailto:gcobb@pivotal.io), Pivotal Labs
|
||||
* [Chris Amavisca](mailto:camavisca@pivotal.io), Pivotal Labs
|
||||
|
||||
### Maintainers Emeritus
|
||||
|
||||
* [Davis W. Frank](mailto:dwfrank@pivotal.io), Pivotal Labs
|
||||
* [Rajan Agaskar](mailto:rajan@pivotal.io), Pivotal Labs
|
||||
* [Greg Cobb](mailto:gcobb@pivotal.io), Pivotal Labs
|
||||
* [Chris Amavisca](mailto:camavisca@pivotal.io), Pivotal Labs
|
||||
* [Christian Williams](mailto:antixian666@gmail.com), Cloud Foundry
|
||||
* Sheel Choksi
|
||||
|
||||
Copyright (c) 2008-2016 Pivotal Labs. This software is licensed under the MIT License.
|
||||
Copyright (c) 2008-2018 Pivotal Labs. This software is licensed under the MIT License.
|
||||
|
||||
|
||||
## License
|
||||
[](https://app.fossa.io/projects/git%2Bgithub.com%2Fjasmine%2Fjasmine?ref=badge_large)
|
||||
|
||||
78
RELEASE.md
78
RELEASE.md
@@ -7,9 +7,7 @@ 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`.
|
||||
Please attempt to keep commits to `main` 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 pushing to `main`.
|
||||
|
||||
### Version
|
||||
|
||||
@@ -30,28 +28,38 @@ When jasmine-core revs its major or minor version, the binding libraries should
|
||||
|
||||
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
|
||||
1. Update the release notes in `release_notes` - use the Anchorman gem to generate the markdown file and edit accordingly. Include a list of supported environments.
|
||||
1. Update the version in `package.json`
|
||||
1. Run `npm run build`.
|
||||
1. Copy version to the Ruby gem with `grunt build:copyVersionToGem`
|
||||
|
||||
### Commit and push core changes
|
||||
|
||||
1. Run the browser tests using `scripts/run-all-browsers`.
|
||||
1. Commit release notes and version changes (jasmine.js, version.rb, package.json)
|
||||
1. Push
|
||||
1. Wait for Circle CI to go green
|
||||
|
||||
### Build standalone distribution
|
||||
|
||||
1. Build the standalone distribution with `grunt buildStandaloneDist`
|
||||
1. This will generate `dist/jasmine-standalone-<version>.zip`, which you will upload later (see "Finally" below).
|
||||
|
||||
### Release the Python egg
|
||||
### Release the core Ruby gem
|
||||
|
||||
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. __NOTE__: You will likely need to push a new jasmine gem with a dependent version right after this release. See below.
|
||||
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
|
||||
### Release the core Python egg
|
||||
|
||||
Install [twine](https://github.com/pypa/twine)
|
||||
|
||||
1. `python setup.py sdist`
|
||||
1. `twine upload dist/jasmine-core-<version>.tar.gz` You will need pypi credentials to upload the egg.
|
||||
|
||||
### Release the core NPM module
|
||||
|
||||
1. Run the tests on Windows. (CI only tests on Linux.)
|
||||
1. `npm adduser` to save your credentials locally
|
||||
1. `npm publish .` to publish what's in `package.json`
|
||||
|
||||
@@ -59,15 +67,35 @@ When ready to release - specs are all green and the stories are done:
|
||||
|
||||
Probably only need to do this when releasing a minor version, and not a patch version.
|
||||
|
||||
1. `cp -R edge ${version}` to copy the current edge docs to the new version
|
||||
1. Add a link to the new version in `index.html`
|
||||
1. `rake update_edge_jasmine`
|
||||
1. `npm run jsdoc`
|
||||
1. `rake release[${version}]` to copy the current edge docs to the new version
|
||||
1. Commit and push.
|
||||
|
||||
### Release the binding libraries
|
||||
|
||||
#### NPM
|
||||
|
||||
1. Create release notes using Anchorman as above
|
||||
1. In `package.json`, update both the package version and the jasmine-core dependency version
|
||||
1. Commit and push.
|
||||
1. Wait for Circle CI to go green again.
|
||||
1. Run the tests on Windows locally.
|
||||
1. `grunt release `. (Note: This will publish the package by running `npm publish`.)
|
||||
|
||||
#### Gem
|
||||
|
||||
1. Create release notes using Anchorman as above
|
||||
1. Update the version number in `lib/jasmine/version.rb`.
|
||||
1. Update the jasmine-core dependency version in `jasmine.gemspec`.
|
||||
1. Commit and push.
|
||||
1. Wait for Circle CI to go green again.
|
||||
1. `rake release`
|
||||
|
||||
### Finally
|
||||
|
||||
1. Visit the [Releases page for Jasmine](https://github.com/jasmine/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.
|
||||
For each of the above GitHub repos:
|
||||
1. Visit the releases page and find the tag just published.
|
||||
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. For core, attach the standalone zipfile.
|
||||
|
||||
16
Rakefile
16
Rakefile
@@ -1,18 +1,2 @@
|
||||
require "bundler"
|
||||
Bundler::GemHelper.install_tasks
|
||||
require "json"
|
||||
require "jasmine"
|
||||
unless ENV["JASMINE_BROWSER"] == 'phantomjs'
|
||||
require "jasmine_selenium_runner"
|
||||
end
|
||||
load "jasmine/tasks/jasmine.rake"
|
||||
|
||||
namespace :jasmine do
|
||||
task :set_env do
|
||||
ENV['JASMINE_CONFIG_PATH'] ||= 'spec/support/jasmine.yml'
|
||||
end
|
||||
end
|
||||
|
||||
task "jasmine:configure" => "jasmine:set_env"
|
||||
|
||||
task :default => "jasmine:ci"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "jasmine-core",
|
||||
"homepage": "http://jasmine.github.io",
|
||||
"homepage": "https://jasmine.github.io",
|
||||
"authors": [
|
||||
"slackersoft <gregg@slackersoft.net>"
|
||||
],
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
module.exports = {
|
||||
jasmine: {
|
||||
options: {
|
||||
cssDir: 'lib/jasmine-core/',
|
||||
sassDir: 'src/html',
|
||||
outputStyle: 'compact',
|
||||
noLineComments: true,
|
||||
bundleExec: true
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -2,7 +2,6 @@ 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 = {
|
||||
@@ -30,15 +29,7 @@ module.exports = {
|
||||
cwd: libJasmineCore("")
|
||||
},
|
||||
{
|
||||
src: [
|
||||
"console.js"
|
||||
],
|
||||
dest: standaloneLibDir,
|
||||
expand: true,
|
||||
cwd: libConsole()
|
||||
},
|
||||
{
|
||||
src: [ "boot.js" ],
|
||||
src: [ "boot0.js", "boot1.js" ],
|
||||
dest: standaloneLibDir,
|
||||
expand: true,
|
||||
cwd: libJasmineCore("boot")
|
||||
|
||||
@@ -15,7 +15,8 @@ module.exports = {
|
||||
'src/html/HtmlReporter.js',
|
||||
'src/html/HtmlSpecFilter.js',
|
||||
'src/html/ResultsNode.js',
|
||||
'src/html/QueryString.js'
|
||||
'src/html/QueryString.js',
|
||||
'src/html/**/*.js'
|
||||
],
|
||||
dest: 'lib/jasmine-core/jasmine-html.js'
|
||||
},
|
||||
@@ -40,17 +41,18 @@ module.exports = {
|
||||
src: ['lib/jasmine-core/boot/boot.js'],
|
||||
dest: 'lib/jasmine-core/boot.js'
|
||||
},
|
||||
boot0: {
|
||||
src: ['lib/jasmine-core/boot/boot0.js'],
|
||||
dest: 'lib/jasmine-core/boot0.js'
|
||||
},
|
||||
boot1: {
|
||||
src: ['lib/jasmine-core/boot/boot1.js'],
|
||||
dest: 'lib/jasmine-core/boot1.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: {
|
||||
|
||||
7
grunt/config/cssUrlEmbed.js
Normal file
7
grunt/config/cssUrlEmbed.js
Normal file
@@ -0,0 +1,7 @@
|
||||
module.exports = {
|
||||
encodeWithBaseDir: {
|
||||
files: {
|
||||
"lib/jasmine-core/jasmine.css": ["lib/jasmine-core/jasmine.css"]
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,11 +0,0 @@
|
||||
module.exports = {
|
||||
beforeConcat: ['src/**/*.js'],
|
||||
afterConcat: [
|
||||
'lib/jasmine-core/jasmine-html.js',
|
||||
'lib/jasmine-core/jasmine.js'
|
||||
],
|
||||
options: {
|
||||
jshintrc: '.jshintrc'
|
||||
},
|
||||
all: ['src/**/*.js']
|
||||
};
|
||||
13
grunt/config/sass.js
Normal file
13
grunt/config/sass.js
Normal file
@@ -0,0 +1,13 @@
|
||||
const sass = require('sass');
|
||||
|
||||
module.exports = {
|
||||
options: {
|
||||
implementation: sass,
|
||||
sourceComments: false
|
||||
},
|
||||
dist: {
|
||||
files: {
|
||||
"lib/jasmine-core/jasmine.css": "src/html/jasmine.scss"
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -9,7 +9,9 @@
|
||||
|
||||
<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>
|
||||
<script src="lib/jasmine-<%= jasmineVersion %>/boot0.js"></script>
|
||||
<!-- optional: include a file here that configures the Jasmine env -->
|
||||
<script src="lib/jasmine-<%= jasmineVersion %>/boot1.js"></script>
|
||||
|
||||
<!-- include source files here... -->
|
||||
<script src="src/Player.js"></script>
|
||||
|
||||
@@ -6,18 +6,25 @@ Gem::Specification.new do |s|
|
||||
s.name = "jasmine-core"
|
||||
s.version = Jasmine::Core::VERSION
|
||||
s.platform = Gem::Platform::RUBY
|
||||
s.authors = ["Rajan Agaskar", "Davis W. Frank", "Gregg Van Hove"]
|
||||
s.authors = ["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.description = <<~DESC
|
||||
Test your JavaScript without any framework dependencies, in any environment,
|
||||
and with a nice descriptive syntax.
|
||||
|
||||
Jasmine for Ruby is deprecated. The direct replacment for the jasmine-core
|
||||
gem is the jasmine-core NPM package. If you are also using the jasmine gem,
|
||||
we recommend using the jasmine-browser-runner NPM package instead. It
|
||||
supports all the same scenarios as the jasmine gem gem plus Webpacker. See
|
||||
https://jasmine.github.io/setup/browser.html for setup instructions, and
|
||||
https://github.com/jasmine/jasmine-gem/blob/main/release_notes/3.9.0.md
|
||||
for other options.
|
||||
DESC
|
||||
s.email = %q{jasmine-js@googlegroups.com}
|
||||
s.homepage = "http://jasmine.github.io"
|
||||
s.rubyforge_project = "jasmine-core"
|
||||
s.license = "MIT"
|
||||
|
||||
s.files = Dir.glob("./lib/**/*") + Dir.glob("./lib/jasmine-core/spec/**/*.js")
|
||||
s.files = Dir.glob("./lib/**/*")
|
||||
s.require_paths = ["lib"]
|
||||
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,190 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2008-2016 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;
|
||||
};
|
||||
@@ -5,11 +5,12 @@ var path = require('path'),
|
||||
fs = require('fs');
|
||||
|
||||
var rootPath = path.join(__dirname, "jasmine-core"),
|
||||
bootFiles = ['boot.js'],
|
||||
bootFiles = ['boot0.js', 'boot1.js'],
|
||||
legacyBootFiles = ['boot.js'],
|
||||
nodeBootFiles = ['node_boot.js'],
|
||||
cssFiles = [],
|
||||
jsFiles = [],
|
||||
jsFilesToSkip = ['jasmine.js'].concat(bootFiles, nodeBootFiles);
|
||||
jsFilesToSkip = ['jasmine.js'].concat(bootFiles, legacyBootFiles, nodeBootFiles);
|
||||
|
||||
fs.readdirSync(rootPath).forEach(function(file) {
|
||||
if(fs.statSync(path.join(rootPath, file)).isFile()) {
|
||||
|
||||
@@ -1,3 +1,28 @@
|
||||
if ENV["SUPPRESS_JASMINE_DEPRECATION"].nil?
|
||||
puts <<~END_DEPRECATION_MSG
|
||||
The Jasmine Ruby gems are deprecated. There will be no further releases after
|
||||
the end of the Jasmine 3.x series. We recommend that most users migrate to the
|
||||
jasmine-browser-runner npm package, which is the direct replacement for the
|
||||
jasmine gem. See <https://jasmine.github.io/setup/browser.html> for setup
|
||||
instructions, including for Rails applications that use either Sprockets or
|
||||
Webpacker.
|
||||
|
||||
If jasmine-browser-runner doesn't meet your needs, one of these might:
|
||||
|
||||
* The jasmine npm package to run specs in Node.js:
|
||||
<https://github.com/jasmine/jasmine-npm>
|
||||
* The standalone distribution to run specs in browsers with no additional
|
||||
tools: <https://github.com/jasmine/jasmine#installation>
|
||||
* The jasmine-core npm package if all you need is the Jasmine assets:
|
||||
<https://github.com/jasmine/jasmine>. This is the direct equivalent of the
|
||||
jasmine-core Ruby gem.
|
||||
|
||||
To prevent this message from appearing, set the SUPPRESS_JASMINE_DEPRECATION
|
||||
environment variable.
|
||||
|
||||
END_DEPRECATION_MSG
|
||||
end
|
||||
|
||||
module Jasmine
|
||||
module Core
|
||||
class << self
|
||||
@@ -6,7 +31,7 @@ module Jasmine
|
||||
end
|
||||
|
||||
def js_files
|
||||
(["jasmine.js"] + Dir.glob(File.join(path, "*.js"))).map { |f| File.basename(f) }.uniq - boot_files - node_boot_files
|
||||
(["jasmine.js"] + Dir.glob(File.join(path, "*.js"))).map { |f| File.basename(f) }.uniq - boot_files - ["boot0.js", "boot1.js"] - node_boot_files
|
||||
end
|
||||
|
||||
SPEC_TYPES = ["core", "html", "node"]
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (c) 2008-2016 Pivotal Labs
|
||||
Copyright (c) 2008-2021 Pivotal Labs
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
@@ -21,6 +21,10 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
/**
|
||||
|
||||
NOTE: This file is deprecated and will be removed in a future release.
|
||||
Include both boot0.js and boot1.js (in that order) instead.
|
||||
|
||||
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.
|
||||
@@ -31,13 +35,16 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
var jasmineRequire = window.jasmineRequire || require('./jasmine.js');
|
||||
|
||||
/**
|
||||
* ## 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);
|
||||
var jasmine = jasmineRequire.core(jasmineRequire),
|
||||
global = jasmine.getGlobal();
|
||||
global.jasmine = jasmine;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
@@ -59,7 +66,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
/**
|
||||
* Add all of the Jasmine global/public interface to the global scope, so a project can use the public interface directly. For example, calling `describe` in specs instead of `jasmine.getEnv().describe`.
|
||||
*/
|
||||
extend(window, jasmineInterface);
|
||||
extend(global, jasmineInterface);
|
||||
|
||||
/**
|
||||
* ## Runner Parameters
|
||||
@@ -71,18 +78,23 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
getWindowLocation: function() { return window.location; }
|
||||
});
|
||||
|
||||
var catchingExceptions = queryString.getParam("catch");
|
||||
env.catchExceptions(typeof catchingExceptions === "undefined" ? true : catchingExceptions);
|
||||
var filterSpecs = !!queryString.getParam("spec");
|
||||
|
||||
var throwingExpectationFailures = queryString.getParam("throwFailures");
|
||||
env.throwOnExpectationFailure(throwingExpectationFailures);
|
||||
var config = {
|
||||
failFast: queryString.getParam("failFast"),
|
||||
oneFailurePerSpec: queryString.getParam("oneFailurePerSpec"),
|
||||
hideDisabled: queryString.getParam("hideDisabled")
|
||||
};
|
||||
|
||||
var random = queryString.getParam("random");
|
||||
env.randomizeTests(random);
|
||||
|
||||
if (random !== undefined && random !== "") {
|
||||
config.random = random;
|
||||
}
|
||||
|
||||
var seed = queryString.getParam("seed");
|
||||
if (seed) {
|
||||
env.seed(seed);
|
||||
config.seed = seed;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -91,14 +103,13 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
var htmlReporter = new jasmine.HtmlReporter({
|
||||
env: env,
|
||||
onRaiseExceptionsClick: function() { queryString.navigateWithNewParam("catch", !env.catchingExceptions()); },
|
||||
onThrowExpectationsClick: function() { queryString.navigateWithNewParam("throwFailures", !env.throwingExpectationFailures()); },
|
||||
onRandomClick: function() { queryString.navigateWithNewParam("random", !env.randomTests()); },
|
||||
navigateWithNewParam: function(key, value) { return queryString.navigateWithNewParam(key, value); },
|
||||
addToExistingQueryString: function(key, value) { return queryString.fullStringWithNewParam(key, value); },
|
||||
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()
|
||||
timer: new jasmine.Timer(),
|
||||
filterSpecs: filterSpecs
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -114,10 +125,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
filterString: function() { return queryString.getParam("spec"); }
|
||||
});
|
||||
|
||||
env.specFilter = function(spec) {
|
||||
config.specFilter = function(spec) {
|
||||
return specFilter.matches(spec.getFullName());
|
||||
};
|
||||
|
||||
env.configure(config);
|
||||
|
||||
/**
|
||||
* Setting up timing functions to be able to be overridden. Certain browsers (Safari, IE 8, phantomjs) require this hack.
|
||||
*/
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
/**
|
||||
|
||||
NOTE: This file is deprecated and will be removed in a future release.
|
||||
Include both boot0.js and boot1.js (in that order) instead.
|
||||
|
||||
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.
|
||||
@@ -9,13 +13,16 @@
|
||||
*/
|
||||
|
||||
(function() {
|
||||
var jasmineRequire = window.jasmineRequire || require('./jasmine.js');
|
||||
|
||||
/**
|
||||
* ## 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);
|
||||
var jasmine = jasmineRequire.core(jasmineRequire),
|
||||
global = jasmine.getGlobal();
|
||||
global.jasmine = jasmine;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
@@ -37,7 +44,7 @@
|
||||
/**
|
||||
* Add all of the Jasmine global/public interface to the global scope, so a project can use the public interface directly. For example, calling `describe` in specs instead of `jasmine.getEnv().describe`.
|
||||
*/
|
||||
extend(window, jasmineInterface);
|
||||
extend(global, jasmineInterface);
|
||||
|
||||
/**
|
||||
* ## Runner Parameters
|
||||
@@ -49,18 +56,23 @@
|
||||
getWindowLocation: function() { return window.location; }
|
||||
});
|
||||
|
||||
var catchingExceptions = queryString.getParam("catch");
|
||||
env.catchExceptions(typeof catchingExceptions === "undefined" ? true : catchingExceptions);
|
||||
var filterSpecs = !!queryString.getParam("spec");
|
||||
|
||||
var throwingExpectationFailures = queryString.getParam("throwFailures");
|
||||
env.throwOnExpectationFailure(throwingExpectationFailures);
|
||||
var config = {
|
||||
failFast: queryString.getParam("failFast"),
|
||||
oneFailurePerSpec: queryString.getParam("oneFailurePerSpec"),
|
||||
hideDisabled: queryString.getParam("hideDisabled")
|
||||
};
|
||||
|
||||
var random = queryString.getParam("random");
|
||||
env.randomizeTests(random);
|
||||
|
||||
if (random !== undefined && random !== "") {
|
||||
config.random = random;
|
||||
}
|
||||
|
||||
var seed = queryString.getParam("seed");
|
||||
if (seed) {
|
||||
env.seed(seed);
|
||||
config.seed = seed;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -69,14 +81,13 @@
|
||||
*/
|
||||
var htmlReporter = new jasmine.HtmlReporter({
|
||||
env: env,
|
||||
onRaiseExceptionsClick: function() { queryString.navigateWithNewParam("catch", !env.catchingExceptions()); },
|
||||
onThrowExpectationsClick: function() { queryString.navigateWithNewParam("throwFailures", !env.throwingExpectationFailures()); },
|
||||
onRandomClick: function() { queryString.navigateWithNewParam("random", !env.randomTests()); },
|
||||
navigateWithNewParam: function(key, value) { return queryString.navigateWithNewParam(key, value); },
|
||||
addToExistingQueryString: function(key, value) { return queryString.fullStringWithNewParam(key, value); },
|
||||
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()
|
||||
timer: new jasmine.Timer(),
|
||||
filterSpecs: filterSpecs
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -92,10 +103,12 @@
|
||||
filterString: function() { return queryString.getParam("spec"); }
|
||||
});
|
||||
|
||||
env.specFilter = function(spec) {
|
||||
config.specFilter = function(spec) {
|
||||
return specFilter.matches(spec.getFullName());
|
||||
};
|
||||
|
||||
env.configure(config);
|
||||
|
||||
/**
|
||||
* Setting up timing functions to be able to be overridden. Certain browsers (Safari, IE 8, phantomjs) require this hack.
|
||||
*/
|
||||
|
||||
42
lib/jasmine-core/boot/boot0.js
Normal file
42
lib/jasmine-core/boot/boot0.js
Normal file
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
This file starts the process of "booting" Jasmine. It initializes Jasmine,
|
||||
makes its globals available, and creates the env. This file should be loaded
|
||||
after `jasmine.js` and `jasmine_html.js`, but before `boot1.js` or any project
|
||||
source files or spec files are loaded.
|
||||
*/
|
||||
(function() {
|
||||
var jasmineRequire = window.jasmineRequire || require('./jasmine.js');
|
||||
|
||||
/**
|
||||
* ## Require & Instantiate
|
||||
*
|
||||
* Require Jasmine's core files. Specifically, this requires and attaches all of Jasmine's code to the `jasmine` reference.
|
||||
*/
|
||||
var jasmine = jasmineRequire.core(jasmineRequire),
|
||||
global = jasmine.getGlobal();
|
||||
global.jasmine = jasmine;
|
||||
|
||||
/**
|
||||
* 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 global scope, so a project can use the public interface directly. For example, calling `describe` in specs instead of `jasmine.getEnv().describe`.
|
||||
*/
|
||||
for (var property in jasmineInterface) {
|
||||
global[property] = jasmineInterface[property];
|
||||
}
|
||||
}());
|
||||
111
lib/jasmine-core/boot/boot1.js
Normal file
111
lib/jasmine-core/boot/boot1.js
Normal file
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
This file finishes "booting" 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 `boot0.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 you only wish to configure the Jasmine env, you
|
||||
can load another file that calls `jasmine.getEnv().configure({...})`
|
||||
after `boot0.js` is loaded and before this file is loaded.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
var env = jasmine.getEnv();
|
||||
|
||||
/**
|
||||
* ## 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 filterSpecs = !!queryString.getParam("spec");
|
||||
|
||||
var config = {
|
||||
failFast: queryString.getParam("failFast"),
|
||||
oneFailurePerSpec: queryString.getParam("oneFailurePerSpec"),
|
||||
hideDisabled: queryString.getParam("hideDisabled")
|
||||
};
|
||||
|
||||
var random = queryString.getParam("random");
|
||||
|
||||
if (random !== undefined && random !== "") {
|
||||
config.random = random;
|
||||
}
|
||||
|
||||
var seed = queryString.getParam("seed");
|
||||
if (seed) {
|
||||
config.seed = seed;
|
||||
}
|
||||
|
||||
/**
|
||||
* ## 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,
|
||||
navigateWithNewParam: function(key, value) { return queryString.navigateWithNewParam(key, value); },
|
||||
addToExistingQueryString: function(key, value) { return queryString.fullStringWithNewParam(key, value); },
|
||||
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(),
|
||||
filterSpecs: filterSpecs
|
||||
});
|
||||
|
||||
/**
|
||||
* The `jsApiReporter` also receives spec results, and is used by any environment that needs to extract the results from JavaScript.
|
||||
*/
|
||||
env.addReporter(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"); }
|
||||
});
|
||||
|
||||
config.specFilter = function(spec) {
|
||||
return specFilter.matches(spec.getFullName());
|
||||
};
|
||||
|
||||
env.configure(config);
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
}());
|
||||
@@ -1,10 +1,7 @@
|
||||
module.exports = function(jasmineRequire) {
|
||||
var jasmine = jasmineRequire.core(jasmineRequire);
|
||||
|
||||
var consoleFns = require('../console/console.js');
|
||||
consoleFns.console(consoleFns, jasmine);
|
||||
|
||||
var env = jasmine.getEnv();
|
||||
var env = jasmine.getEnv({suppressLoadErrors: true});
|
||||
|
||||
var jasmineInterface = jasmineRequire.interface(jasmine, env);
|
||||
|
||||
|
||||
64
lib/jasmine-core/boot0.js
Normal file
64
lib/jasmine-core/boot0.js
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
Copyright (c) 2008-2021 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.
|
||||
*/
|
||||
/**
|
||||
This file starts the process of "booting" Jasmine. It initializes Jasmine,
|
||||
makes its globals available, and creates the env. This file should be loaded
|
||||
after `jasmine.js` and `jasmine_html.js`, but before `boot1.js` or any project
|
||||
source files or spec files are loaded.
|
||||
*/
|
||||
(function() {
|
||||
var jasmineRequire = window.jasmineRequire || require('./jasmine.js');
|
||||
|
||||
/**
|
||||
* ## Require & Instantiate
|
||||
*
|
||||
* Require Jasmine's core files. Specifically, this requires and attaches all of Jasmine's code to the `jasmine` reference.
|
||||
*/
|
||||
var jasmine = jasmineRequire.core(jasmineRequire),
|
||||
global = jasmine.getGlobal();
|
||||
global.jasmine = jasmine;
|
||||
|
||||
/**
|
||||
* 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 global scope, so a project can use the public interface directly. For example, calling `describe` in specs instead of `jasmine.getEnv().describe`.
|
||||
*/
|
||||
for (var property in jasmineInterface) {
|
||||
global[property] = jasmineInterface[property];
|
||||
}
|
||||
}());
|
||||
133
lib/jasmine-core/boot1.js
Normal file
133
lib/jasmine-core/boot1.js
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
Copyright (c) 2008-2021 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.
|
||||
*/
|
||||
/**
|
||||
This file finishes "booting" 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 `boot0.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 you only wish to configure the Jasmine env, you
|
||||
can load another file that calls `jasmine.getEnv().configure({...})`
|
||||
after `boot0.js` is loaded and before this file is loaded.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
var env = jasmine.getEnv();
|
||||
|
||||
/**
|
||||
* ## 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 filterSpecs = !!queryString.getParam("spec");
|
||||
|
||||
var config = {
|
||||
failFast: queryString.getParam("failFast"),
|
||||
oneFailurePerSpec: queryString.getParam("oneFailurePerSpec"),
|
||||
hideDisabled: queryString.getParam("hideDisabled")
|
||||
};
|
||||
|
||||
var random = queryString.getParam("random");
|
||||
|
||||
if (random !== undefined && random !== "") {
|
||||
config.random = random;
|
||||
}
|
||||
|
||||
var seed = queryString.getParam("seed");
|
||||
if (seed) {
|
||||
config.seed = seed;
|
||||
}
|
||||
|
||||
/**
|
||||
* ## 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,
|
||||
navigateWithNewParam: function(key, value) { return queryString.navigateWithNewParam(key, value); },
|
||||
addToExistingQueryString: function(key, value) { return queryString.fullStringWithNewParam(key, value); },
|
||||
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(),
|
||||
filterSpecs: filterSpecs
|
||||
});
|
||||
|
||||
/**
|
||||
* The `jsApiReporter` also receives spec results, and is used by any environment that needs to extract the results from JavaScript.
|
||||
*/
|
||||
env.addReporter(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"); }
|
||||
});
|
||||
|
||||
config.specFilter = function(spec) {
|
||||
return specFilter.matches(spec.getFullName());
|
||||
};
|
||||
|
||||
env.configure(config);
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
}());
|
||||
@@ -1,4 +1,33 @@
|
||||
import pkg_resources
|
||||
import os
|
||||
|
||||
if 'SUPPRESS_JASMINE_DEPRECATION' not in os.environ:
|
||||
print('DEPRECATION WARNING:\n' +
|
||||
'\n' +
|
||||
'The Jasmine packages for Python are deprecated. There will be no further\n' +
|
||||
'releases after the end of the Jasmine 3.x series. We recommend migrating to the\n' +
|
||||
'following options:\n' +
|
||||
'\n' +
|
||||
'* jasmine-browser-runner (<https://github.com/jasmine/jasmine-browser>,\n' +
|
||||
' `npm install jasmine-browser-runner`) to run specs in browsers, including\n' +
|
||||
' headless Chrome and Saucelabs. This is the most direct replacement for the\n' +
|
||||
' jasmine server` and `jasmine ci` commands provided by the `jasmine` Python\n' +
|
||||
' package.\n' +
|
||||
'* The jasmine npm package (<https://github.com/jasmine/jasmine-npm>,\n' +
|
||||
' `npm install jasmine`) to run specs under Node.js.\n' +
|
||||
'* The standalone distribution from the latest Jasmine release\n' +
|
||||
' <https://github.com/jasmine/jasmine/releases> to run specs in browsers with\n' +
|
||||
' no additional tools.\n' +
|
||||
'* The jasmine-core npm package (`npm install jasmine-core`) if all you need is\n' +
|
||||
' the Jasmine assets. This is the direct equivalent of the jasmine-core Python\n' +
|
||||
' package.\n' +
|
||||
'\n' +
|
||||
'Except for the standalone distribution, all of the above are distributed through\n' +
|
||||
'npm.\n' +
|
||||
'\n' +
|
||||
'To prevent this message from appearing, set the SUPPRESS_JASMINE_DEPRECATION\n' +
|
||||
'environment variable.\n')
|
||||
|
||||
|
||||
try:
|
||||
from collections import OrderedDict
|
||||
@@ -29,6 +58,11 @@ class Core(object):
|
||||
js_files.remove('boot.js')
|
||||
js_files.append('boot.js')
|
||||
|
||||
# Remove the new boot files. jasmine-py will continue to use the legacy
|
||||
# boot.js.
|
||||
js_files.remove('boot0.js')
|
||||
js_files.remove('boot1.js')
|
||||
|
||||
return cls._uniq(js_files)
|
||||
|
||||
@classmethod
|
||||
@@ -57,4 +91,4 @@ class Core(object):
|
||||
|
||||
seen[marker] = 1
|
||||
result.append(item)
|
||||
return result
|
||||
return result
|
||||
|
||||
@@ -19,4 +19,4 @@ Player.prototype.resume = function() {
|
||||
|
||||
Player.prototype.makeFavorite = function() {
|
||||
this.currentlyPlayingSong.persistFavoriteStatus(true);
|
||||
};
|
||||
};
|
||||
|
||||
@@ -4,4 +4,4 @@ function Song() {
|
||||
Song.prototype.persistFavoriteStatus = function(value) {
|
||||
// something complicated
|
||||
throw new Error("not yet implemented");
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (c) 2008-2016 Pivotal Labs
|
||||
Copyright (c) 2008-2021 Pivotal Labs
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
@@ -20,6 +20,8 @@ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
var jasmineRequire = window.jasmineRequire || require('./jasmine.js');
|
||||
|
||||
jasmineRequire.html = function(j$) {
|
||||
j$.ResultsNode = jasmineRequire.ResultsNode();
|
||||
j$.HtmlReporter = jasmineRequire.HtmlReporter(j$);
|
||||
@@ -28,41 +30,84 @@ jasmineRequire.html = function(j$) {
|
||||
};
|
||||
|
||||
jasmineRequire.HtmlReporter = function(j$) {
|
||||
function ResultsStateBuilder() {
|
||||
this.topResults = new j$.ResultsNode({}, '', null);
|
||||
this.currentParent = this.topResults;
|
||||
this.specsExecuted = 0;
|
||||
this.failureCount = 0;
|
||||
this.pendingSpecCount = 0;
|
||||
}
|
||||
|
||||
var noopTimer = {
|
||||
start: function() {},
|
||||
elapsed: function() { return 0; }
|
||||
ResultsStateBuilder.prototype.suiteStarted = function(result) {
|
||||
this.currentParent.addChild(result, 'suite');
|
||||
this.currentParent = this.currentParent.last();
|
||||
};
|
||||
|
||||
ResultsStateBuilder.prototype.suiteDone = function(result) {
|
||||
this.currentParent.updateResult(result);
|
||||
if (this.currentParent !== this.topResults) {
|
||||
this.currentParent = this.currentParent.parent;
|
||||
}
|
||||
|
||||
if (result.status === 'failed') {
|
||||
this.failureCount++;
|
||||
}
|
||||
};
|
||||
|
||||
ResultsStateBuilder.prototype.specStarted = function(result) {};
|
||||
|
||||
ResultsStateBuilder.prototype.specDone = function(result) {
|
||||
this.currentParent.addChild(result, 'spec');
|
||||
|
||||
if (result.status !== 'excluded') {
|
||||
this.specsExecuted++;
|
||||
}
|
||||
|
||||
if (result.status === 'failed') {
|
||||
this.failureCount++;
|
||||
}
|
||||
|
||||
if (result.status == 'pending') {
|
||||
this.pendingSpecCount++;
|
||||
}
|
||||
};
|
||||
|
||||
function HtmlReporter(options) {
|
||||
var env = options.env || {},
|
||||
var config = function() {
|
||||
return (options.env && options.env.configuration()) || {};
|
||||
},
|
||||
getContainer = options.getContainer,
|
||||
createElement = options.createElement,
|
||||
createTextNode = options.createTextNode,
|
||||
onRaiseExceptionsClick = options.onRaiseExceptionsClick || function() {},
|
||||
onThrowExpectationsClick = options.onThrowExpectationsClick || function() {},
|
||||
onRandomClick = options.onRandomClick || function() {},
|
||||
addToExistingQueryString = options.addToExistingQueryString || defaultQueryString,
|
||||
timer = options.timer || noopTimer,
|
||||
results = [],
|
||||
specsExecuted = 0,
|
||||
failureCount = 0,
|
||||
pendingSpecCount = 0,
|
||||
navigateWithNewParam = options.navigateWithNewParam || function() {},
|
||||
addToExistingQueryString =
|
||||
options.addToExistingQueryString || defaultQueryString,
|
||||
filterSpecs = options.filterSpecs,
|
||||
htmlReporterMain,
|
||||
symbols,
|
||||
failedSuites = [];
|
||||
deprecationWarnings = [];
|
||||
|
||||
this.initialize = function() {
|
||||
clearPrior();
|
||||
htmlReporterMain = createDom('div', {className: 'jasmine_html-reporter'},
|
||||
createDom('div', {className: 'jasmine-banner'},
|
||||
createDom('a', {className: 'jasmine-title', href: 'http://jasmine.github.io/', target: '_blank'}),
|
||||
createDom('span', {className: 'jasmine-version'}, j$.version)
|
||||
htmlReporterMain = createDom(
|
||||
'div',
|
||||
{ className: 'jasmine_html-reporter' },
|
||||
createDom(
|
||||
'div',
|
||||
{ className: 'jasmine-banner' },
|
||||
createDom('a', {
|
||||
className: 'jasmine-title',
|
||||
href: 'http://jasmine.github.io/',
|
||||
target: '_blank'
|
||||
}),
|
||||
createDom('span', { className: 'jasmine-version' }, j$.version)
|
||||
),
|
||||
createDom('ul', {className: 'jasmine-symbol-summary'}),
|
||||
createDom('div', {className: 'jasmine-alert'}),
|
||||
createDom('div', {className: 'jasmine-results'},
|
||||
createDom('div', {className: 'jasmine-failures'})
|
||||
createDom('ul', { className: 'jasmine-symbol-summary' }),
|
||||
createDom('div', { className: 'jasmine-alert' }),
|
||||
createDom(
|
||||
'div',
|
||||
{ className: 'jasmine-results' },
|
||||
createDom('div', { className: 'jasmine-failures' })
|
||||
)
|
||||
);
|
||||
getContainer().appendChild(htmlReporterMain);
|
||||
@@ -71,247 +116,263 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
var totalSpecsDefined;
|
||||
this.jasmineStarted = function(options) {
|
||||
totalSpecsDefined = options.totalSpecsDefined || 0;
|
||||
timer.start();
|
||||
};
|
||||
|
||||
var summary = createDom('div', {className: 'jasmine-summary'});
|
||||
var summary = createDom('div', { className: 'jasmine-summary' });
|
||||
|
||||
var topResults = new j$.ResultsNode({}, '', null),
|
||||
currentParent = topResults;
|
||||
var stateBuilder = new ResultsStateBuilder();
|
||||
|
||||
this.suiteStarted = function(result) {
|
||||
currentParent.addChild(result, 'suite');
|
||||
currentParent = currentParent.last();
|
||||
stateBuilder.suiteStarted(result);
|
||||
};
|
||||
|
||||
this.suiteDone = function(result) {
|
||||
if (result.status == 'failed') {
|
||||
failedSuites.push(result);
|
||||
}
|
||||
stateBuilder.suiteDone(result);
|
||||
|
||||
if (currentParent == topResults) {
|
||||
return;
|
||||
if (result.status === 'failed') {
|
||||
failures.push(failureDom(result));
|
||||
}
|
||||
|
||||
currentParent = currentParent.parent;
|
||||
addDeprecationWarnings(result, 'suite');
|
||||
};
|
||||
|
||||
this.specStarted = function(result) {
|
||||
currentParent.addChild(result, 'spec');
|
||||
stateBuilder.specStarted(result);
|
||||
};
|
||||
|
||||
var failures = [];
|
||||
this.specDone = function(result) {
|
||||
if(noExpectations(result) && typeof console !== 'undefined' && typeof console.error !== 'undefined') {
|
||||
console.error('Spec \'' + result.fullName + '\' has no expectations.');
|
||||
stateBuilder.specDone(result);
|
||||
|
||||
if (noExpectations(result)) {
|
||||
var noSpecMsg = "Spec '" + result.fullName + "' has no expectations.";
|
||||
if (result.status === 'failed') {
|
||||
console.error(noSpecMsg);
|
||||
} else {
|
||||
console.warn(noSpecMsg);
|
||||
}
|
||||
}
|
||||
|
||||
if (result.status != 'disabled') {
|
||||
specsExecuted++;
|
||||
}
|
||||
|
||||
if (!symbols){
|
||||
if (!symbols) {
|
||||
symbols = find('.jasmine-symbol-summary');
|
||||
}
|
||||
|
||||
symbols.appendChild(createDom('li', {
|
||||
className: noExpectations(result) ? 'jasmine-empty' : 'jasmine-' + result.status,
|
||||
symbols.appendChild(
|
||||
createDom('li', {
|
||||
className: this.displaySpecInCorrectFormat(result),
|
||||
id: 'spec_' + result.id,
|
||||
title: result.fullName
|
||||
}
|
||||
));
|
||||
})
|
||||
);
|
||||
|
||||
if (result.status == 'failed') {
|
||||
failureCount++;
|
||||
|
||||
var failure =
|
||||
createDom('div', {className: 'jasmine-spec-detail jasmine-failed'},
|
||||
createDom('div', {className: 'jasmine-description'},
|
||||
createDom('a', {title: result.fullName, href: specHref(result)}, result.fullName)
|
||||
),
|
||||
createDom('div', {className: 'jasmine-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: 'jasmine-result-message'}, expectation.message));
|
||||
messages.appendChild(createDom('div', {className: 'jasmine-stack-trace'}, expectation.stack));
|
||||
}
|
||||
|
||||
failures.push(failure);
|
||||
if (result.status === 'failed') {
|
||||
failures.push(failureDom(result));
|
||||
}
|
||||
|
||||
if (result.status == 'pending') {
|
||||
pendingSpecCount++;
|
||||
addDeprecationWarnings(result, 'spec');
|
||||
};
|
||||
|
||||
this.displaySpecInCorrectFormat = function(result) {
|
||||
return noExpectations(result) && result.status === 'passed'
|
||||
? 'jasmine-empty'
|
||||
: this.resultStatus(result.status);
|
||||
};
|
||||
|
||||
this.resultStatus = function(status) {
|
||||
if (status === 'excluded') {
|
||||
return config().hideDisabled
|
||||
? 'jasmine-excluded-no-display'
|
||||
: 'jasmine-excluded';
|
||||
}
|
||||
return 'jasmine-' + status;
|
||||
};
|
||||
|
||||
this.jasmineDone = function(doneResult) {
|
||||
var banner = find('.jasmine-banner');
|
||||
var alert = find('.jasmine-alert');
|
||||
var order = doneResult && doneResult.order;
|
||||
alert.appendChild(createDom('span', {className: 'jasmine-duration'}, 'finished in ' + timer.elapsed() / 1000 + 's'));
|
||||
var i;
|
||||
alert.appendChild(
|
||||
createDom(
|
||||
'span',
|
||||
{ className: 'jasmine-duration' },
|
||||
'finished in ' + doneResult.totalTime / 1000 + 's'
|
||||
)
|
||||
);
|
||||
|
||||
banner.appendChild(
|
||||
createDom('div', { className: 'jasmine-run-options' },
|
||||
createDom('span', { className: 'jasmine-trigger' }, 'Options'),
|
||||
createDom('div', { className: 'jasmine-payload' },
|
||||
createDom('div', { className: 'jasmine-exceptions' },
|
||||
createDom('input', {
|
||||
className: 'jasmine-raise',
|
||||
id: 'jasmine-raise-exceptions',
|
||||
type: 'checkbox'
|
||||
}),
|
||||
createDom('label', { className: 'jasmine-label', 'for': 'jasmine-raise-exceptions' }, 'raise exceptions')),
|
||||
createDom('div', { className: 'jasmine-throw-failures' },
|
||||
createDom('input', {
|
||||
className: 'jasmine-throw',
|
||||
id: 'jasmine-throw-failures',
|
||||
type: 'checkbox'
|
||||
}),
|
||||
createDom('label', { className: 'jasmine-label', 'for': 'jasmine-throw-failures' }, 'stop spec on expectation failure')),
|
||||
createDom('div', { className: 'jasmine-random-order' },
|
||||
createDom('input', {
|
||||
className: 'jasmine-random',
|
||||
id: 'jasmine-random-order',
|
||||
type: 'checkbox'
|
||||
}),
|
||||
createDom('label', { className: 'jasmine-label', 'for': 'jasmine-random-order' }, 'run tests in random order'))
|
||||
)
|
||||
));
|
||||
banner.appendChild(optionsMenu(config()));
|
||||
|
||||
var raiseCheckbox = find('#jasmine-raise-exceptions');
|
||||
|
||||
raiseCheckbox.checked = !env.catchingExceptions();
|
||||
raiseCheckbox.onclick = onRaiseExceptionsClick;
|
||||
|
||||
var throwCheckbox = find('#jasmine-throw-failures');
|
||||
throwCheckbox.checked = env.throwingExpectationFailures();
|
||||
throwCheckbox.onclick = onThrowExpectationsClick;
|
||||
|
||||
var randomCheckbox = find('#jasmine-random-order');
|
||||
randomCheckbox.checked = env.randomTests();
|
||||
randomCheckbox.onclick = onRandomClick;
|
||||
|
||||
var optionsMenu = find('.jasmine-run-options'),
|
||||
optionsTrigger = optionsMenu.querySelector('.jasmine-trigger'),
|
||||
optionsPayload = optionsMenu.querySelector('.jasmine-payload'),
|
||||
isOpen = /\bjasmine-open\b/;
|
||||
|
||||
optionsTrigger.onclick = function() {
|
||||
if (isOpen.test(optionsPayload.className)) {
|
||||
optionsPayload.className = optionsPayload.className.replace(isOpen, '');
|
||||
} else {
|
||||
optionsPayload.className += ' jasmine-open';
|
||||
}
|
||||
};
|
||||
|
||||
if (specsExecuted < totalSpecsDefined) {
|
||||
var skippedMessage = 'Ran ' + specsExecuted + ' of ' + totalSpecsDefined + ' specs - run all';
|
||||
var skippedLink = order && order.random ? '?random=true' : '?';
|
||||
if (stateBuilder.specsExecuted < totalSpecsDefined) {
|
||||
var skippedMessage =
|
||||
'Ran ' +
|
||||
stateBuilder.specsExecuted +
|
||||
' of ' +
|
||||
totalSpecsDefined +
|
||||
' specs - run all';
|
||||
// include window.location.pathname to fix issue with karma-jasmine-html-reporter in angular: see https://github.com/jasmine/jasmine/issues/1906
|
||||
var skippedLink =
|
||||
(window.location.pathname || '') +
|
||||
addToExistingQueryString('spec', '');
|
||||
alert.appendChild(
|
||||
createDom('span', {className: 'jasmine-bar jasmine-skipped'},
|
||||
createDom('a', {href: skippedLink, title: 'Run all specs'}, skippedMessage)
|
||||
createDom(
|
||||
'span',
|
||||
{ className: 'jasmine-bar jasmine-skipped' },
|
||||
createDom(
|
||||
'a',
|
||||
{ href: skippedLink, title: 'Run all specs' },
|
||||
skippedMessage
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
var statusBarMessage = '';
|
||||
var statusBarClassName = 'jasmine-bar ';
|
||||
var statusBarClassName = 'jasmine-overall-result jasmine-bar ';
|
||||
var globalFailures = (doneResult && doneResult.failedExpectations) || [];
|
||||
var failed = stateBuilder.failureCount + globalFailures.length > 0;
|
||||
|
||||
if (totalSpecsDefined > 0) {
|
||||
statusBarMessage += pluralize('spec', specsExecuted) + ', ' + pluralize('failure', failureCount);
|
||||
if (pendingSpecCount) { statusBarMessage += ', ' + pluralize('pending spec', pendingSpecCount); }
|
||||
statusBarClassName += (failureCount > 0) ? 'jasmine-failed' : 'jasmine-passed';
|
||||
if (totalSpecsDefined > 0 || failed) {
|
||||
statusBarMessage +=
|
||||
pluralize('spec', stateBuilder.specsExecuted) +
|
||||
', ' +
|
||||
pluralize('failure', stateBuilder.failureCount);
|
||||
if (stateBuilder.pendingSpecCount) {
|
||||
statusBarMessage +=
|
||||
', ' + pluralize('pending spec', stateBuilder.pendingSpecCount);
|
||||
}
|
||||
}
|
||||
|
||||
if (doneResult.overallStatus === 'passed') {
|
||||
statusBarClassName += ' jasmine-passed ';
|
||||
} else if (doneResult.overallStatus === 'incomplete') {
|
||||
statusBarClassName += ' jasmine-incomplete ';
|
||||
statusBarMessage =
|
||||
'Incomplete: ' +
|
||||
doneResult.incompleteReason +
|
||||
', ' +
|
||||
statusBarMessage;
|
||||
} else {
|
||||
statusBarClassName += 'jasmine-skipped';
|
||||
statusBarMessage += 'No specs found';
|
||||
statusBarClassName += ' jasmine-failed ';
|
||||
}
|
||||
|
||||
var seedBar;
|
||||
if (order && order.random) {
|
||||
seedBar = createDom('span', {className: 'jasmine-seed-bar'},
|
||||
seedBar = createDom(
|
||||
'span',
|
||||
{ className: 'jasmine-seed-bar' },
|
||||
', randomized with seed ',
|
||||
createDom('a', {title: 'randomized with seed ' + order.seed, href: seedHref(order.seed)}, order.seed)
|
||||
createDom(
|
||||
'a',
|
||||
{
|
||||
title: 'randomized with seed ' + order.seed,
|
||||
href: seedHref(order.seed)
|
||||
},
|
||||
order.seed
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
alert.appendChild(createDom('span', {className: statusBarClassName}, statusBarMessage, seedBar));
|
||||
alert.appendChild(
|
||||
createDom(
|
||||
'span',
|
||||
{ className: statusBarClassName },
|
||||
statusBarMessage,
|
||||
seedBar
|
||||
)
|
||||
);
|
||||
|
||||
var errorBarClassName = 'jasmine-bar jasmine-errored';
|
||||
var errorBarMessagePrefix = 'AfterAll ';
|
||||
var afterAllMessagePrefix = 'AfterAll ';
|
||||
|
||||
for(var i = 0; i < failedSuites.length; i++) {
|
||||
var failedSuite = failedSuites[i];
|
||||
for(var j = 0; j < failedSuite.failedExpectations.length; j++) {
|
||||
alert.appendChild(createDom('span', {className: errorBarClassName}, errorBarMessagePrefix + failedSuite.failedExpectations[j].message));
|
||||
for (i = 0; i < globalFailures.length; i++) {
|
||||
alert.appendChild(
|
||||
createDom(
|
||||
'span',
|
||||
{ className: errorBarClassName },
|
||||
globalFailureMessage(globalFailures[i])
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function globalFailureMessage(failure) {
|
||||
if (failure.globalErrorType === 'load') {
|
||||
var prefix = 'Error during loading: ' + failure.message;
|
||||
|
||||
if (failure.filename) {
|
||||
return (
|
||||
prefix + ' in ' + failure.filename + ' line ' + failure.lineno
|
||||
);
|
||||
} else {
|
||||
return prefix;
|
||||
}
|
||||
} else {
|
||||
return afterAllMessagePrefix + failure.message;
|
||||
}
|
||||
}
|
||||
|
||||
var globalFailures = (doneResult && doneResult.failedExpectations) || [];
|
||||
for(i = 0; i < globalFailures.length; i++) {
|
||||
var failure = globalFailures[i];
|
||||
alert.appendChild(createDom('span', {className: errorBarClassName}, errorBarMessagePrefix + failure.message));
|
||||
addDeprecationWarnings(doneResult);
|
||||
|
||||
for (i = 0; i < deprecationWarnings.length; i++) {
|
||||
var context;
|
||||
|
||||
switch (deprecationWarnings[i].runnableType) {
|
||||
case 'spec':
|
||||
context = '(in spec: ' + deprecationWarnings[i].runnableName + ')';
|
||||
break;
|
||||
case 'suite':
|
||||
context = '(in suite: ' + deprecationWarnings[i].runnableName + ')';
|
||||
break;
|
||||
default:
|
||||
context = '';
|
||||
}
|
||||
|
||||
alert.appendChild(
|
||||
createDom(
|
||||
'span',
|
||||
{ className: 'jasmine-bar jasmine-warning' },
|
||||
'DEPRECATION: ' + deprecationWarnings[i].message,
|
||||
createDom('br'),
|
||||
context
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
var results = find('.jasmine-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: 'jasmine-suite', id: 'suite-' + resultNode.result.id},
|
||||
createDom('li', {className: 'jasmine-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') != 'jasmine-specs') {
|
||||
specListNode = createDom('ul', {className: 'jasmine-specs'});
|
||||
domParent.appendChild(specListNode);
|
||||
}
|
||||
var specDescription = resultNode.result.description;
|
||||
if(noExpectations(resultNode.result)) {
|
||||
specDescription = 'SPEC HAS NO EXPECTATIONS ' + specDescription;
|
||||
}
|
||||
if(resultNode.result.status === 'pending' && resultNode.result.pendingReason !== '') {
|
||||
specDescription = specDescription + ' PENDING WITH MESSAGE: ' + resultNode.result.pendingReason;
|
||||
}
|
||||
specListNode.appendChild(
|
||||
createDom('li', {
|
||||
className: 'jasmine-' + resultNode.result.status,
|
||||
id: 'spec-' + resultNode.result.id
|
||||
},
|
||||
createDom('a', {href: specHref(resultNode.result)}, specDescription)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
summaryList(stateBuilder.topResults, summary);
|
||||
|
||||
if (failures.length) {
|
||||
alert.appendChild(
|
||||
createDom('span', {className: 'jasmine-menu jasmine-bar jasmine-spec-list'},
|
||||
createDom(
|
||||
'span',
|
||||
{ className: 'jasmine-menu jasmine-bar jasmine-spec-list' },
|
||||
createDom('span', {}, 'Spec List | '),
|
||||
createDom('a', {className: 'jasmine-failures-menu', href: '#'}, 'Failures')));
|
||||
createDom(
|
||||
'a',
|
||||
{ className: 'jasmine-failures-menu', href: '#' },
|
||||
'Failures'
|
||||
)
|
||||
)
|
||||
);
|
||||
alert.appendChild(
|
||||
createDom('span', {className: 'jasmine-menu jasmine-bar jasmine-failure-list'},
|
||||
createDom('a', {className: 'jasmine-spec-list-menu', href: '#'}, 'Spec List'),
|
||||
createDom('span', {}, ' | Failures ')));
|
||||
createDom(
|
||||
'span',
|
||||
{ className: 'jasmine-menu jasmine-bar jasmine-failure-list' },
|
||||
createDom(
|
||||
'a',
|
||||
{ className: 'jasmine-spec-list-menu', href: '#' },
|
||||
'Spec List'
|
||||
),
|
||||
createDom('span', {}, ' | Failures ')
|
||||
)
|
||||
);
|
||||
|
||||
find('.jasmine-failures-menu').onclick = function() {
|
||||
setMenuModeTo('jasmine-failure-list');
|
||||
return false;
|
||||
};
|
||||
find('.jasmine-spec-list-menu').onclick = function() {
|
||||
setMenuModeTo('jasmine-spec-list');
|
||||
return false;
|
||||
};
|
||||
|
||||
setMenuModeTo('jasmine-failure-list');
|
||||
@@ -325,6 +386,283 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
|
||||
return this;
|
||||
|
||||
function failureDom(result) {
|
||||
var failure = createDom(
|
||||
'div',
|
||||
{ className: 'jasmine-spec-detail jasmine-failed' },
|
||||
failureDescription(result, stateBuilder.currentParent),
|
||||
createDom('div', { className: 'jasmine-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: 'jasmine-result-message' },
|
||||
expectation.message
|
||||
)
|
||||
);
|
||||
messages.appendChild(
|
||||
createDom(
|
||||
'div',
|
||||
{ className: 'jasmine-stack-trace' },
|
||||
expectation.stack
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (result.failedExpectations.length === 0) {
|
||||
messages.appendChild(
|
||||
createDom(
|
||||
'div',
|
||||
{ className: 'jasmine-result-message' },
|
||||
'Spec has no expectations'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return failure;
|
||||
}
|
||||
|
||||
function summaryList(resultsTree, domParent) {
|
||||
var specListNode;
|
||||
for (var i = 0; i < resultsTree.children.length; i++) {
|
||||
var resultNode = resultsTree.children[i];
|
||||
if (filterSpecs && !hasActiveSpec(resultNode)) {
|
||||
continue;
|
||||
}
|
||||
if (resultNode.type === 'suite') {
|
||||
var suiteListNode = createDom(
|
||||
'ul',
|
||||
{ className: 'jasmine-suite', id: 'suite-' + resultNode.result.id },
|
||||
createDom(
|
||||
'li',
|
||||
{
|
||||
className:
|
||||
'jasmine-suite-detail jasmine-' + resultNode.result.status
|
||||
},
|
||||
createDom(
|
||||
'a',
|
||||
{ href: specHref(resultNode.result) },
|
||||
resultNode.result.description
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
summaryList(resultNode, suiteListNode);
|
||||
domParent.appendChild(suiteListNode);
|
||||
}
|
||||
if (resultNode.type === 'spec') {
|
||||
if (domParent.getAttribute('class') !== 'jasmine-specs') {
|
||||
specListNode = createDom('ul', { className: 'jasmine-specs' });
|
||||
domParent.appendChild(specListNode);
|
||||
}
|
||||
var specDescription = resultNode.result.description;
|
||||
if (noExpectations(resultNode.result)) {
|
||||
specDescription = 'SPEC HAS NO EXPECTATIONS ' + specDescription;
|
||||
}
|
||||
if (
|
||||
resultNode.result.status === 'pending' &&
|
||||
resultNode.result.pendingReason !== ''
|
||||
) {
|
||||
specDescription =
|
||||
specDescription +
|
||||
' PENDING WITH MESSAGE: ' +
|
||||
resultNode.result.pendingReason;
|
||||
}
|
||||
specListNode.appendChild(
|
||||
createDom(
|
||||
'li',
|
||||
{
|
||||
className: 'jasmine-' + resultNode.result.status,
|
||||
id: 'spec-' + resultNode.result.id
|
||||
},
|
||||
createDom(
|
||||
'a',
|
||||
{ href: specHref(resultNode.result) },
|
||||
specDescription
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function optionsMenu(config) {
|
||||
var optionsMenuDom = createDom(
|
||||
'div',
|
||||
{ className: 'jasmine-run-options' },
|
||||
createDom('span', { className: 'jasmine-trigger' }, 'Options'),
|
||||
createDom(
|
||||
'div',
|
||||
{ className: 'jasmine-payload' },
|
||||
createDom(
|
||||
'div',
|
||||
{ className: 'jasmine-stop-on-failure' },
|
||||
createDom('input', {
|
||||
className: 'jasmine-fail-fast',
|
||||
id: 'jasmine-fail-fast',
|
||||
type: 'checkbox'
|
||||
}),
|
||||
createDom(
|
||||
'label',
|
||||
{ className: 'jasmine-label', for: 'jasmine-fail-fast' },
|
||||
'stop execution on spec failure'
|
||||
)
|
||||
),
|
||||
createDom(
|
||||
'div',
|
||||
{ className: 'jasmine-throw-failures' },
|
||||
createDom('input', {
|
||||
className: 'jasmine-throw',
|
||||
id: 'jasmine-throw-failures',
|
||||
type: 'checkbox'
|
||||
}),
|
||||
createDom(
|
||||
'label',
|
||||
{ className: 'jasmine-label', for: 'jasmine-throw-failures' },
|
||||
'stop spec on expectation failure'
|
||||
)
|
||||
),
|
||||
createDom(
|
||||
'div',
|
||||
{ className: 'jasmine-random-order' },
|
||||
createDom('input', {
|
||||
className: 'jasmine-random',
|
||||
id: 'jasmine-random-order',
|
||||
type: 'checkbox'
|
||||
}),
|
||||
createDom(
|
||||
'label',
|
||||
{ className: 'jasmine-label', for: 'jasmine-random-order' },
|
||||
'run tests in random order'
|
||||
)
|
||||
),
|
||||
createDom(
|
||||
'div',
|
||||
{ className: 'jasmine-hide-disabled' },
|
||||
createDom('input', {
|
||||
className: 'jasmine-disabled',
|
||||
id: 'jasmine-hide-disabled',
|
||||
type: 'checkbox'
|
||||
}),
|
||||
createDom(
|
||||
'label',
|
||||
{ className: 'jasmine-label', for: 'jasmine-hide-disabled' },
|
||||
'hide disabled tests'
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
var failFastCheckbox = optionsMenuDom.querySelector('#jasmine-fail-fast');
|
||||
failFastCheckbox.checked = config.stopOnSpecFailure;
|
||||
failFastCheckbox.onclick = function() {
|
||||
navigateWithNewParam('failFast', !config.stopOnSpecFailure);
|
||||
};
|
||||
|
||||
var throwCheckbox = optionsMenuDom.querySelector(
|
||||
'#jasmine-throw-failures'
|
||||
);
|
||||
throwCheckbox.checked = config.stopSpecOnExpectationFailure;
|
||||
throwCheckbox.onclick = function() {
|
||||
navigateWithNewParam(
|
||||
'oneFailurePerSpec',
|
||||
!config.stopSpecOnExpectationFailure
|
||||
);
|
||||
};
|
||||
|
||||
var randomCheckbox = optionsMenuDom.querySelector(
|
||||
'#jasmine-random-order'
|
||||
);
|
||||
randomCheckbox.checked = config.random;
|
||||
randomCheckbox.onclick = function() {
|
||||
navigateWithNewParam('random', !config.random);
|
||||
};
|
||||
|
||||
var hideDisabled = optionsMenuDom.querySelector('#jasmine-hide-disabled');
|
||||
hideDisabled.checked = config.hideDisabled;
|
||||
hideDisabled.onclick = function() {
|
||||
navigateWithNewParam('hideDisabled', !config.hideDisabled);
|
||||
};
|
||||
|
||||
var optionsTrigger = optionsMenuDom.querySelector('.jasmine-trigger'),
|
||||
optionsPayload = optionsMenuDom.querySelector('.jasmine-payload'),
|
||||
isOpen = /\bjasmine-open\b/;
|
||||
|
||||
optionsTrigger.onclick = function() {
|
||||
if (isOpen.test(optionsPayload.className)) {
|
||||
optionsPayload.className = optionsPayload.className.replace(
|
||||
isOpen,
|
||||
''
|
||||
);
|
||||
} else {
|
||||
optionsPayload.className += ' jasmine-open';
|
||||
}
|
||||
};
|
||||
|
||||
return optionsMenuDom;
|
||||
}
|
||||
|
||||
function failureDescription(result, suite) {
|
||||
var wrapper = createDom(
|
||||
'div',
|
||||
{ className: 'jasmine-description' },
|
||||
createDom(
|
||||
'a',
|
||||
{ title: result.description, href: specHref(result) },
|
||||
result.description
|
||||
)
|
||||
);
|
||||
var suiteLink;
|
||||
|
||||
while (suite && suite.parent) {
|
||||
wrapper.insertBefore(createTextNode(' > '), wrapper.firstChild);
|
||||
suiteLink = createDom(
|
||||
'a',
|
||||
{ href: suiteHref(suite) },
|
||||
suite.result.description
|
||||
);
|
||||
wrapper.insertBefore(suiteLink, wrapper.firstChild);
|
||||
|
||||
suite = suite.parent;
|
||||
}
|
||||
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
function suiteHref(suite) {
|
||||
var els = [];
|
||||
|
||||
while (suite && suite.parent) {
|
||||
els.unshift(suite.result.description);
|
||||
suite = suite.parent;
|
||||
}
|
||||
|
||||
// include window.location.pathname to fix issue with karma-jasmine-html-reporter in angular: see https://github.com/jasmine/jasmine/issues/1906
|
||||
return (
|
||||
(window.location.pathname || '') +
|
||||
addToExistingQueryString('spec', els.join(' '))
|
||||
);
|
||||
}
|
||||
|
||||
function addDeprecationWarnings(result, runnableType) {
|
||||
if (result && result.deprecationWarnings) {
|
||||
for (var i = 0; i < result.deprecationWarnings.length; i++) {
|
||||
var warning = result.deprecationWarnings[i].message;
|
||||
if (!j$.util.arrayContains(warning)) {
|
||||
deprecationWarnings.push({
|
||||
message: warning,
|
||||
runnableName: result.fullName,
|
||||
runnableType: runnableType
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function find(selector) {
|
||||
return getContainer().querySelector('.jasmine_html-reporter ' + selector);
|
||||
}
|
||||
@@ -333,7 +671,7 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
// return the reporter
|
||||
var oldReporter = find('');
|
||||
|
||||
if(oldReporter) {
|
||||
if (oldReporter) {
|
||||
getContainer().removeChild(oldReporter);
|
||||
}
|
||||
}
|
||||
@@ -365,17 +703,25 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
}
|
||||
|
||||
function pluralize(singular, count) {
|
||||
var word = (count == 1 ? singular : singular + 's');
|
||||
var word = count == 1 ? singular : singular + 's';
|
||||
|
||||
return '' + count + ' ' + word;
|
||||
}
|
||||
|
||||
function specHref(result) {
|
||||
return addToExistingQueryString('spec', result.fullName);
|
||||
// include window.location.pathname to fix issue with karma-jasmine-html-reporter in angular: see https://github.com/jasmine/jasmine/issues/1906
|
||||
return (
|
||||
(window.location.pathname || '') +
|
||||
addToExistingQueryString('spec', result.fullName)
|
||||
);
|
||||
}
|
||||
|
||||
function seedHref(seed) {
|
||||
return addToExistingQueryString('seed', seed);
|
||||
// include window.location.pathname to fix issue with karma-jasmine-html-reporter in angular: see https://github.com/jasmine/jasmine/issues/1906
|
||||
return (
|
||||
(window.location.pathname || '') +
|
||||
addToExistingQueryString('seed', seed)
|
||||
);
|
||||
}
|
||||
|
||||
function defaultQueryString(key, value) {
|
||||
@@ -387,8 +733,27 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
}
|
||||
|
||||
function noExpectations(result) {
|
||||
return (result.failedExpectations.length + result.passedExpectations.length) === 0 &&
|
||||
result.status === 'passed';
|
||||
var allExpectations =
|
||||
result.failedExpectations.length + result.passedExpectations.length;
|
||||
|
||||
return (
|
||||
allExpectations === 0 &&
|
||||
(result.status === 'passed' || result.status === 'failed')
|
||||
);
|
||||
}
|
||||
|
||||
function hasActiveSpec(resultNode) {
|
||||
if (resultNode.type == 'spec' && resultNode.result.status != 'excluded') {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (resultNode.type == 'suite') {
|
||||
for (var i = 0, j = resultNode.children.length; i < j; i++) {
|
||||
if (hasActiveSpec(resultNode.children[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -397,7 +762,10 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
|
||||
jasmineRequire.HtmlSpecFilter = function() {
|
||||
function HtmlSpecFilter(options) {
|
||||
var filterString = options && options.filterString() && options.filterString().replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
|
||||
var filterString =
|
||||
options &&
|
||||
options.filterString() &&
|
||||
options.filterString().replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
|
||||
var filterPattern = new RegExp(filterString);
|
||||
|
||||
this.matches = function(specName) {
|
||||
@@ -423,6 +791,10 @@ jasmineRequire.ResultsNode = function() {
|
||||
this.last = function() {
|
||||
return this.children[this.children.length - 1];
|
||||
};
|
||||
|
||||
this.updateResult = function(result) {
|
||||
this.result = result;
|
||||
};
|
||||
}
|
||||
|
||||
return ResultsNode;
|
||||
@@ -430,9 +802,11 @@ jasmineRequire.ResultsNode = function() {
|
||||
|
||||
jasmineRequire.QueryString = function() {
|
||||
function QueryString(options) {
|
||||
|
||||
this.navigateWithNewParam = function(key, value) {
|
||||
options.getWindowLocation().search = this.fullStringWithNewParam(key, value);
|
||||
options.getWindowLocation().search = this.fullStringWithNewParam(
|
||||
key,
|
||||
value
|
||||
);
|
||||
};
|
||||
|
||||
this.fullStringWithNewParam = function(key, value) {
|
||||
@@ -450,7 +824,9 @@ jasmineRequire.QueryString = function() {
|
||||
function toQueryString(paramMap) {
|
||||
var qStrPairs = [];
|
||||
for (var prop in paramMap) {
|
||||
qStrPairs.push(encodeURIComponent(prop) + '=' + encodeURIComponent(paramMap[prop]));
|
||||
qStrPairs.push(
|
||||
encodeURIComponent(prop) + '=' + encodeURIComponent(paramMap[prop])
|
||||
);
|
||||
}
|
||||
return '?' + qStrPairs.join('&');
|
||||
}
|
||||
@@ -474,7 +850,6 @@ jasmineRequire.QueryString = function() {
|
||||
|
||||
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,5 +1,5 @@
|
||||
/*
|
||||
Copyright (c) 2008-2016 Pivotal Labs
|
||||
Copyright (c) 2008-2021 Pivotal Labs
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
@@ -23,10 +23,7 @@ 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 env = jasmine.getEnv({suppressLoadErrors: true});
|
||||
|
||||
var jasmineInterface = jasmineRequire.interface(jasmine, env);
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
../../spec
|
||||
@@ -4,6 +4,6 @@
|
||||
#
|
||||
module Jasmine
|
||||
module Core
|
||||
VERSION = "2.5.1"
|
||||
VERSION = "3.10.1"
|
||||
end
|
||||
end
|
||||
|
||||
98
package.json
98
package.json
@@ -1,34 +1,104 @@
|
||||
{
|
||||
"name": "jasmine-core",
|
||||
"license": "MIT",
|
||||
"version": "2.5.1",
|
||||
"version": "3.10.1",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/jasmine/jasmine.git"
|
||||
},
|
||||
"keywords": [
|
||||
"test",
|
||||
"testing",
|
||||
"jasmine",
|
||||
"tdd",
|
||||
"bdd"
|
||||
],
|
||||
"scripts": {
|
||||
"test": "grunt jshint execSpecsInNode"
|
||||
"posttest": "eslint \"src/**/*.js\" \"spec/**/*.js\" && prettier --check \"src/**/*.js\" \"spec/**/*.js\"",
|
||||
"test": "grunt --stack execSpecsInNode",
|
||||
"cleanup": "prettier --write \"src/**/*.js\" \"spec/**/*.js\"",
|
||||
"build": "grunt buildDistribution",
|
||||
"serve": "node spec/support/localJasmineBrowser.js",
|
||||
"serve:performance": "node spec/support/localJasmineBrowser.js jasmine-browser-performance.json",
|
||||
"ci": "node spec/support/ci.js",
|
||||
"ci:performance": "node spec/support/ci.js jasmine-browser-performance.json"
|
||||
},
|
||||
"description": "Official packaging of Jasmine's core files for use by Node.js projects.",
|
||||
"homepage": "http://jasmine.github.io",
|
||||
"description": "Simple JavaScript testing framework for browsers and node.js",
|
||||
"homepage": "https://jasmine.github.io",
|
||||
"main": "./lib/jasmine-core.js",
|
||||
"files": [
|
||||
"MIT.LICENSE",
|
||||
"README.md",
|
||||
"images/*.{png,svg}",
|
||||
"lib/**/*.{js,css}",
|
||||
"package.json"
|
||||
],
|
||||
"devDependencies": {
|
||||
"glob": "~7.0.5",
|
||||
"grunt": "^1.0.1",
|
||||
"grunt-cli": "^1.2.0",
|
||||
"grunt-contrib-compass": "^1.1.1",
|
||||
"ejs": "^2.5.5",
|
||||
"eslint": "^6.8.0",
|
||||
"eslint-plugin-compat": "^3.8.0",
|
||||
"fast-glob": "^2.2.6",
|
||||
"grunt": "^1.0.4",
|
||||
"grunt-cli": "^1.3.2",
|
||||
"grunt-contrib-compress": "^1.3.0",
|
||||
"grunt-contrib-concat": "^1.0.1",
|
||||
"grunt-contrib-jshint": "^1.0.0",
|
||||
"jasmine": "^2.4.0",
|
||||
"load-grunt-tasks": "^0.4.0",
|
||||
"shelljs": "^0.7.0",
|
||||
"temp": "~0.8.1"
|
||||
}
|
||||
"grunt-css-url-embed": "^1.11.1",
|
||||
"grunt-sass": "^3.0.2",
|
||||
"jasmine": "^3.4.0",
|
||||
"jasmine-browser-runner": "github:jasmine/jasmine-browser#main",
|
||||
"jsdom": "^15.0.0",
|
||||
"load-grunt-tasks": "^4.0.0",
|
||||
"prettier": "1.17.1",
|
||||
"sass": "^1.32.12",
|
||||
"shelljs": "^0.8.3",
|
||||
"temp": "^0.9.0"
|
||||
},
|
||||
"prettier": {
|
||||
"singleQuote": true
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"plugin:compat/recommended"
|
||||
],
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 5
|
||||
},
|
||||
"rules": {
|
||||
"quotes": [
|
||||
"error",
|
||||
"single",
|
||||
{
|
||||
"avoidEscape": true
|
||||
}
|
||||
],
|
||||
"no-unused-vars": [
|
||||
"error",
|
||||
{
|
||||
"args": "none"
|
||||
}
|
||||
],
|
||||
"block-spacing": "error",
|
||||
"func-call-spacing": [
|
||||
"error",
|
||||
"never"
|
||||
],
|
||||
"key-spacing": "error",
|
||||
"no-tabs": "error",
|
||||
"no-trailing-spaces": "error",
|
||||
"no-whitespace-before-property": "error",
|
||||
"semi": [
|
||||
"error",
|
||||
"always"
|
||||
],
|
||||
"space-before-blocks": "error"
|
||||
}
|
||||
},
|
||||
"browserslist": [
|
||||
"Safari >= 8",
|
||||
"last 2 Chrome versions",
|
||||
"last 2 Firefox versions",
|
||||
"Firefox 68",
|
||||
"last 2 Edge versions",
|
||||
"IE >= 10"
|
||||
]
|
||||
}
|
||||
|
||||
14
release_notes/2.5.2.md
Normal file
14
release_notes/2.5.2.md
Normal file
@@ -0,0 +1,14 @@
|
||||
# Jasmine 2.5.2 Release Notes
|
||||
|
||||
## Pull Requests & Issues
|
||||
|
||||
* Allow currently registered reporters to be cleared
|
||||
- [jasmine/jasmine-npm#88](https://github.com/jasmine/jasmine-npm/issues/88)
|
||||
|
||||
|
||||
* Use `isFunction` to check for functionness in `callFake`
|
||||
- Fixes [#1191](https://github.com/jasmine/jasmine/issues/1191)
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_
|
||||
108
release_notes/2.6.0.md
Normal file
108
release_notes/2.6.0.md
Normal file
@@ -0,0 +1,108 @@
|
||||
# Jasmine 2.6.0 Release Notes
|
||||
|
||||
## Summary
|
||||
|
||||
This release contains a number of fixes and pull requests.
|
||||
|
||||
## Pull Requests & Issues
|
||||
|
||||
Updating introduction url to last version
|
||||
- Merges [#1316](https://github.com/jasmine/jasmine/issues/1316) from @rachelcarmena
|
||||
|
||||
* Throw a recognizable Error message when `fail` outside of a spec.
|
||||
- Fixes [#1017](https://github.com/jasmine/jasmine/issues/1017)
|
||||
|
||||
* Allow the matcher provide a custom error message
|
||||
- Merges [#1298](https://github.com/jasmine/jasmine/issues/1298) from @deckar01
|
||||
- Fixes [#1123](https://github.com/jasmine/jasmine/issues/1123)
|
||||
|
||||
* Fix the order in which afterAll hooks are run to match afterEach
|
||||
- Merges [#1312](https://github.com/jasmine/jasmine/issues/1312) from @gdborton
|
||||
- Fixes [#1311](https://github.com/jasmine/jasmine/issues/1311)
|
||||
|
||||
* Add matchers for positive and negative infinity
|
||||
- Merges [#1300](https://github.com/jasmine/jasmine/issues/1300) from @toubou91
|
||||
- Fixes [#1294](https://github.com/jasmine/jasmine/issues/1294)
|
||||
|
||||
* Add a first pass at JSDocs for the intended public API
|
||||
- Fixes [#596](https://github.com/jasmine/jasmine/issues/596)
|
||||
|
||||
* Pretty print objects passed to fail method
|
||||
- Merges [#1283](https://github.com/jasmine/jasmine/issues/1283) from @mmmichl
|
||||
- Fixes [#1090](https://github.com/jasmine/jasmine/issues/1090)
|
||||
|
||||
* Properly check for Error constructor from a different frame
|
||||
- Merges [#1275](https://github.com/jasmine/jasmine/issues/1275) from @anseki
|
||||
- Fixes [#1252](https://github.com/jasmine/jasmine/issues/1252)
|
||||
|
||||
* Add toHaveBeenCalledBefore matcher
|
||||
- Merges [#1242](https://github.com/jasmine/jasmine/issues/1242) from @DamienCassou
|
||||
|
||||
* Collect unhandled exceptions and pass them to the current runnable
|
||||
- Fixes [#529](https://github.com/jasmine/jasmine/issues/529)
|
||||
- Fixes [#937](https://github.com/jasmine/jasmine/issues/937)
|
||||
|
||||
* Nicer error messages for `spyOn` when `null` is provided
|
||||
- Fixes [#1258](https://github.com/jasmine/jasmine/issues/1258)
|
||||
|
||||
* Require arguments to beforeEach, it, etc, to be actual functions
|
||||
- Merges [#1222](https://github.com/jasmine/jasmine/issues/1222) from @voithos
|
||||
- Fixes [#1004](https://github.com/jasmine/jasmine/issues/1004)
|
||||
|
||||
* Update MIT.LICENSE for new year
|
||||
- Merges [#1249](https://github.com/jasmine/jasmine/issues/1249) from @Scottkao85
|
||||
|
||||
* Update README.md for new year
|
||||
- Merges [#1248](https://github.com/jasmine/jasmine/issues/1248) from @Nebojsaa
|
||||
|
||||
* Remove unused `message` param from Suite#pend
|
||||
- See [#1132](https://github.com/jasmine/jasmine/issues/1132)
|
||||
|
||||
* Fix bug where before/afterAll were being executed in disabled suites.
|
||||
- Merges [#1225](https://github.com/jasmine/jasmine/issues/1225) from @voithos
|
||||
- Fixes [#1175](https://github.com/jasmine/jasmine/issues/1175)
|
||||
|
||||
* Make toEqual matcher report the difference between objects
|
||||
- Merges [#1163](https://github.com/jasmine/jasmine/issues/1163) from @benchristel
|
||||
- Fixes [#675](https://github.com/jasmine/jasmine/issues/675)
|
||||
- Merges [#1236](https://github.com/jasmine/jasmine/issues/1236) from @benchristel
|
||||
|
||||
|
||||
* Implement spies for get/set functions on accessor properties
|
||||
- Merges [#1203](https://github.com/jasmine/jasmine/issues/1203) from @celluj34
|
||||
- Merges [#1008](https://github.com/jasmine/jasmine/issues/1008) from @smacker
|
||||
- Fixes [#943](https://github.com/jasmine/jasmine/issues/943)
|
||||
|
||||
* When the HtmlReporter has a 'spec' query param, the spec list only shows matching specs/suites
|
||||
- Merges [#1046](https://github.com/jasmine/jasmine/issues/1046) from @d-reinhold
|
||||
- Fixes [#510](https://github.com/jasmine/jasmine/issues/510)
|
||||
|
||||
* createSpyObj may use object for method/response shorthand
|
||||
- Merges [#1101](https://github.com/jasmine/jasmine/issues/1101) from @mbildner
|
||||
|
||||
* Separate clear stack and run it after each spec
|
||||
- Fixes [#985](https://github.com/jasmine/jasmine/issues/985)
|
||||
- Fixes [#945](https://github.com/jasmine/jasmine/issues/945)
|
||||
- Fixes [#366](https://github.com/jasmine/jasmine/issues/366)
|
||||
|
||||
* Now spies preserve original function arity
|
||||
- Merges [#1055](https://github.com/jasmine/jasmine/issues/1055) from @kapke
|
||||
- Fixes [#991](https://github.com/jasmine/jasmine/issues/991)
|
||||
|
||||
* Added support for ES6 sets to toContain and toEqual.
|
||||
- Merges [#1067](https://github.com/jasmine/jasmine/issues/1067) from @alur
|
||||
|
||||
* Correctly pretty print objects from other contexts (e.g. iframes) and which do not override toString
|
||||
- Merges [#1091](https://github.com/jasmine/jasmine/issues/1091) from @thatfulvioguy
|
||||
- Fixes [#1087](https://github.com/jasmine/jasmine/issues/1087)
|
||||
|
||||
* Pass custom testers to asymmetric testers
|
||||
- Merges [#1139](https://github.com/jasmine/jasmine/issues/1139) from @joeyparrish
|
||||
- Fixes [#1138](https://github.com/jasmine/jasmine/issues/1138)
|
||||
|
||||
* Fix bad url in README
|
||||
- Merges [#1215](https://github.com/jasmine/jasmine/issues/1215) from @mattc41190
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_
|
||||
31
release_notes/2.6.1.md
Normal file
31
release_notes/2.6.1.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# Jasmine 2.6.1 Release Notes
|
||||
|
||||
## Summary
|
||||
|
||||
This is a patch release to fix some regressions in the 2.6.0 release
|
||||
|
||||
## Pull Requests & Issues
|
||||
|
||||
* Update README.md to make installation instructions more version-agnostic
|
||||
- Merges #1319 from @reinrl
|
||||
|
||||
* Check for `process.listeners` as well, for GlobalErrors
|
||||
- Fixes #1333
|
||||
|
||||
* allow explicit undefined as function for `it` and `xit`
|
||||
- Merges #1329 from @UziTech
|
||||
- Fixes #1328
|
||||
|
||||
* remove eval to create spy wrapper
|
||||
- Merges #1330 from @UziTech
|
||||
- Fixes #1325
|
||||
|
||||
* iterate through keys with a regular for loop
|
||||
- Merges #1326 from @seanparmelee
|
||||
- Fixes #1321
|
||||
- Fixes #1324
|
||||
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_
|
||||
23
release_notes/2.6.2.md
Normal file
23
release_notes/2.6.2.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# Jasmine 2.6.2 Release Notes
|
||||
|
||||
## Summary
|
||||
|
||||
This is a patch release to fix some regressions and performance problems in the 2.6.0 release
|
||||
|
||||
## Changes
|
||||
|
||||
* Clear the stack if onmessage is called before the previous invocation finishes
|
||||
- Fixes #1327
|
||||
- Fixes jasmine/gulp-jasmine-browser#48
|
||||
|
||||
* Correctly route errors that occur while a QueueRunner is clearing stack
|
||||
- Merges #1352 from @sgravrock
|
||||
- Fixes #1344
|
||||
- Fixes #1349
|
||||
|
||||
* Don't mask errors that occur when no handlers are installed
|
||||
- Merges #1347 from @sgravrock
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_
|
||||
17
release_notes/2.6.3.md
Normal file
17
release_notes/2.6.3.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# Jasmine 2.6.3 Release Notes
|
||||
|
||||
## Summary
|
||||
|
||||
This is a patch release to fix some regressions and performance problems in the 2.6.0 release
|
||||
|
||||
## Changes
|
||||
|
||||
* Make sure the queue runner goes async for async specs
|
||||
- Fixes [#1327](https://github.com/jasmine/jasmine/issues/1327)
|
||||
- Fixes [#1334](https://github.com/jasmine/jasmine/issues/1334)
|
||||
- Fixes [jasmine/gulp-jasmine-browser#48](https://github.com/jasmine/gulp-jasmine-browser/issues/48)
|
||||
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_
|
||||
17
release_notes/2.6.4.md
Normal file
17
release_notes/2.6.4.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# Jasmine 2.6.4 Release Notes
|
||||
|
||||
## Summary
|
||||
|
||||
This is a patch release to fix some regressions and performance problems in the 2.6.0 release
|
||||
|
||||
## Changes
|
||||
|
||||
* Break into a `setTimeout` every once in a while allowing the CPU to run other things that used the real `setTimeout`
|
||||
- Fixes [#1327](https://github.com/jasmine/jasmine/issues/1327)
|
||||
- See [#1334](https://github.com/jasmine/jasmine/issues/1334)
|
||||
- Fixes [jasmine/gulp-jasmine-browser#48](https://github.com/jasmine/gulp-jasmine-browser/issues/48)
|
||||
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_
|
||||
61
release_notes/2.7.0.md
Normal file
61
release_notes/2.7.0.md
Normal file
@@ -0,0 +1,61 @@
|
||||
# Jasmine 2.7.0 Release Notes
|
||||
|
||||
## Summary
|
||||
|
||||
This release contains a number of fixes and pull requests.
|
||||
|
||||
## Pull Requests & Issues
|
||||
|
||||
|
||||
* Add class UserContext
|
||||
- Merges [#1400](https://github.com/jasmine/jasmine/issues/1400) from @darthjee
|
||||
|
||||
* Send unfocused tests through the same queue as focused tests
|
||||
- Merges [#1399](https://github.com/jasmine/jasmine/issues/1399) from @jberney
|
||||
|
||||
* PrettyPrinter allows an object to have a `toString` that isn't a function
|
||||
- Fixes [#1389](https://github.com/jasmine/jasmine/issues/1389)
|
||||
|
||||
* Fix rounding in toBeCloseTo
|
||||
- Fixes [#1382](https://github.com/jasmine/jasmine/issues/1382)
|
||||
|
||||
* When stop on failure is enabled, skip subsequent it() and beforeEach(). Note: afterEach() functions are still run, because skipping them is highly likely to pollute specs that run after the failure.
|
||||
- Fixes [#577](https://github.com/jasmine/jasmine/issues/577)
|
||||
- Fixes [#807](https://github.com/jasmine/jasmine/issues/807)
|
||||
|
||||
* Only clear out the `spec` param for Run all link
|
||||
- Fixes [#1369](https://github.com/jasmine/jasmine/issues/1369)
|
||||
|
||||
* Pretty printer will now use MAX_PRETTY_PRINT_ARRAY_LENGTH for objects
|
||||
- Fixes [#1291](https://github.com/jasmine/jasmine/issues/1291)
|
||||
- Fixes [#1360](https://github.com/jasmine/jasmine/issues/1360)
|
||||
|
||||
* updated package glob from 7.0.5 to 7.1.2
|
||||
- Merges [#1368](https://github.com/jasmine/jasmine/issues/1368) from @EsrefDurna
|
||||
|
||||
* Fix bower.json url to be https instead of http
|
||||
- Merges [#1365](https://github.com/jasmine/jasmine/issues/1365) from @kant
|
||||
|
||||
* Fail when one of the arguments passed into toBeCloseTo matcher is null
|
||||
- Merges [#1362](https://github.com/jasmine/jasmine/issues/1362) from @beatrichartz
|
||||
|
||||
* Fixed HTML snippet in README
|
||||
- Closes [#1366](https://github.com/jasmine/jasmine/issues/1366).
|
||||
|
||||
* Report the random seed at the beginning and end of execution. This allows reporters to provide the seed to the user even in cases where Jasmine crashes before completing.
|
||||
- Merges [#1348](https://github.com/jasmine/jasmine/issues/1348) from @sgravrock
|
||||
|
||||
* Add ES6 map support to Jasmine
|
||||
- Merges [#1340](https://github.com/jasmine/jasmine/issues/1340) from @rmehlinger
|
||||
- Fixes [#1257](https://github.com/jasmine/jasmine/issues/1257)
|
||||
|
||||
* Added support for async before/it/after functions that return promises and added support for ES2017 async functions
|
||||
- Merges [#1356](https://github.com/jasmine/jasmine/issues/1356) from @sgravrock
|
||||
- Fixes [#1336](https://github.com/jasmine/jasmine/issues/1336)
|
||||
- Fixes [#1270](https://github.com/jasmine/jasmine/issues/1270)
|
||||
- Fixes [#1350](https://github.com/jasmine/jasmine/issues/1350)
|
||||
- Fixes [#1320](https://github.com/jasmine/jasmine/issues/1320)
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_
|
||||
52
release_notes/2.8.0.md
Normal file
52
release_notes/2.8.0.md
Normal file
@@ -0,0 +1,52 @@
|
||||
# Jasmine 2.8.0 Release Notes
|
||||
|
||||
## Summary
|
||||
|
||||
This release contains a number of fixes and pull requests.
|
||||
2.8 should be the last 2.x release of Jasmine, as we aim for 3.0.
|
||||
|
||||
## Changes
|
||||
|
||||
* Create CODE_OF_CONDUCT.md
|
||||
* Add jsdocs for reporter events
|
||||
* Update jsApiReporter docs to link to new suite and spec results
|
||||
* Add explicit docs for the callback function passed to `it` etc.
|
||||
* Update afterAll documentation
|
||||
|
||||
## Pull Requests & Issues
|
||||
|
||||
* Add 'nothing' matcher and tests
|
||||
- Merges [#1412](https://github.com/jasmine/jasmine/issues/1412) from @ksvitkovsky
|
||||
- Fixes [#1221](https://github.com/jasmine/jasmine/issues/1221)
|
||||
|
||||
|
||||
* Make toEqual matcher report the difference between array elements when arrays have different length
|
||||
- Closes [#1375](https://github.com/jasmine/jasmine/issues/1375) from @kiewic
|
||||
|
||||
|
||||
* Add arrayWithExactContents asymmetric matcher
|
||||
- Fixes [#817](https://github.com/jasmine/jasmine/issues/817)
|
||||
|
||||
|
||||
* Ensure no message added on asym. match success
|
||||
- Closes [#1408](https://github.com/jasmine/jasmine/issues/1408) from @ksvitkovsky
|
||||
- Fixes [#1388](https://github.com/jasmine/jasmine/issues/1388)
|
||||
|
||||
|
||||
* Better primitives detection for saveArgsByValue
|
||||
- Closes [#1407](https://github.com/jasmine/jasmine/issues/1407) from @ksvitkovsky
|
||||
- Fixes [#1403](https://github.com/jasmine/jasmine/issues/1403)
|
||||
|
||||
|
||||
* Better pretty printing for typed arrays
|
||||
- Closes [#1404](https://github.com/jasmine/jasmine/issues/1404) from @ksvitkovsky
|
||||
- Fixes [#1180](https://github.com/jasmine/jasmine/issues/1180)
|
||||
|
||||
|
||||
* Rewrite ES6 Set and Map comparison to ignore insertion order
|
||||
- Merges [#1406](https://github.com/jasmine/jasmine/issues/1406) from @theefer
|
||||
- Fixes [#1402](https://github.com/jasmine/jasmine/issues/1402)
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_
|
||||
99
release_notes/2.9.0.md
Normal file
99
release_notes/2.9.0.md
Normal file
@@ -0,0 +1,99 @@
|
||||
# Jasmine 2.9 Release Notes
|
||||
|
||||
## Summary
|
||||
|
||||
This release contains a number of fixes and pull requests.
|
||||
|
||||
## Changes
|
||||
|
||||
* Fixed DelayedFunctionScheduler IE 8 compatibility issue
|
||||
* Fixed SPEC HAS NO EXPECTATIONS warning in HTML reporter
|
||||
* Correctly remove spies of window.onerror on IE
|
||||
* Truncate pretty printer output that is more than j$.MAX_PRETTY_PRINT_CHARS long
|
||||
* Reduced pretty printer limits to much smaller values
|
||||
* Update contributing for new naming of `jasmineUnderTest`
|
||||
* Allowed async functions to be passed into spy#callFake
|
||||
|
||||
## Pull Requests & Issues
|
||||
|
||||
* Added complete support for Set also for IE11.
|
||||
- Merges [#1478](https://github.com/jasmine/jasmine/issues/1478) from @Volox
|
||||
- Fixes [#1355](https://github.com/jasmine/jasmine/issues/1355)
|
||||
|
||||
|
||||
* Added complete support for Map also for IE11.
|
||||
- Merges [#1477](https://github.com/jasmine/jasmine/issues/1477) from @Volox
|
||||
- Fixes [#1472](https://github.com/jasmine/jasmine/issues/1472)
|
||||
|
||||
|
||||
* Use timeout objects when in node
|
||||
- Merges [#1470](https://github.com/jasmine/jasmine/issues/1470) from @chris--young
|
||||
- Fixes [#1469](https://github.com/jasmine/jasmine/issues/1469)
|
||||
|
||||
|
||||
* Fixed `pending()` for `async`/promise-returning specs
|
||||
- Fixes [#1449](https://github.com/jasmine/jasmine/issues/1449)
|
||||
- Fixes [#1450](https://github.com/jasmine/jasmine/issues/1450)
|
||||
|
||||
|
||||
* Added test steps for other major node versions
|
||||
- Merges [#1448](https://github.com/jasmine/jasmine/issues/1448) from @mrlannigan
|
||||
|
||||
|
||||
* Fix equality computation for ES6 Sets.
|
||||
- Merges [#1445](https://github.com/jasmine/jasmine/issues/1445) from @b-3-n
|
||||
- Fixes [#1444](https://github.com/jasmine/jasmine/issues/1444)
|
||||
|
||||
|
||||
* Add instruction to sync local master with upstream
|
||||
- Merges [#1440](https://github.com/jasmine/jasmine/issues/1440) from aaronang
|
||||
|
||||
|
||||
* Add some unit tests that exercise jasmine.anything() and Map matching.
|
||||
- Merges [#1437](https://github.com/jasmine/jasmine/issues/1437) from @voithos
|
||||
|
||||
|
||||
* Add special handling of asymmetric matcher objects as keys in Maps.
|
||||
- Merges [#1436](https://github.com/jasmine/jasmine/issues/1436) from @voithos
|
||||
- Fixes [#1432](https://github.com/jasmine/jasmine/issues/1432)
|
||||
|
||||
|
||||
* Add support for jasmine.any(Symbol).
|
||||
- Merge [#1435](https://github.com/jasmine/jasmine/issues/1435) from @voithos
|
||||
- Fixes [#1431](https://github.com/jasmine/jasmine/issues/1431)
|
||||
|
||||
|
||||
* Throw an error for invalid nesting of a suite functions
|
||||
- Merges [#1411](https://github.com/jasmine/jasmine/issues/1411) from @ksvitkovsky
|
||||
- Fixes [#1295](https://github.com/jasmine/jasmine/issues/1295)
|
||||
|
||||
|
||||
* Deep clone args before passing them to reporters
|
||||
- Merges [#1424](https://github.com/jasmine/jasmine/issues/1424) from @aj-dev
|
||||
|
||||
|
||||
* Fix "Before Committing" section of CONTRIBUTING.md.
|
||||
- Merges [#1429](https://github.com/jasmine/jasmine/issues/1429) from @voithos
|
||||
|
||||
|
||||
* Fix lint warning in CallTracker.
|
||||
- Merges [#1428](https://github.com/jasmine/jasmine/issues/1428) from @voithos
|
||||
|
||||
|
||||
* clearTimeout should now correctly clear a timeout that is also scheduled to run at the same tick.
|
||||
- Merges [#1427](https://github.com/jasmine/jasmine/issues/1427) from @leahciMic
|
||||
- Fixes [#1426](https://github.com/jasmine/jasmine/issues/1426)
|
||||
|
||||
|
||||
* Add a note about `defineProperty` for `spyOnProperty`
|
||||
- Fixes [#1415](https://github.com/jasmine/jasmine/issues/1415)
|
||||
|
||||
|
||||
* Add Promise checking to eq
|
||||
- Merges [#1386](https://github.com/jasmine/jasmine/issues/1386) from @sderickson
|
||||
- Fixes [#1314](https://github.com/jasmine/jasmine/issues/1314)
|
||||
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_
|
||||
15
release_notes/2.9.1.md
Normal file
15
release_notes/2.9.1.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# Jasmine Core 2.9.1 Release Notes
|
||||
|
||||
## Summary
|
||||
|
||||
This is a hotfix release to fix a breaking change from the 2.9.0 release
|
||||
|
||||
## Changes
|
||||
|
||||
* Clear timeouts when starting to process a milli instead of at the end
|
||||
- Fixes #1482
|
||||
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_
|
||||
19
release_notes/2.99.md
Normal file
19
release_notes/2.99.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# Jasmine-Core 2.99 Release Notes
|
||||
|
||||
## Summary
|
||||
|
||||
This release is part of the upgrade path to Jasmine 3.0. It deprecates some functionality that will change.
|
||||
|
||||
## Changes
|
||||
|
||||
* Add ability to report deprecation warnings from within the suite and display them in the HTML reporter
|
||||
* Add deprecation messages for things that will change/break in 3.0
|
||||
* * done for async functionality will now add a failure if it is invoked with an Error
|
||||
* * Env.catchExceptions and the query param are going away, in favor of a more fully functional fail fast handler
|
||||
* * jasmine.Any(Object) will no longer match null
|
||||
* * Unhandled errors during suite load will be caught and reported as failures by Jasmine
|
||||
* * Calling execute more than once on the same spec will definitely fail in 3.0
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_
|
||||
91
release_notes/3.0.md
Normal file
91
release_notes/3.0.md
Normal file
@@ -0,0 +1,91 @@
|
||||
# Jasmine-Core 3.0 Release Notes
|
||||
|
||||
## Summary
|
||||
|
||||
Jasmine 3.0 is a major release of Jasmine, and as such includes some breaking changes in addition to various new features.
|
||||
|
||||
There is also a 2.99 release of Jasmine that will present deprecation warnings for suites that will encounter different behavior in 3.0.
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
* Replace old "catch exceptions" logic with proper fail fast with error reporting
|
||||
- Fixes [#414](https://github.com/jasmine/jasmine/issues/414)
|
||||
- Fixes [jasmine/jasmine-npm#16](https://github.com/jasmine/jasmine-npm/issues/16)
|
||||
|
||||
* Detect an Error passed to `done` and add an expectation failure
|
||||
- Fixes [#567](https://github.com/jasmine/jasmine/issues/567)
|
||||
|
||||
* Unify status for xdescribe and xit
|
||||
- Ensure *All's only execute if at least one child will run
|
||||
- Specs will report a status of `excluded` instead of disabled
|
||||
- Fixes [#1418](https://github.com/jasmine/jasmine/issues/1418)
|
||||
|
||||
* Suite level errors all report the same way (on suiteDone)
|
||||
|
||||
* Refactor QueueRunner and remove references to functions that Jasmine is done with
|
||||
|
||||
* expect(null).toEqual(jasmine.any(Object)) no longer passes
|
||||
- Fixes [#1255](https://github.com/jasmine/jasmine/issues/1255)
|
||||
|
||||
* Default to running tests in random order
|
||||
|
||||
* The `identity` of a Jasmnine Spy is now a property and no longer a method
|
||||
|
||||
* Additionally, Jasmine 3.0 drops support for older browsers and environments. Notably:
|
||||
- Internet Explorer 8 and 9
|
||||
- Ruby 1.x (for the Ruby gem)
|
||||
- Rails 3.x (for the Ruby gem)
|
||||
- Python 2.x (for the Python wheel)
|
||||
- Nodejs 0.x (for the NPM package)
|
||||
|
||||
## Changes
|
||||
|
||||
* Remove node modules from python wheel, and update languages
|
||||
|
||||
* Allow reporter callbacks to be asynchronous
|
||||
- Fixes [#842](https://github.com/jasmine/jasmine/issues/842)
|
||||
|
||||
* Allow adding custom spy strategies
|
||||
|
||||
* Add the ability to specify the strategy to use for a spy based on which parameters are passed
|
||||
|
||||
* Added links to re-run the suites containing a failing spec
|
||||
|
||||
* Added a toHaveClass matcher
|
||||
|
||||
* More informative pretty-printing of DOM elements
|
||||
|
||||
* Allow jasmine-npm to handle its own load errors
|
||||
|
||||
* Treat random= as a no-op rather than disabling randomization
|
||||
|
||||
* Use prototype for spy strategy for better memory management
|
||||
|
||||
* Remove console.js altogether
|
||||
|
||||
* Add safari 10 and update readme to include edge
|
||||
|
||||
* Determine overall status in core, not reporters
|
||||
|
||||
* Filter Jasmine frames from stack traces
|
||||
|
||||
* Treat afterAll errors at any level as failures
|
||||
|
||||
* Improved reporting of load errors and afterAll errors
|
||||
- Pass file and line number to reporters when present
|
||||
- Show file and line number in the HTML reporter when present
|
||||
- Visually separate adjacent errors in the HTML reporter
|
||||
|
||||
* Report loading errors as loading errors, not afterAll errors
|
||||
|
||||
* HTML reporter reports overall failure if there are any global errors
|
||||
|
||||
* Fail if error events (e.g. syntax errors) occur during loading
|
||||
|
||||
* Allow use of a predicate function to validate thrown exceptions
|
||||
|
||||
* Check truthiness of toThrowError args, not arg count
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_
|
||||
54
release_notes/3.1.0.md
Normal file
54
release_notes/3.1.0.md
Normal file
@@ -0,0 +1,54 @@
|
||||
# Jasmine-Core 3.1 Release Notes
|
||||
|
||||
## Summary
|
||||
|
||||
This release contains a number of fixes and pull requests
|
||||
|
||||
## Pull Requests and Issues
|
||||
|
||||
* Display error properties for failed specs
|
||||
- Merges [#1516](https://github.com/jasmine/jasmine/issues/1516) from @jbunton-atlassian
|
||||
|
||||
* Allow node to report load time errors
|
||||
- Fixes [#1519](https://github.com/jasmine/jasmine/issues/1519)
|
||||
|
||||
* Fixing missing semi-colons
|
||||
- Merges [#1512](https://github.com/jasmine/jasmine/issues/1512) from @Sylhare
|
||||
|
||||
* Fixed release notes link
|
||||
|
||||
* Added matchers: truthy, falsy, empty and notEmpty
|
||||
- Merges [#1460](https://github.com/jasmine/jasmine/issues/1460) from @sjolicoeur
|
||||
|
||||
* Add API docs for async reporters
|
||||
|
||||
* Return <anonymous> for functions that have no actual words between keyword and (
|
||||
- Also fixes a potential catastrophic backtracking if someone has
|
||||
severely damaged their own `toString` during test execution.
|
||||
|
||||
* Moved toHaveClass matcher into core so that it can be used in Karma
|
||||
- Fixes [#1503](https://github.com/jasmine/jasmine/issues/1503)
|
||||
|
||||
* allow adding a deprecation object
|
||||
- Merges [#1498](https://github.com/jasmine/jasmine/issues/1498) from @UziTech
|
||||
|
||||
* Add CodeTriage badge to jasmine/jasmine
|
||||
- Merges [#1505](https://github.com/jasmine/jasmine/issues/1505) from @codetriage-readme-bot
|
||||
|
||||
* Resolve merge conflict
|
||||
- Merges [#1501](https://github.com/jasmine/jasmine/issues/1501) from @aptx4869
|
||||
- Fixes [#1500](https://github.com/jasmine/jasmine/issues/1500)
|
||||
|
||||
* Fix release note typo
|
||||
- Merges [#1499](https://github.com/jasmine/jasmine/issues/1499) @bcaudan
|
||||
|
||||
* Only show deprecation for catch exceptions if you tell Jasmine not to catch
|
||||
- Fixes [#1497](https://github.com/jasmine/jasmine/issues/1497)
|
||||
|
||||
* Add notes for environments that have lost support
|
||||
- Fixes [#1495](https://github.com/jasmine/jasmine/issues/1495)
|
||||
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_
|
||||
57
release_notes/3.10.0.md
Normal file
57
release_notes/3.10.0.md
Normal file
@@ -0,0 +1,57 @@
|
||||
# Jasmine Core 3.10 Release Notes
|
||||
|
||||
## New features and bug fixes
|
||||
|
||||
* Added support for running Jasmine multiple times
|
||||
* If the env is configured with `autoCleanClosures: false`, then it can be
|
||||
executed repeatedly.
|
||||
* Merges #1934 from @nicojs
|
||||
* Fixes #1925
|
||||
|
||||
* Improved error message when an async expectation occurs after the spec
|
||||
finishes
|
||||
* Merges #1937 from @AndreWillomitzer
|
||||
* Fixes #1854
|
||||
|
||||
* Reject timeout values that are too large for setTimeout
|
||||
* See #1930
|
||||
|
||||
* Don't immediately move to the next queueable fn on async error
|
||||
|
||||
This allows assertion failures and other errors that occur after the async
|
||||
error to be routed to the correct spec/suite.
|
||||
|
||||
* Added a stringContaining asymmetric equality tester
|
||||
* Fixes #1923.
|
||||
|
||||
* The jasmine-core Ruby gem now prints a deprecation message when loaded unless
|
||||
the SUPPRESS_JASMINE_DEPRECATION environment variable is set.
|
||||
|
||||
|
||||
## Documentation updates
|
||||
|
||||
* Added discussion of max timeout value to jsdocs
|
||||
* Merges #1931 from @trusktr
|
||||
|
||||
* Added missing @since annotations
|
||||
|
||||
* Improved jsdocs for asymmetric equality testers
|
||||
|
||||
* Added a deprecation notice to the jasmine-core Ruby gem's description
|
||||
|
||||
## Supported environments
|
||||
|
||||
jasmine-core 3.10.0 has been tested in the following environments.
|
||||
|
||||
| Environment | Supported versions |
|
||||
|-------------------|--------------------|
|
||||
| Node | 10, 12, 14, 16 |
|
||||
| Safari | 8-14 |
|
||||
| Chrome | 94 |
|
||||
| Firefox | 93, 78, 68 |
|
||||
| Edge | 94 |
|
||||
| Internet Explorer | 10, 11 |
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_
|
||||
12
release_notes/3.10.1.md
Normal file
12
release_notes/3.10.1.md
Normal file
@@ -0,0 +1,12 @@
|
||||
# Jasmine Core 3.10.1 Release Notes
|
||||
|
||||
## Bugfixes
|
||||
|
||||
* Fixed missing pendingReason in pending spec results
|
||||
* Fixes [#1939](https://github.com/jasmine/jasmine/issues/1939)
|
||||
* Merges [#1940](https://github.com/jasmine/jasmine/pull/1940) from @jan-molak
|
||||
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_
|
||||
83
release_notes/3.2.0.md
Normal file
83
release_notes/3.2.0.md
Normal file
@@ -0,0 +1,83 @@
|
||||
# Jasmine-Core 3.2 Release Notes
|
||||
|
||||
## Summary
|
||||
|
||||
This release contains a number of fixes and pull requests
|
||||
|
||||
## Changes
|
||||
|
||||
* Add spyOnAllFunctions function
|
||||
- Merges [#1581](https://github.com/jasmine/jasmine/issues/1581) from @aeisenberg
|
||||
- Fixes [#1421](https://github.com/jasmine/jasmine/issues/1421)
|
||||
|
||||
|
||||
* Improve timeout error message
|
||||
- Merges [#1567](https://github.com/jasmine/jasmine/issues/1567) from @ikonst
|
||||
|
||||
|
||||
* Fix JSDoc naming for Env functions
|
||||
- See [#1565](https://github.com/jasmine/jasmine/issues/1565)
|
||||
|
||||
|
||||
* Add documentation for more public functions on Env
|
||||
- Fixes [#1565](https://github.com/jasmine/jasmine/issues/1565)
|
||||
|
||||
|
||||
* Added a basic set of async matchers
|
||||
- Fixes [#1447](https://github.com/jasmine/jasmine/issues/1447)
|
||||
- Fixes [#1547](https://github.com/jasmine/jasmine/issues/1547)
|
||||
|
||||
|
||||
* Properly cascade StopExecutionError's up the tree
|
||||
- Fixes [#1563](https://github.com/jasmine/jasmine/issues/1563)
|
||||
|
||||
|
||||
* Implemented hiding of disabled specs
|
||||
- Merges [#1561](https://github.com/jasmine/jasmine/issues/1561) from @SamFare
|
||||
|
||||
|
||||
* Line-break long expectation failure messages
|
||||
- See [#296](https://github.com/jasmine/jasmine/issues/296)
|
||||
|
||||
|
||||
* Better detection of DOM Nodes for equality
|
||||
- Fixes [#1172](https://github.com/jasmine/jasmine/issues/1172)
|
||||
|
||||
|
||||
* Fix typo from `incimplete` to `incomplete`
|
||||
- Merges [#1555](https://github.com/jasmine/jasmine/issues/1555) from @yinm
|
||||
|
||||
|
||||
* Allow omitting the name argument: `createSpy(func)`
|
||||
- Merges [#1551](https://github.com/jasmine/jasmine/issues/1551) from @riophae
|
||||
|
||||
|
||||
* name new global status stuff correctly in API docs
|
||||
|
||||
|
||||
* Check for accidental global variable creation
|
||||
|
||||
|
||||
* Fixed global variable leak
|
||||
- Fixes [#1534](https://github.com/jasmine/jasmine/issues/1534)
|
||||
|
||||
|
||||
* Correctly format stack traces for errors with multiline messages
|
||||
- Fixes [#1526](https://github.com/jasmine/jasmine/issues/1526)
|
||||
|
||||
|
||||
* Change message for extra elements at end of actual array
|
||||
- Merges [#1527](https://github.com/jasmine/jasmine/issues/1527) from @majidmade
|
||||
- Fixes [#1485](https://github.com/jasmine/jasmine/issues/1485)
|
||||
|
||||
|
||||
* Report unhandled rejections as globalErrors.
|
||||
- Merges [#1521](https://github.com/jasmine/jasmine/issues/1521) from @johnjbarton
|
||||
|
||||
|
||||
* add some links to more tutorials from the api docs
|
||||
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_
|
||||
11
release_notes/3.2.1.md
Normal file
11
release_notes/3.2.1.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# Jasmine-Core 3.2.1 Release Notes
|
||||
|
||||
## Changes
|
||||
|
||||
* Correctly expose `spyOnAllFunctions`
|
||||
- See [#1581](https://github.com/jasmine/jasmine/issues/1581)
|
||||
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_
|
||||
47
release_notes/3.3.0.md
Normal file
47
release_notes/3.3.0.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# Jasmine Core 3.3 Release Notes
|
||||
|
||||
## Summary
|
||||
|
||||
This release includes a new way to configure Jasmine, the ability to provide additional
|
||||
context with your expectations, and other things
|
||||
|
||||
## Changes
|
||||
|
||||
* Added expect().withContext() to provide additional information in failure messages
|
||||
* Implement `withContext` for async expectations too
|
||||
- Fixes [#641](https://github.com/jasmine/jasmine/issues/641)
|
||||
|
||||
* New asynchronous matcher `toBeRejectedWith`
|
||||
- Merges [#1615](https://github.com/jasmine/jasmine/issues/1615) from @codymikol
|
||||
- Closes [#1600](https://github.com/jasmine/jasmine/issues/1600)
|
||||
- Fixes [#1595](https://github.com/jasmine/jasmine/issues/1595)
|
||||
|
||||
* Show a tip for `toBe` failures for how to get deep equality
|
||||
- Merges [#1616](https://github.com/jasmine/jasmine/issues/1616) from @tdurtshi
|
||||
- Fixes [#1614](https://github.com/jasmine/jasmine/issues/1614)
|
||||
|
||||
* `expectAsync` now works with non-native promises
|
||||
- Merges [#1613](https://github.com/jasmine/jasmine/issues/1613) from @codymikol
|
||||
- Fixes [#1612](https://github.com/jasmine/jasmine/issues/1612)
|
||||
|
||||
|
||||
* Show status marks next to spec description in HTML reporter
|
||||
- Merges [#1610](https://github.com/jasmine/jasmine/issues/1610) from @m1010j
|
||||
- Fixes [#1596](https://github.com/jasmine/jasmine/issues/1596)
|
||||
|
||||
* Show error messages for `Error`s without a name
|
||||
- Merges [#1601](https://github.com/jasmine/jasmine/issues/1601) from @nitobuendia
|
||||
- Fixes [#1594](https://github.com/jasmine/jasmine/issues/1594)
|
||||
|
||||
* Optimized clearTimeout cpu usage
|
||||
- Merges [#1599](https://github.com/jasmine/jasmine/issues/1599) from @Havunen
|
||||
|
||||
* Introduce a configuration object to `Env` deprecating old single use functions
|
||||
- [finishes #159158038](http://www.pivotaltracker.com/story/159158038)
|
||||
|
||||
* Specify https for github urls in package.json
|
||||
- Merges [#1597](https://github.com/jasmine/jasmine/issues/1597) @limonte
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_
|
||||
49
release_notes/3.4.0.md
Normal file
49
release_notes/3.4.0.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# Jasmine Core 3.4 Release Notes
|
||||
|
||||
## Summary
|
||||
|
||||
This is a maintenance release of Jasmine with a number of new features and fixes
|
||||
|
||||
## Changes
|
||||
|
||||
* Handle WebSocket events in IE when detecting Errors
|
||||
- Fixes [#1623](https://github.com/jasmine/jasmine/issues/1623)
|
||||
|
||||
* bump dependencies for security fixes
|
||||
- Merges [#1672](https://github.com/jasmine/jasmine/issues/1672) from @wood1986
|
||||
|
||||
* Make node execution default and override for browsers
|
||||
- Merges [#1658](https://github.com/jasmine/jasmine/issues/1658) from @wood1986
|
||||
- Fixes [#883](https://github.com/jasmine/jasmine/issues/883)
|
||||
|
||||
* feat(result.duration): report test duration in ms
|
||||
- Merges [#1660](https://github.com/jasmine/jasmine/issues/1660) from @johnjbarton
|
||||
- Fixes [#1646](https://github.com/jasmine/jasmine/issues/1646)
|
||||
|
||||
* refactor(Timer): share htmlReporter noopTimer via Timer.js
|
||||
- Merges [#1669](https://github.com/jasmine/jasmine/issues/1669) from @johnjbarton
|
||||
|
||||
* Fix various typos
|
||||
- Merges [#1666](https://github.com/jasmine/jasmine/issues/1666) from @FelixRilling
|
||||
- Merges [#1667](https://github.com/jasmine/jasmine/issues/1667) from @FelixRilling
|
||||
- Merges [#1665](https://github.com/jasmine/jasmine/issues/1665) from @FelixRilling
|
||||
- Merges [#1664](https://github.com/jasmine/jasmine/issues/1664) from @FelixRilling
|
||||
- Fixes [#1663](https://github.com/jasmine/jasmine/issues/1663)
|
||||
|
||||
* When catching a global error in Node.js, print the type of error
|
||||
- Merges [#1632](https://github.com/jasmine/jasmine/issues/1632) from @jbunton-atlassian
|
||||
|
||||
* Support Error.stack in globalErrors.
|
||||
- Merges [#1644](https://github.com/jasmine/jasmine/issues/1644) from @johnjbarton
|
||||
|
||||
* Stop treating objects with a `nodeType` as if they are DOM Nodes
|
||||
- Fixes [#1638](https://github.com/jasmine/jasmine/issues/1638)
|
||||
|
||||
* Fixes issue where PhantomJS 2 and IE 10 - 11 crashed when reporting SVG element equality
|
||||
- Merges [#1621](https://github.com/jasmine/jasmine/issues/1621) from @Havunen
|
||||
- Fixes [#1618](https://github.com/jasmine/jasmine/issues/1618)
|
||||
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_
|
||||
199
release_notes/3.5.0.md
Normal file
199
release_notes/3.5.0.md
Normal file
@@ -0,0 +1,199 @@
|
||||
# Jasmine Core 3.5 Release Notes
|
||||
|
||||
## Summary
|
||||
|
||||
This is a maintenance release of Jasmine with a number of new features and fixes
|
||||
|
||||
### Highlights
|
||||
|
||||
* The output of toHaveBeenCalledWith should now be more readable
|
||||
|
||||
This breaks each call out onto its own line, so that it's much easier to
|
||||
see where each call starts and how they differ. E.g. previously the output
|
||||
would be:
|
||||
|
||||
Expected spy foo to have been called with [ 'bar', 'baz', 'qux' ] but actual calls were [ [ 42, 'wibble' ], [ 'bar' 'qux' ], [ 'grault '] ]
|
||||
|
||||
Now it's:
|
||||
|
||||
Expected spy foo to have been called with:
|
||||
[ 'bar', 'baz', 'qux' ]
|
||||
but actual calls were:
|
||||
[ 42, 'wibble' ],
|
||||
[ 'bar' 'qux' ],
|
||||
[ 'grault '].
|
||||
|
||||
* Add new spy strategies to resolve and reject Promises `resolveTo` and `rejectWith`
|
||||
|
||||
* Add the ability to have custom async matchers
|
||||
|
||||
### Internal notes
|
||||
|
||||
* Stop testing against PhantomJS
|
||||
* PhantomJS is at end of life, and the last version of Selenium that supported it was 3.6.0, released almost three years ago. We can't test Jasmine against PhantomJS without pinning key pieces of the project to increasingly outdated versions of key libraries.
|
||||
|
||||
* Fail Jasmine's CI build if the promise returned from `jasmineBrowser.runSpecs` is rejected
|
||||
|
||||
* A bunch of other rejiggering of the Travis-CI builds to make them easier to work with
|
||||
|
||||
* Also released a new browser runner that is being used by Jasmine
|
||||
* See [jasmine-browser-runner](https://github.com/jasmine/jasmine-browser)
|
||||
* This is a first pass at getting this to work for other projects as well. Please try it out and let us know what isn't working for you.
|
||||
|
||||
* add prettier and eslint
|
||||
|
||||
|
||||
## All Changes
|
||||
|
||||
* Adds new configuration option to failSpecWithNoExpectations that will report specs without expectations as failures if enabled
|
||||
* Merges [#1743](https://github.com/jasmine/jasmine/issues/1743) from @dtychshenko
|
||||
* Fixes [#1740](https://github.com/jasmine/jasmine/issues/1740)
|
||||
|
||||
|
||||
* Correctly propagate the `Error` object caught by the global error handler to reporters, etc.
|
||||
- Merges [#1738](https://github.com/jasmine/jasmine/issues/1738) from @prantlf
|
||||
- Fixes [#1728](https://github.com/jasmine/jasmine/issues/1728)
|
||||
|
||||
|
||||
* Show argument diffs in toHaveBeenCalledWith failure messages
|
||||
* Fixes [#1641](https://github.com/jasmine/jasmine/issues/1641)
|
||||
|
||||
|
||||
* Updated arrayContaining to require actual values to be arrays
|
||||
* Merges [#1746](https://github.com/jasmine/jasmine/issues/1746) from @divido
|
||||
* Fixes [#1745](https://github.com/jasmine/jasmine/issues/1745)
|
||||
|
||||
|
||||
* Add the ability to have custom async matchers
|
||||
* Merges [#1732](https://github.com/jasmine/jasmine/issues/1732) from @UziTech
|
||||
|
||||
|
||||
* Allow users to set a default spy strategy
|
||||
- Merges [#1716](https://github.com/jasmine/jasmine/issues/1716) from @elliot-nelson
|
||||
|
||||
|
||||
* Accept configurations with `Promise: undefined`.
|
||||
|
||||
|
||||
* PrettyPrinter survives if objects throw in toString
|
||||
- Merges [#1718](https://github.com/jasmine/jasmine/issues/1718) from @johnjbarton
|
||||
- Fixes [#1726](https://github.com/jasmine/jasmine/issues/1726)
|
||||
|
||||
|
||||
* Add `mapContaining` and `setContaining` asymmetric matchers
|
||||
* Merges [#1741](https://github.com/jasmine/jasmine/issues/1741) from @eventlistener
|
||||
|
||||
|
||||
* Use the same spec file pattern for both node and browser
|
||||
|
||||
|
||||
* Gemspec: Drop EOL'd property rubyforge_project
|
||||
* Merges [#1736](https://github.com/jasmine/jasmine/issues/1736) from @olleolleolle
|
||||
|
||||
|
||||
* Updated async timeout message to include all of the ways that async code can be run in Jasmine
|
||||
|
||||
|
||||
* Allow users to pass property names to createSpyObj
|
||||
- Merges [#1722](https://github.com/jasmine/jasmine/issues/1722) from @elliot-nelson
|
||||
- Closes [#1569](https://github.com/jasmine/jasmine/issues/1569)
|
||||
- Fixes [#1442](https://github.com/jasmine/jasmine/issues/1442)
|
||||
|
||||
|
||||
* don't attempt to normalize PNGs (gitattributes)
|
||||
- Merges [#1721](https://github.com/jasmine/jasmine/issues/1721) from @elliot-nelson
|
||||
|
||||
|
||||
* Add `@since` to most JSDoc comments
|
||||
- See [jasmine/jasmine.github.io#117](https://github.com/jasmine/jasmine.github.io/issues/117)
|
||||
|
||||
|
||||
* Make no expectations in HTML Reporter message a console warning
|
||||
- Fixes [#1704](https://github.com/jasmine/jasmine/issues/1704)
|
||||
|
||||
|
||||
* Prevent page overflow in HTML reporter under some situations by setting an explicit width
|
||||
- Merges [#1713](https://github.com/jasmine/jasmine/issues/1713) from @pixelpax
|
||||
|
||||
|
||||
* Cleanup: minor dead code removal and style fixes
|
||||
- Merges [#1708](https://github.com/jasmine/jasmine/issues/1708) from @elliot-nelson
|
||||
|
||||
|
||||
* Pretty Printer can now handle printing an object whose `toString` function has been spied upon
|
||||
- Merges [#1712](https://github.com/jasmine/jasmine/issues/1712) from @johnjbarton
|
||||
|
||||
|
||||
* PrettyPrinter handles objects with invalid toString implementations
|
||||
- Merges [#1711](https://github.com/jasmine/jasmine/issues/1711) from @elliot-nelson
|
||||
- Closes [#1700](https://github.com/jasmine/jasmine/issues/1700)
|
||||
- Closes [#1575](https://github.com/jasmine/jasmine/issues/1575)
|
||||
|
||||
|
||||
* Fix toBeCloseTo matcher for Node.js 12 and Chrome 74
|
||||
- Merges [#1710](https://github.com/jasmine/jasmine/issues/1710) from @paulvanbrenk
|
||||
- Fixes [#1695](https://github.com/jasmine/jasmine/issues/1695)
|
||||
|
||||
|
||||
* spyOnProperty jasmine-style error messages with usage note
|
||||
- Merges [#1706](https://github.com/jasmine/jasmine/issues/1706) from @elliot-nelson
|
||||
|
||||
|
||||
* spyOnProperty respects the allowRespy flag
|
||||
- Merges [#1705](https://github.com/jasmine/jasmine/issues/1705) from @elliot-nelson
|
||||
|
||||
|
||||
* Introduce matchers#toBeInstanceOf
|
||||
- Merges [#1697](https://github.com/jasmine/jasmine/issues/1697) from @elliot-nelson
|
||||
|
||||
|
||||
* Print global errors encountered during CI runs
|
||||
- Merges [#1701](https://github.com/jasmine/jasmine/issues/1701) from @elliot-nelson
|
||||
|
||||
|
||||
* Update contributing doc based on some of the newer tooling
|
||||
- Fixes [#1702](https://github.com/jasmine/jasmine/issues/1702)
|
||||
|
||||
|
||||
* Extend spyOnAllFunctions to include prototype and parent methods
|
||||
- Merges [#1699](https://github.com/jasmine/jasmine/issues/1699) from @elliot-nelson
|
||||
- Fixes [#1677](https://github.com/jasmine/jasmine/issues/1677)
|
||||
|
||||
|
||||
* Improve error handling in CI test launcher
|
||||
- Merges [#1598](https://github.com/jasmine/jasmine/issues/1598) from @elliot-nelson
|
||||
|
||||
|
||||
* Add new spy strategies to resolve and reject Promises `resolveTo` and `rejectWith`
|
||||
- Merges [#1688](https://github.com/jasmine/jasmine/issues/1688) from @enelson
|
||||
- See [#1590](https://github.com/jasmine/jasmine/issues/1590)
|
||||
- Fixes [#1715](https://github.com/jasmine/jasmine/issues/1715)
|
||||
|
||||
|
||||
* Update deprecation messages to indicate _future_ removal
|
||||
- Fixes [#1628](https://github.com/jasmine/jasmine/issues/1628)
|
||||
|
||||
* Add toBeRejectedWithError matcher
|
||||
- Merges [#1686](https://github.com/jasmine/jasmine/issues/1686) from @megahertz
|
||||
- Fixes [#1625](https://github.com/jasmine/jasmine/issues/1625)
|
||||
|
||||
|
||||
* Ignore internal ci.js from npm package
|
||||
- See [#1684](https://github.com/jasmine/jasmine/issues/1684)
|
||||
|
||||
|
||||
* Fix failure messages for positive/negative infinity matchers
|
||||
- Fixes [#1674](https://github.com/jasmine/jasmine/issues/1674)
|
||||
|
||||
|
||||
* nit: fix typo
|
||||
- Merges [#1680](https://github.com/jasmine/jasmine/issues/1680) from @acinader
|
||||
|
||||
|
||||
* added #toBeTrue and #toBeFalse matchers
|
||||
- Merges [#1679](https://github.com/jasmine/jasmine/issues/1679) from @FelixRilling
|
||||
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_
|
||||
146
release_notes/3.6.0.md
Normal file
146
release_notes/3.6.0.md
Normal file
@@ -0,0 +1,146 @@
|
||||
# Jasmine Core 3.6 Release Notes
|
||||
|
||||
## Summary
|
||||
|
||||
This is a maintenance release of Jasmine with a number of new features and fixes.
|
||||
|
||||
## Highlights
|
||||
|
||||
* Added support for custom object formatters
|
||||
* Allows customizing how an object is stringified in matcher failure messages
|
||||
* [Tutorial](https://jasmine.github.io/tutorials/custom_object_formatter)
|
||||
* [API reference](https://jasmine.github.io/api/3.6/jasmine.html#.addCustomObjectFormatter)
|
||||
|
||||
* Don't require matchers and asymmetric equality testers to pass custom object formatters back to Jasmine
|
||||
- Supports custom object formatters.
|
||||
- Makes it easier to write high quality matchers and asymmetric equality testers.
|
||||
- The old API will still work until 4.0.
|
||||
|
||||
* Properly import jasmineRequire object before using
|
||||
- Improves compatibility with Webpack
|
||||
- Merges [#1766](https://github.com/jasmine/jasmine/pull/1766) from @amilligan
|
||||
|
||||
* Added a toHaveBeenCalledOnceWith matcher
|
||||
- Merges [#1801](https://github.com/jasmine/jasmine/pull/1801) from @Maximaximum
|
||||
- Fixes [#1717](https://github.com/jasmine/jasmine/issues/1717)
|
||||
|
||||
* Added a toHaveSize matcher
|
||||
- Merges [#1796](https://github.com/jasmine/jasmine/pull/1796) from @wokier
|
||||
|
||||
* Added a toBePending async matcher
|
||||
- Merges [#1808](https://github.com/jasmine/jasmine/pull/1808) from @DCtheTall
|
||||
- Fixes [#1803](https://github.com/jasmine/jasmine/issues/1803)
|
||||
|
||||
* Added support for user-defined spec/suite properties
|
||||
- Allows specs/suites to pass data to custom reporters
|
||||
- Merges [#1763](https://github.com/jasmine/jasmine/pull/1763) from @johnjbarton
|
||||
|
||||
* Route unhandled promise rejections to onerror
|
||||
- Merges [#1778](https://github.com/jasmine/jasmine/pull/1778) from @johnjbarton
|
||||
- Fixes [#1777](https://github.com/jasmine/jasmine/issues/1777)
|
||||
|
||||
|
||||
## Internal notes
|
||||
|
||||
* Use a version of eslint that works on Node 8
|
||||
|
||||
* Check for syntax and standard library objects that don't work in IE
|
||||
|
||||
* Run eslint against all files
|
||||
|
||||
* Add Additional Test for equals Matcher
|
||||
- Merges [#1829](https://github.com/jasmine/jasmine/pull/1829) from @tobiasschweizer
|
||||
- Fixes [#1821](https://github.com/jasmine/jasmine/issues/1821)
|
||||
|
||||
* Depend on head of jasmine-browser to fix IE failures in CI
|
||||
|
||||
* Fixed test failure in Firefox 74
|
||||
|
||||
* Added test for resolveTo/rejectWith with empty parameters
|
||||
- Merges [#1802](https://github.com/jasmine/jasmine/pull/1802) from @chivesrs
|
||||
|
||||
* Removed unnecessary uses of new in tests
|
||||
|
||||
* Realigned the browser testing matrix to match current reality
|
||||
- Use Windows instead of Linux so we can get current browsers from Sauce.
|
||||
- Test against the version of Firefox that corresponds to ESR as well as
|
||||
latest.
|
||||
- Test the latest Edge rather than a specific older version.
|
||||
- Test Safari 8 and 13 instead of 8, 9 and 10. What works in those versions
|
||||
is likely to work in the ones in between.
|
||||
|
||||
* Don't leak global error handlers between Jasmine's own tests
|
||||
|
||||
* Added basic property tests for matchersUtil.equals
|
||||
|
||||
* Added integration tests for existing matcher interfaces
|
||||
|
||||
* Added integration tests for asymmetric equality testers
|
||||
|
||||
* Test IE before other browsers on Travis
|
||||
|
||||
|
||||
## Other Changes
|
||||
|
||||
* Show diffs involving root-level asymmetric equality testers
|
||||
- Fixes [#1831](https://github.com/jasmine/jasmine/issues/1831)
|
||||
|
||||
* Fixed references to master in docs
|
||||
|
||||
* Allow spy throwError to throw an Object
|
||||
- Merges [#1822](https://github.com/jasmine/jasmine/pull/1822) from @terencehonles
|
||||
|
||||
* Added missing periods to README
|
||||
- Merges [#1828](https://github.com/jasmine/jasmine/pull/1828) from @dirkpuge
|
||||
|
||||
|
||||
* Expose setSpec/SuiteProperty on interface
|
||||
- Merges [#1820](https://github.com/jasmine/jasmine/pull/1820) from @johnjbarton
|
||||
|
||||
* Prevent undesired reloads when karma-jasmine-html-reporter is used
|
||||
- Merges [#1807](https://github.com/jasmine/jasmine/pull/1807) from @parloti
|
||||
- Fixes [#1775](https://github.com/jasmine/jasmine/issues/1775)
|
||||
|
||||
* Correctly report spec and suite duration
|
||||
- Fixes [#1676](https://github.com/jasmine/jasmine/issues/1676).
|
||||
|
||||
* Added jsdocs for MatchersUtil
|
||||
|
||||
* Allow the .callThrough spy strategy to call constructor functions without errors
|
||||
- Merges [#1782](https://github.com/jasmine/jasmine/pull/1782) from @enelson
|
||||
- Fixes [#1760](https://github.com/jasmine/jasmine/issues/1760)
|
||||
|
||||
* Inject a per-runable pretty printer into MatchersUtil
|
||||
- Supports custom object formatters
|
||||
|
||||
* Include stack traces in unhandled promise rejection messages
|
||||
|
||||
* Describe the naming for the function it
|
||||
- Merges [#1772](https://github.com/jasmine/jasmine/pull/1772) from @johnlinp
|
||||
|
||||
* Correctly extract error messages from stack traces that don't start with `Error`
|
||||
- Merges [#1776](https://github.com/jasmine/jasmine/pull/1776) from @vhermannitk
|
||||
- Fixes [#1771](https://github.com/jasmine/jasmine/issues/1771)
|
||||
|
||||
* Fixed objectContaining to not match when the expected is the empty object and the actual is a non-object
|
||||
|
||||
* Fixed toEqual(0, Number.MIN_VALUE) to fail instead of passing
|
||||
- Merges [#1764](https://github.com/jasmine/jasmine/pull/1764) from @dubzzz
|
||||
|
||||
* Fixed comparison between ObjectContaining and non-objects on IE
|
||||
|
||||
* Provide better diffs for object graphs that include `objectContaining`
|
||||
|
||||
* Indent multiline failure messages in the output of `withContext`
|
||||
* This makes it easier to see where each failure message begins and ends.
|
||||
|
||||
* Report async expectations that complete after the runable completes
|
||||
- See [#1752](https://github.com/jasmine/jasmine/issues/1752).
|
||||
|
||||
* Treat NodeJS assertion failures as expectation failures
|
||||
- Merges [#1678](https://github.com/jasmine/jasmine/pull/1678) from @apla
|
||||
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_
|
||||
80
release_notes/3.7.0.md
Normal file
80
release_notes/3.7.0.md
Normal file
@@ -0,0 +1,80 @@
|
||||
# Jasmine Core 3.7 Release Notes
|
||||
|
||||
## Summary
|
||||
|
||||
This is a maintenance release of Jasmine with a number of new features and fixes.
|
||||
|
||||
|
||||
## New features and bug fixes
|
||||
|
||||
* Allow custom object formatters to be added in beforeAll
|
||||
- Fixes [#1876](http://github.com/jasmine/jasmine/issues/1876)
|
||||
|
||||
* Allow specs to disable Jasmine's global error handling by overwriting `onerror`.
|
||||
- Merges [#1860](https://github.com/jasmine/jasmine/pull/1860) from @greghuc
|
||||
|
||||
* Fixed comparison between URL objects
|
||||
- Fixes [#1866](http://github.com/jasmine/jasmine/issues/1866)
|
||||
|
||||
* Added support for stack traces created by `node --enable-source-maps`
|
||||
with tools like the Typescript compiler.
|
||||
- Merges [#1862](https://github.com/jasmine/jasmine/pull/1862) from @JannesMeyer
|
||||
|
||||
* Made properties added by createSpyObj() enumerable.
|
||||
- Merges [#1859](https://github.com/jasmine/jasmine/pull/1859) from DCtheTall
|
||||
- Fixes [#1837](http://github.com/jasmine/jasmine/issues/1837)
|
||||
|
||||
* Show the name of the spec/suite that caused a deprecation
|
||||
|
||||
* Warn if a spec or before/after function both takes a callback and returns a promise
|
||||
|
||||
* Don't overwrite MatchersUtil methods with ones that were added to
|
||||
`Array.prototype`, esp. `contains`
|
||||
- Fixes [#1849](http://github.com/jasmine/jasmine/issues/1849)
|
||||
|
||||
* Allow generator functions to be passed to `.and.callFake`
|
||||
- Fixes [#1848](http://github.com/jasmine/jasmine/issues/1848)
|
||||
|
||||
|
||||
## Documentation updates
|
||||
|
||||
* Fixed instructions for contributors to run Jasmine's ci script
|
||||
|
||||
* Updated supported Node versions in README
|
||||
|
||||
* Fixed script and CSS URLs in standalone example in README
|
||||
- Merges [#1839](https://github.com/jasmine/jasmine/pull/1839) from @snowman
|
||||
|
||||
* Fixed typo in asyncMatcher toBePending comment
|
||||
- Merges [#1847](https://github.com/jasmine/jasmine/pull/1847) from @SnailCoil
|
||||
|
||||
* Fixed link to custom object formatter tutorial
|
||||
|
||||
* Added jasmine.isSpy to the public interface
|
||||
- Fixes [#1880](http://github.com/jasmine/jasmine/issues/1880)
|
||||
|
||||
|
||||
|
||||
## Internal notes
|
||||
|
||||
* Fixed intermittent test failures
|
||||
|
||||
* Added additional assertions to tests for toBeTruthy and toBeFalsy
|
||||
- Merges [#1875](https://github.com/jasmine/jasmine/pull/1875) from @yasinkocak
|
||||
|
||||
* Pointed Travis badge at travis-ci.com, not .org
|
||||
|
||||
* Fixed file globs so that Prettier runs on all files
|
||||
|
||||
* Check for forgotten console and debugger statements
|
||||
|
||||
* Fixed code in Jasmine that will trigger deprecations in 3.99
|
||||
|
||||
* Use jasmine-browser from npm rather than from the main branch
|
||||
- The current released version now works with IE, so we no longer need to
|
||||
depend on main.
|
||||
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_
|
||||
8
release_notes/3.7.1.md
Normal file
8
release_notes/3.7.1.md
Normal file
@@ -0,0 +1,8 @@
|
||||
# Jasmine Core 3.7.1 Release Notes
|
||||
|
||||
## Summary
|
||||
|
||||
This is a bug fix release of Jasmine. It's identical to 3.7.0 except that it
|
||||
correctly reports its version number. Please see the
|
||||
[3.7.0 release notes](https://github.com/jasmine/jasmine/blob/main/release_notes/3.7.0.md)
|
||||
if you're upgrading directly from 3.6.0 or earlier.
|
||||
132
release_notes/3.8.0.md
Normal file
132
release_notes/3.8.0.md
Normal file
@@ -0,0 +1,132 @@
|
||||
# Jasmine Core 3.8 Release Notes
|
||||
|
||||
## Summary
|
||||
|
||||
This is a maintenance release of Jasmine with a number of new features and fixes.
|
||||
|
||||
## Python deprecation
|
||||
|
||||
The Jasmine packages for Python are deprecated. We intend to continue releasing
|
||||
them through the end of the 3.x series, but after that they will be
|
||||
discontinued. We recommend migrating to the following alternatives:
|
||||
|
||||
* The [jasmine-browser-runner](https://github.com/jasmine/jasmine-browser)
|
||||
npm package to run specs in browsers, including headless Chrome and
|
||||
Saucelabs. This is the most direct replacement for the `jasmine server`
|
||||
and `jasmine ci` commands provided by the `jasmine` Python package.
|
||||
* The [jasmine](https://github.com/jasmine/jasmine-npm) npm package (
|
||||
`npm install jasmine`) to run specs under Node.js.
|
||||
* The standalone distribution from the
|
||||
[latest Jasmine release](https://github.com/jasmine/jasmine/releases) to
|
||||
run specs in browsers with no additional tools.
|
||||
* The [jasmine-core](https://github.com/jasmine/jasmine) npm package if all
|
||||
you need is the Jasmine assets. This is the direct equivalent of the
|
||||
jasmine-core Python package.
|
||||
|
||||
|
||||
## New features and bug fixes
|
||||
|
||||
* Fixed spec filtering in Karma
|
||||
* Merges [#1920](https://github.com/jasmine/jasmine/pull/1920) from @jlpstolwijk
|
||||
* Fixes [#1906](https://github.com/jasmine/jasmine/issues/1906)
|
||||
|
||||
* Added expectAsync(...).already
|
||||
* Causes async matchers to immediately fail if the promise is pending
|
||||
* See https://jasmine.github.io/api/3.8/async-matchers.html#already
|
||||
* Fixes [#1845](https://github.com/jasmine/jasmine/issues/1845)
|
||||
|
||||
* Include rejection details in failure messages for toBeResolved and toBeResolvedWith
|
||||
|
||||
* Fixed "stop spec on expectation failure" checkbox in standalone
|
||||
|
||||
* Added option for spyOnAllFunctions to include non-enumerable props
|
||||
* Makes spyOnAllFunctions work on instance methods of ES6 classes
|
||||
* Merges [#1909](https://github.com/jasmine/jasmine/pull/1909) from @Dari-k
|
||||
* Fixes [#1897](https://github.com/jasmine/jasmine/issues/1897)
|
||||
|
||||
* Added Spy#calls#thisFor
|
||||
* Provides the `this` value for a given spy call
|
||||
* Merges [#1903](https://github.com/jasmine/jasmine/pull/1903) from @ajvincent
|
||||
|
||||
* Improved handling of unhandled promise rejections with no error in Node
|
||||
* Fixes [#1759](https://github.com/jasmine/jasmine/issues/1759)
|
||||
|
||||
|
||||
## Documentation updates
|
||||
|
||||
* Updated package description
|
||||
|
||||
* Updated contributing guide
|
||||
|
||||
* Added TypeScript typings and jasmine-browser-runner to issue template
|
||||
|
||||
* Removed constructors from jsdocs of classes that aren't user-constructable
|
||||
|
||||
* Fixed config.seed type in jsdocs
|
||||
* Merges [#1892](https://github.com/jasmine/jasmine/pull/1892) from @UziTech
|
||||
|
||||
* Added jsdocs for the following:
|
||||
* asymmetric equality testers
|
||||
* Env#execute
|
||||
* Env#allowRespy
|
||||
* The public portion of Spec
|
||||
* Spy.callData.returnValue
|
||||
* Env#topSuite and Suite
|
||||
|
||||
* Added a jsdoc cross-reference from Configuration to its usage
|
||||
|
||||
* Added a note about correct usage of async matchers
|
||||
|
||||
* Added support for ArrayBuffers to matchersUtil.equals
|
||||
* Merges [#1891](https://github.com/jasmine/jasmine/pull/1892) from @Finesse
|
||||
* Merges [#1689](https://github.com/jasmine/jasmine/pull/1892) from @dankurka
|
||||
* Fixes [#1687](https://github.com/jasmine/jasmine/issues/1687)
|
||||
|
||||
|
||||
## Internal notes
|
||||
|
||||
* Fixed typo in spec name
|
||||
* Merges [#1918](https://github.com/jasmine/jasmine/pull/1918) from @eltociear
|
||||
|
||||
* Specify files to include in the NPM package rather than files to exclude
|
||||
|
||||
* Added test coverage for MatchersUtil#equals with typed arrays
|
||||
|
||||
* Removed checks for typed array support in the test suite
|
||||
* All supported browsers have all typed arrays except for Uint8ClampedArray,
|
||||
BigInt64Array, and BigUint64Array.
|
||||
|
||||
* Fixed test failures on IE 10
|
||||
|
||||
* Test matrix updates
|
||||
* Added Node 16
|
||||
* Added Safari 14
|
||||
* Added Firefox 78 (closest match to current ESR)
|
||||
* Removed Safari 10-12 to speed up CI. The newer and older versions we test
|
||||
provide a good measure of safety.
|
||||
|
||||
* Replaced node-sass dev dependency that isn't compatible with Node 16
|
||||
|
||||
* Removed unused dev dependencies
|
||||
|
||||
* Migrated CI from Travis to Circle
|
||||
|
||||
* Compensate for clock jitter in specs
|
||||
|
||||
|
||||
## Supported environments
|
||||
|
||||
jasmine-core 3.8.0 has been tested in the following environments.
|
||||
|
||||
| Environment | Supported versions |
|
||||
|-------------------|--------------------|
|
||||
| Node | 10, 12, 14, 16 |
|
||||
| Safari | 8-14 |
|
||||
| Chrome | 91 |
|
||||
| Firefox | 89, 68, 78 |
|
||||
| Edge | 91 |
|
||||
| Internet Explorer | 10, 11 |
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_
|
||||
65
release_notes/3.9.0.md
Normal file
65
release_notes/3.9.0.md
Normal file
@@ -0,0 +1,65 @@
|
||||
# Jasmine Core 3.9 Release Notes
|
||||
|
||||
## New features and bug fixes
|
||||
|
||||
* Fixed Trusted Types error in `j$.isError_` in Chromium-based browsers
|
||||
* Merges [#1921](https://github.com/jasmine/jasmine/pull/1921) from @bjarkler
|
||||
* Fixes [#1910](https://github.com/jasmine/jasmine/issues/1910)
|
||||
* Fixes [#1653](https://github.com/jasmine/jasmine/issues/1653)
|
||||
|
||||
* Better reporting of unhandled promise rejections with truthy but non-`Error`
|
||||
reasons on Node
|
||||
* `Env#execute` returns a promise in environments that support promises
|
||||
* Renamed `failFast` and `oneFailurePerSpec` config props to `stopOnSpecFailure`
|
||||
and `stopSpecOnExpectationFailure`
|
||||
|
||||
The new names are more self-explanatory and consistent with jasmine-npm. The
|
||||
old names are deprecated but will still work until the next major release.
|
||||
|
||||
* Split `boot.js` into two files to allow the env to be configured in between
|
||||
|
||||
This is mainly intended to support jasmine-browser-runner, which will load
|
||||
a script that configures the env in between the two boot files (`boot0.js` and
|
||||
`boot1.js`). The single-file `boot.js` will still be included until the next
|
||||
major release.
|
||||
|
||||
## Ruby deprecation
|
||||
|
||||
The Jasmine Ruby gems are deprecated. There will be no further releases after
|
||||
the end of the Jasmine 3.x series. We recommend that most users migrate to the
|
||||
[jasmine-browser-runner](https://github.com/jasmine/jasmine-browser)
|
||||
npm package, which is the direct replacement for the `jasmine` gem.
|
||||
|
||||
If `jasmine-browser-runner` doesn't meet your needs, one of these might:
|
||||
|
||||
* The [jasmine](https://github.com/jasmine/jasmine-npm) npm package to run
|
||||
specs in Node.js.
|
||||
* The [standalone distribution](https://github.com/jasmine/jasmine#installation)
|
||||
to run specs in browsers with no additional tools.
|
||||
* The [jasmine-core](https://github.com/jasmine/jasmine) npm package if all
|
||||
you need is the Jasmine assets. This is the direct equivalent of the
|
||||
`jasmine-core` Ruby gem.
|
||||
|
||||
## Documentation updates
|
||||
|
||||
* Added API docs for `Suite#id` and `Spec#id`
|
||||
* Marked `Env#hideDisabled` deprecated in jsdocs
|
||||
|
||||
|
||||
------
|
||||
|
||||
## Supported environments
|
||||
|
||||
jasmine-core 3.9.0 has been tested in the following environments.
|
||||
|
||||
| Environment | Supported versions |
|
||||
|-------------------|--------------------|
|
||||
| Node | 10, 12, 14, 16 |
|
||||
| Safari | 8-14 |
|
||||
| Chrome | 92 |
|
||||
| Firefox | 91, 78, 68 |
|
||||
| Edge | 92 |
|
||||
| Internet Explorer | 10, 11 |
|
||||
|
||||
|
||||
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_
|
||||
43
scripts/run-all-browsers
Executable file
43
scripts/run-all-browsers
Executable file
@@ -0,0 +1,43 @@
|
||||
#!/bin/sh
|
||||
|
||||
run_browser() {
|
||||
browser=$1
|
||||
version=$2
|
||||
description="$browser $version"
|
||||
if [ $version = "latest" ]; then
|
||||
version=""
|
||||
fi
|
||||
|
||||
echo
|
||||
echo
|
||||
echo "Running $description"
|
||||
echo
|
||||
USE_SAUCE=true JASMINE_BROWSER=$browser SAUCE_BROWSER_VERSION=$version npm run ci
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "PASS: $description" >> "$passfile"
|
||||
else
|
||||
echo "FAIL: $description" >> "$failfile"
|
||||
fi
|
||||
}
|
||||
|
||||
passfile=`mktemp -t jasmine-results.XXXXXX` || exit 1
|
||||
failfile=`mktemp -t jasmine-results.XXXXXX` || exit 1
|
||||
run_browser "internet explorer" 11
|
||||
run_browser "internet explorer" 10
|
||||
run_browser chrome latest
|
||||
run_browser firefox latest
|
||||
run_browser firefox 78
|
||||
run_browser firefox 68
|
||||
run_browser safari 14
|
||||
run_browser safari 13
|
||||
run_browser safari 9
|
||||
run_browser safari 8
|
||||
run_browser MicrosoftEdge latest
|
||||
|
||||
echo
|
||||
cat "$passfile" "$failfile"
|
||||
|
||||
if [ -s "$failfile" ]; then
|
||||
exit 1
|
||||
fi
|
||||
37
scripts/start-sauce-connect
Executable file
37
scripts/start-sauce-connect
Executable file
@@ -0,0 +1,37 @@
|
||||
#!/usr/bin/env bash
|
||||
set -o errexit
|
||||
set -o pipefail
|
||||
|
||||
if [ $# -gt 1 -o "$1" = "--help" ]; then
|
||||
echo "Usage: $0 [pidfile]" 1>&2
|
||||
exit
|
||||
fi
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
pidfile=`mktemp`
|
||||
else
|
||||
pidfile="$1"
|
||||
fi
|
||||
|
||||
outfile=`mktemp`
|
||||
echo "Starting Sauce Connect"
|
||||
if [ -z "$SAUCE_TUNNEL_IDENTIFIER" ]; then
|
||||
sc -u "$SAUCE_USERNAME" -k "$SAUCE_ACCESS_KEY" -X 4445 --pidfile "$pidfile" 2>&1 | tee "$outfile" &
|
||||
else
|
||||
sc -u "$SAUCE_USERNAME" -k "$SAUCE_ACCESS_KEY" -X 4445 --pidfile "$pidfile" -i "$SAUCE_TUNNEL_IDENTIFIER" 2>&1 | tee "$outfile" &
|
||||
fi
|
||||
|
||||
while ! fgrep "Sauce Connect is up, you may start your tests." "$outfile" > /dev/null; do
|
||||
sleep 1
|
||||
|
||||
if ! ps -p $(cat "$pidfile") > /dev/null; then
|
||||
echo "Sauce Connect exited"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
if ! nc -z localhost 4445; then
|
||||
echo "Can't connect to Sauce tunnel"
|
||||
killall sc
|
||||
exit 1
|
||||
fi
|
||||
33
scripts/stop-sauce-connect
Executable file
33
scripts/stop-sauce-connect
Executable file
@@ -0,0 +1,33 @@
|
||||
#!/usr/bin/env bash
|
||||
set -o errexit
|
||||
set -o pipefail
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
echo "Usage: $0 sauce-connect-pid" 1>&2
|
||||
exit
|
||||
fi
|
||||
|
||||
pid="$1"
|
||||
echo "PID: $pid"
|
||||
|
||||
echo "Stopping Sauce Connect"
|
||||
# Sauce Connect docs say that we can just kill -9 it if we don't care about
|
||||
# failing any ongoing sessions. In practice, that sometimes works but usually
|
||||
# leaks a tunnel so badly that you can't even stop it from the web UI.
|
||||
# Instead of doing that, we give Sauce Connect some time to shut down
|
||||
# gracefully and then give up.
|
||||
kill -INT $pid
|
||||
|
||||
# Wait up to 2 minutes, then give up if it's still running
|
||||
n=0
|
||||
while [ $n -lt 120 ] && ps -p $pid > /dev/null; do
|
||||
sleep 1
|
||||
kill -INT $pid 2> /dev/null || true
|
||||
n=$(($n + 1))
|
||||
done
|
||||
|
||||
if ps -p $pid > /dev/null; then
|
||||
echo "Could not shut down Sauce Connect"
|
||||
fi
|
||||
|
||||
exit $exitcode
|
||||
35
setup.py
35
setup.py
@@ -4,15 +4,41 @@ import json
|
||||
with open('package.json') as packageFile:
|
||||
version = json.load(packageFile)['version']
|
||||
|
||||
short_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.')
|
||||
deprecation=('The Jasmine packages for Python are deprecated. There will be no further\n' +
|
||||
'releases after the end of the Jasmine 3.x series. We recommend migrating to the\n' +
|
||||
'following options:\n' +
|
||||
'\n' +
|
||||
'* jasmine-browser-runner (<https://github.com/jasmine/jasmine-browser>,\n' +
|
||||
' `npm install jasmine-browser-runner`) to run specs in browsers, including\n' +
|
||||
' headless Chrome and Saucelabs. This is the most direct replacement for the\n' +
|
||||
' jasmine server` and `jasmine ci` commands provided by the `jasmine` Python\n' +
|
||||
' package.\n' +
|
||||
'* The jasmine npm package (<https://github.com/jasmine/jasmine-npm>,\n' +
|
||||
' `npm install jasmine`) to run specs under Node.js.\n' +
|
||||
'* The standalone distribution from the latest Jasmine release\n' +
|
||||
' <https://github.com/jasmine/jasmine/releases> to run specs in browsers with\n' +
|
||||
' no additional tools.\n' +
|
||||
'* The jasmine-core npm package (`npm install jasmine-core`) if all you need is\n' +
|
||||
' the Jasmine assets. This is the direct equivalent of the jasmine-core Python\n' +
|
||||
' package.\n' +
|
||||
'\n' +
|
||||
'Except for the standalone distribution, all of the above are distributed through\n'
|
||||
'npm.\n')
|
||||
long_description = short_description + '\n\n' + deprecation
|
||||
|
||||
|
||||
setup(
|
||||
name="jasmine-core",
|
||||
version=version,
|
||||
url="http://jasmine.github.io",
|
||||
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.'),
|
||||
description=short_description,
|
||||
long_description=long_description,
|
||||
long_description_content_type='text/plain',
|
||||
license='MIT',
|
||||
classifiers=[
|
||||
'Development Status :: 5 - Production/Stable',
|
||||
@@ -23,9 +49,6 @@ setup(
|
||||
'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',
|
||||
|
||||
20
spec/.eslintrc.js
Normal file
20
spec/.eslintrc.js
Normal file
@@ -0,0 +1,20 @@
|
||||
module.exports = {
|
||||
ignorePatterns: ['support/ci.js', 'support/jasmine-browser.js'],
|
||||
rules: {
|
||||
// Relax rules for now to allow for the quirks of the test suite
|
||||
// TODO: We should probably remove these & fix the resulting errors
|
||||
quotes: 'off',
|
||||
semi: 'off',
|
||||
'key-spacing': 'off',
|
||||
'space-before-blocks': 'off',
|
||||
'no-unused-vars': 'off',
|
||||
'no-trailing-spaces': 'off',
|
||||
'block-spacing': 'off',
|
||||
|
||||
// Since linting is done at the end of the process and doesn't stop us
|
||||
// from running tests, it makes sense to fail if debugger statements
|
||||
// or console references are present.
|
||||
'no-debugger': 'error',
|
||||
'no-console': 'error'
|
||||
}
|
||||
};
|
||||
@@ -1,270 +0,0 @@
|
||||
describe("ConsoleReporter", function() {
|
||||
var out;
|
||||
|
||||
beforeEach(function() {
|
||||
out = (function() {
|
||||
var output = "";
|
||||
return {
|
||||
print: function(str) {
|
||||
output += str;
|
||||
},
|
||||
getOutput: function() {
|
||||
return output.replace('ConsoleReporter is deprecated and will be removed in a future version.', '');
|
||||
},
|
||||
clear: function() {
|
||||
output = "";
|
||||
}
|
||||
};
|
||||
}());
|
||||
});
|
||||
|
||||
it("reports that the suite has started to the console", function() {
|
||||
var reporter = new jasmineUnderTest.ConsoleReporter({
|
||||
print: out.print
|
||||
});
|
||||
|
||||
reporter.jasmineStarted();
|
||||
|
||||
expect(out.getOutput()).toEqual("Started\n");
|
||||
});
|
||||
|
||||
it("starts the provided timer when jasmine starts", function() {
|
||||
var timerSpy = jasmine.createSpyObj('timer', ['start']),
|
||||
reporter = new jasmineUnderTest.ConsoleReporter({
|
||||
print: out.print,
|
||||
timer: timerSpy
|
||||
});
|
||||
|
||||
reporter.jasmineStarted();
|
||||
|
||||
expect(timerSpy.start).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("reports a passing spec as a dot", function() {
|
||||
var reporter = new jasmineUnderTest.ConsoleReporter({
|
||||
print: out.print
|
||||
});
|
||||
|
||||
reporter.specDone({status: "passed"});
|
||||
|
||||
expect(out.getOutput()).toEqual(".");
|
||||
});
|
||||
|
||||
it("does not report a disabled spec", function() {
|
||||
var reporter = new jasmineUnderTest.ConsoleReporter({
|
||||
print: out.print
|
||||
});
|
||||
|
||||
reporter.specDone({status: "disabled"});
|
||||
|
||||
expect(out.getOutput()).toEqual("");
|
||||
});
|
||||
|
||||
it("reports a failing spec as an 'F'", function() {
|
||||
var reporter = new jasmineUnderTest.ConsoleReporter({
|
||||
print: out.print
|
||||
});
|
||||
|
||||
reporter.specDone({status: "failed"});
|
||||
|
||||
expect(out.getOutput()).toEqual("F");
|
||||
});
|
||||
|
||||
it("reports a pending spec as a '*'", function() {
|
||||
var reporter = new jasmineUnderTest.ConsoleReporter({
|
||||
print: out.print
|
||||
});
|
||||
|
||||
reporter.specDone({status: "pending"});
|
||||
|
||||
expect(out.getOutput()).toEqual("*");
|
||||
});
|
||||
|
||||
it("alerts user if there are no specs", function(){
|
||||
var reporter = new jasmineUnderTest.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 jasmineUnderTest.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 jasmineUnderTest.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 jasmineUnderTest.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() {
|
||||
onComplete = jasmine.createSpy('onComplete');
|
||||
reporter = new jasmineUnderTest.ConsoleReporter({
|
||||
print: out.print,
|
||||
onComplete: onComplete
|
||||
});
|
||||
reporter.jasmineStarted();
|
||||
});
|
||||
|
||||
it("is called when the suite is done", function() {
|
||||
reporter.jasmineDone();
|
||||
expect(onComplete).toHaveBeenCalledWith(true);
|
||||
});
|
||||
|
||||
it('calls it with false if there are spec failures', function() {
|
||||
reporter.specDone({status: "failed", failedExpectations: []});
|
||||
reporter.jasmineDone();
|
||||
expect(onComplete).toHaveBeenCalledWith(false);
|
||||
});
|
||||
|
||||
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 jasmineUnderTest.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 jasmineUnderTest.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 jasmineUnderTest.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 jasmineUnderTest.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 jasmineUnderTest.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/);
|
||||
});
|
||||
});
|
||||
});
|
||||
849
spec/core/AsyncExpectationSpec.js
Normal file
849
spec/core/AsyncExpectationSpec.js
Normal file
@@ -0,0 +1,849 @@
|
||||
/* eslint-disable compat/compat */
|
||||
describe('AsyncExpectation', function() {
|
||||
beforeEach(function() {
|
||||
jasmineUnderTest.Expectation.addAsyncCoreMatchers(
|
||||
jasmineUnderTest.asyncMatchers
|
||||
);
|
||||
});
|
||||
|
||||
describe('Factory', function() {
|
||||
it('throws an Error if promises are not available', function() {
|
||||
var thenable = { then: function() {} },
|
||||
options = { global: {}, actual: thenable };
|
||||
function f() {
|
||||
jasmineUnderTest.Expectation.asyncFactory(options);
|
||||
}
|
||||
expect(f).toThrowError(
|
||||
'expectAsync is unavailable because the environment does not support promises.'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#not', function() {
|
||||
it('converts a pass to a fail', function() {
|
||||
jasmine.getEnv().requirePromises();
|
||||
|
||||
var addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||
actual = Promise.resolve(),
|
||||
pp = jasmineUnderTest.makePrettyPrinter(),
|
||||
expectation = jasmineUnderTest.Expectation.asyncFactory({
|
||||
matchersUtil: new jasmineUnderTest.MatchersUtil({ pp: pp }),
|
||||
actual: actual,
|
||||
addExpectationResult: addExpectationResult
|
||||
});
|
||||
|
||||
return expectation.not.toBeResolved().then(function() {
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(
|
||||
false,
|
||||
jasmine.objectContaining({
|
||||
passed: false,
|
||||
message: 'Expected [object Promise] not to be resolved.'
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('converts a fail to a pass', function() {
|
||||
jasmine.getEnv().requirePromises();
|
||||
|
||||
var addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||
actual = Promise.reject(),
|
||||
expectation = jasmineUnderTest.Expectation.asyncFactory({
|
||||
matchersUtil: new jasmineUnderTest.MatchersUtil({
|
||||
pp: function() {}
|
||||
}),
|
||||
actual: actual,
|
||||
addExpectationResult: addExpectationResult
|
||||
});
|
||||
|
||||
return expectation.not.toBeResolved().then(function() {
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(
|
||||
true,
|
||||
jasmine.objectContaining({
|
||||
passed: true,
|
||||
message: ''
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('propagates rejections from the comparison function', function() {
|
||||
jasmine.getEnv().requirePromises();
|
||||
var error = new Error('ExpectationSpec failure');
|
||||
|
||||
var addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||
actual = dummyPromise(),
|
||||
expectation = jasmineUnderTest.Expectation.asyncFactory({
|
||||
actual: actual,
|
||||
addExpectationResult: addExpectationResult
|
||||
});
|
||||
|
||||
spyOn(expectation, 'toBeResolved').and.returnValue(Promise.reject(error));
|
||||
|
||||
return expectation.toBeResolved().then(
|
||||
function() {
|
||||
fail('Expected a rejection');
|
||||
},
|
||||
function(e) {
|
||||
expect(e).toBe(error);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
describe('#withContext', function() {
|
||||
it('prepends the context to the generated failure message', function() {
|
||||
jasmine.getEnv().requirePromises();
|
||||
|
||||
var matchersUtil = {
|
||||
pp: function(val) {
|
||||
return val.toString();
|
||||
}
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||
expectation = jasmineUnderTest.Expectation.asyncFactory({
|
||||
actual: Promise.reject('rejected'),
|
||||
addExpectationResult: addExpectationResult,
|
||||
matchersUtil: matchersUtil
|
||||
});
|
||||
|
||||
return expectation
|
||||
.withContext('Some context')
|
||||
.toBeResolved()
|
||||
.then(function() {
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(
|
||||
false,
|
||||
jasmine.objectContaining({
|
||||
message:
|
||||
'Some context: Expected a promise to be resolved but it was rejected with rejected.'
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('prepends the context to a custom failure message', function() {
|
||||
jasmine.getEnv().requirePromises();
|
||||
|
||||
var matchersUtil = {
|
||||
buildFailureMessage: function() {
|
||||
return 'failure message';
|
||||
},
|
||||
pp: jasmineUnderTest.makePrettyPrinter()
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||
expectation = jasmineUnderTest.Expectation.asyncFactory({
|
||||
actual: Promise.reject('b'),
|
||||
addExpectationResult: addExpectationResult,
|
||||
matchersUtil: matchersUtil
|
||||
});
|
||||
|
||||
return expectation
|
||||
.withContext('Some context')
|
||||
.toBeResolvedTo('a')
|
||||
.then(function() {
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(
|
||||
false,
|
||||
jasmine.objectContaining({
|
||||
message:
|
||||
"Some context: Expected a promise to be resolved to 'a' " +
|
||||
"but it was rejected with 'b'."
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('prepends the context to a custom failure message from a function', function() {
|
||||
pending('should actually work, but no custom matchers for async yet');
|
||||
jasmine.getEnv().requirePromises();
|
||||
|
||||
var matchersUtil = {
|
||||
buildFailureMessage: function() {
|
||||
return 'failure message';
|
||||
}
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||
actual = Promise.reject(),
|
||||
expectation = jasmineUnderTest.Expectation.asyncFactory({
|
||||
actual: actual,
|
||||
addExpectationResult: addExpectationResult,
|
||||
matchersUtil: matchersUtil
|
||||
});
|
||||
|
||||
return expectation
|
||||
.withContext('Some context')
|
||||
.toBeResolved()
|
||||
.then(function() {
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(
|
||||
false,
|
||||
jasmine.objectContaining({
|
||||
message: 'Some context: msg'
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('works with #not', function() {
|
||||
jasmine.getEnv().requirePromises();
|
||||
|
||||
var addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||
actual = Promise.resolve(),
|
||||
pp = jasmineUnderTest.makePrettyPrinter(),
|
||||
expectation = jasmineUnderTest.Expectation.asyncFactory({
|
||||
actual: actual,
|
||||
addExpectationResult: addExpectationResult,
|
||||
matchersUtil: new jasmineUnderTest.MatchersUtil({ pp: pp })
|
||||
});
|
||||
|
||||
return expectation
|
||||
.withContext('Some context')
|
||||
.not.toBeResolved()
|
||||
.then(function() {
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(
|
||||
false,
|
||||
jasmine.objectContaining({
|
||||
message:
|
||||
'Some context: Expected [object Promise] not to be resolved.'
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('works with #not and a custom message', function() {
|
||||
jasmine.getEnv().requirePromises();
|
||||
|
||||
var addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||
actual = Promise.resolve('a'),
|
||||
expectation = jasmineUnderTest.Expectation.asyncFactory({
|
||||
actual: actual,
|
||||
addExpectationResult: addExpectationResult,
|
||||
matchersUtil: new jasmineUnderTest.MatchersUtil({
|
||||
pp: jasmineUnderTest.makePrettyPrinter()
|
||||
})
|
||||
});
|
||||
|
||||
return expectation
|
||||
.withContext('Some context')
|
||||
.not.toBeResolvedTo('a')
|
||||
.then(function() {
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(
|
||||
false,
|
||||
jasmine.objectContaining({
|
||||
message:
|
||||
"Some context: Expected a promise not to be resolved to 'a'."
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('async matchers', function() {
|
||||
it('makes custom matchers available to this expectation', function() {
|
||||
jasmine.getEnv().requirePromises();
|
||||
|
||||
var asyncMatchers = {
|
||||
toFoo: function() {},
|
||||
toBar: function() {}
|
||||
},
|
||||
expectation;
|
||||
|
||||
expectation = jasmineUnderTest.Expectation.asyncFactory({
|
||||
customAsyncMatchers: asyncMatchers
|
||||
});
|
||||
|
||||
expect(expectation.toFoo).toBeDefined();
|
||||
expect(expectation.toBar).toBeDefined();
|
||||
});
|
||||
|
||||
it("wraps matchers's compare functions, passing in matcher dependencies", function() {
|
||||
jasmine.getEnv().requirePromises();
|
||||
|
||||
var fakeCompare = function() {
|
||||
return Promise.resolve({ pass: true });
|
||||
},
|
||||
matcherFactory = jasmine
|
||||
.createSpy('matcher')
|
||||
.and.returnValue({ compare: fakeCompare }),
|
||||
matchers = {
|
||||
toFoo: matcherFactory
|
||||
},
|
||||
matchersUtil = {
|
||||
buildFailureMessage: jasmine.createSpy('buildFailureMessage')
|
||||
},
|
||||
customEqualityTesters = ['a'],
|
||||
addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||
expectation;
|
||||
|
||||
expectation = jasmineUnderTest.Expectation.asyncFactory({
|
||||
matchersUtil: matchersUtil,
|
||||
customAsyncMatchers: matchers,
|
||||
customEqualityTesters: customEqualityTesters,
|
||||
actual: 'an actual',
|
||||
addExpectationResult: addExpectationResult
|
||||
});
|
||||
|
||||
return expectation.toFoo('hello').then(function() {
|
||||
expect(matcherFactory).toHaveBeenCalledWith(
|
||||
matchersUtil,
|
||||
customEqualityTesters
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it("wraps matchers's compare functions, passing the actual and expected", function() {
|
||||
jasmine.getEnv().requirePromises();
|
||||
|
||||
var fakeCompare = jasmine
|
||||
.createSpy('fake-compare')
|
||||
.and.returnValue(Promise.resolve({ pass: true })),
|
||||
matchers = {
|
||||
toFoo: function() {
|
||||
return {
|
||||
compare: fakeCompare
|
||||
};
|
||||
}
|
||||
},
|
||||
matchersUtil = {
|
||||
buildFailureMessage: jasmine.createSpy('buildFailureMessage')
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||
expectation;
|
||||
|
||||
expectation = jasmineUnderTest.Expectation.asyncFactory({
|
||||
matchersUtil: matchersUtil,
|
||||
customAsyncMatchers: matchers,
|
||||
actual: 'an actual',
|
||||
addExpectationResult: addExpectationResult
|
||||
});
|
||||
|
||||
return expectation.toFoo('hello').then(function() {
|
||||
expect(fakeCompare).toHaveBeenCalledWith('an actual', 'hello');
|
||||
});
|
||||
});
|
||||
|
||||
it('reports a passing result to the spec when the comparison passes', function() {
|
||||
jasmine.getEnv().requirePromises();
|
||||
|
||||
var matchers = {
|
||||
toFoo: function() {
|
||||
return {
|
||||
compare: function() {
|
||||
return Promise.resolve({ pass: true });
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
matchersUtil = {
|
||||
buildFailureMessage: jasmine.createSpy('buildFailureMessage')
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||
errorWithStack = new Error('errorWithStack'),
|
||||
expectation;
|
||||
|
||||
spyOn(jasmineUnderTest.util, 'errorWithStack').and.returnValue(
|
||||
errorWithStack
|
||||
);
|
||||
|
||||
expectation = jasmineUnderTest.Expectation.asyncFactory({
|
||||
customAsyncMatchers: matchers,
|
||||
matchersUtil: matchersUtil,
|
||||
actual: 'an actual',
|
||||
addExpectationResult: addExpectationResult
|
||||
});
|
||||
|
||||
return expectation.toFoo('hello').then(function() {
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(true, {
|
||||
matcherName: 'toFoo',
|
||||
passed: true,
|
||||
message: '',
|
||||
error: undefined,
|
||||
expected: 'hello',
|
||||
actual: 'an actual',
|
||||
errorForStack: errorWithStack
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('reports a failing result to the spec when the comparison fails', function() {
|
||||
jasmine.getEnv().requirePromises();
|
||||
|
||||
var matchers = {
|
||||
toFoo: function() {
|
||||
return {
|
||||
compare: function() {
|
||||
return Promise.resolve({ pass: false });
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
matchersUtil = {
|
||||
buildFailureMessage: function() {
|
||||
return '';
|
||||
}
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||
errorWithStack = new Error('errorWithStack'),
|
||||
expectation;
|
||||
|
||||
spyOn(jasmineUnderTest.util, 'errorWithStack').and.returnValue(
|
||||
errorWithStack
|
||||
);
|
||||
|
||||
expectation = jasmineUnderTest.Expectation.asyncFactory({
|
||||
customAsyncMatchers: matchers,
|
||||
matchersUtil: matchersUtil,
|
||||
actual: 'an actual',
|
||||
addExpectationResult: addExpectationResult
|
||||
});
|
||||
|
||||
return expectation.toFoo('hello').then(function() {
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(false, {
|
||||
matcherName: 'toFoo',
|
||||
passed: false,
|
||||
expected: 'hello',
|
||||
actual: 'an actual',
|
||||
message: '',
|
||||
error: undefined,
|
||||
errorForStack: errorWithStack
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('reports a failing result and a custom fail message to the spec when the comparison fails', function() {
|
||||
jasmine.getEnv().requirePromises();
|
||||
|
||||
var matchers = {
|
||||
toFoo: function() {
|
||||
return {
|
||||
compare: function() {
|
||||
return Promise.resolve({
|
||||
pass: false,
|
||||
message: 'I am a custom message'
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||
errorWithStack = new Error('errorWithStack'),
|
||||
expectation;
|
||||
|
||||
spyOn(jasmineUnderTest.util, 'errorWithStack').and.returnValue(
|
||||
errorWithStack
|
||||
);
|
||||
|
||||
expectation = jasmineUnderTest.Expectation.asyncFactory({
|
||||
actual: 'an actual',
|
||||
customAsyncMatchers: matchers,
|
||||
addExpectationResult: addExpectationResult
|
||||
});
|
||||
|
||||
return expectation.toFoo('hello').then(function() {
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(false, {
|
||||
matcherName: 'toFoo',
|
||||
passed: false,
|
||||
expected: 'hello',
|
||||
actual: 'an actual',
|
||||
message: 'I am a custom message',
|
||||
error: undefined,
|
||||
errorForStack: errorWithStack
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('reports a failing result with a custom fail message function to the spec when the comparison fails', function() {
|
||||
jasmine.getEnv().requirePromises();
|
||||
|
||||
var matchers = {
|
||||
toFoo: function() {
|
||||
return {
|
||||
compare: function() {
|
||||
return Promise.resolve({
|
||||
pass: false,
|
||||
message: function() {
|
||||
return 'I am a custom message';
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||
errorWithStack = new Error('errorWithStack'),
|
||||
expectation;
|
||||
|
||||
spyOn(jasmineUnderTest.util, 'errorWithStack').and.returnValue(
|
||||
errorWithStack
|
||||
);
|
||||
|
||||
expectation = jasmineUnderTest.Expectation.asyncFactory({
|
||||
customAsyncMatchers: matchers,
|
||||
actual: 'an actual',
|
||||
addExpectationResult: addExpectationResult
|
||||
});
|
||||
|
||||
return expectation.toFoo('hello').then(function() {
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(false, {
|
||||
matcherName: 'toFoo',
|
||||
passed: false,
|
||||
expected: 'hello',
|
||||
actual: 'an actual',
|
||||
message: 'I am a custom message',
|
||||
error: undefined,
|
||||
errorForStack: errorWithStack
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('reports a passing result to the spec when the comparison fails for a negative expectation', function() {
|
||||
jasmine.getEnv().requirePromises();
|
||||
|
||||
var matchers = {
|
||||
toFoo: function() {
|
||||
return {
|
||||
compare: function() {
|
||||
return Promise.resolve({ pass: false });
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||
actual = 'an actual',
|
||||
errorWithStack = new Error('errorWithStack'),
|
||||
expectation;
|
||||
|
||||
spyOn(jasmineUnderTest.util, 'errorWithStack').and.returnValue(
|
||||
errorWithStack
|
||||
);
|
||||
|
||||
expectation = jasmineUnderTest.Expectation.asyncFactory({
|
||||
customAsyncMatchers: matchers,
|
||||
actual: 'an actual',
|
||||
addExpectationResult: addExpectationResult
|
||||
}).not;
|
||||
|
||||
return expectation.toFoo('hello').then(function() {
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(true, {
|
||||
matcherName: 'toFoo',
|
||||
passed: true,
|
||||
message: '',
|
||||
error: undefined,
|
||||
expected: 'hello',
|
||||
actual: actual,
|
||||
errorForStack: errorWithStack
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('reports a failing result to the spec when the comparison passes for a negative expectation', function() {
|
||||
jasmine.getEnv().requirePromises();
|
||||
|
||||
var matchers = {
|
||||
toFoo: function() {
|
||||
return {
|
||||
compare: function() {
|
||||
return Promise.resolve({ pass: true });
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
matchersUtil = {
|
||||
buildFailureMessage: function() {
|
||||
return 'default message';
|
||||
}
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||
actual = 'an actual',
|
||||
errorWithStack = new Error('errorWithStack'),
|
||||
expectation;
|
||||
|
||||
spyOn(jasmineUnderTest.util, 'errorWithStack').and.returnValue(
|
||||
errorWithStack
|
||||
);
|
||||
|
||||
expectation = jasmineUnderTest.Expectation.asyncFactory({
|
||||
customAsyncMatchers: matchers,
|
||||
actual: 'an actual',
|
||||
matchersUtil: matchersUtil,
|
||||
addExpectationResult: addExpectationResult
|
||||
}).not;
|
||||
|
||||
return expectation.toFoo('hello').then(function() {
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(false, {
|
||||
matcherName: 'toFoo',
|
||||
passed: false,
|
||||
expected: 'hello',
|
||||
actual: actual,
|
||||
message: 'default message',
|
||||
error: undefined,
|
||||
errorForStack: errorWithStack
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('reports a failing result and a custom fail message to the spec when the comparison passes for a negative expectation', function() {
|
||||
jasmine.getEnv().requirePromises();
|
||||
|
||||
var matchers = {
|
||||
toFoo: function() {
|
||||
return {
|
||||
compare: function() {
|
||||
return Promise.resolve({
|
||||
pass: true,
|
||||
message: 'I am a custom message'
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||
actual = 'an actual',
|
||||
errorWithStack = new Error('errorWithStack'),
|
||||
expectation;
|
||||
|
||||
spyOn(jasmineUnderTest.util, 'errorWithStack').and.returnValue(
|
||||
errorWithStack
|
||||
);
|
||||
|
||||
expectation = jasmineUnderTest.Expectation.asyncFactory({
|
||||
customAsyncMatchers: matchers,
|
||||
actual: 'an actual',
|
||||
addExpectationResult: addExpectationResult
|
||||
}).not;
|
||||
|
||||
return expectation.toFoo('hello').then(function() {
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(false, {
|
||||
matcherName: 'toFoo',
|
||||
passed: false,
|
||||
expected: 'hello',
|
||||
actual: actual,
|
||||
message: 'I am a custom message',
|
||||
error: undefined,
|
||||
errorForStack: errorWithStack
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("reports a passing result to the spec when the 'not' comparison passes, given a negativeCompare", function() {
|
||||
jasmine.getEnv().requirePromises();
|
||||
|
||||
var matchers = {
|
||||
toFoo: function() {
|
||||
return {
|
||||
compare: function() {
|
||||
return Promise.resolve({ pass: true });
|
||||
},
|
||||
negativeCompare: function() {
|
||||
return Promise.resolve({ pass: true });
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||
actual = 'an actual',
|
||||
errorWithStack = new Error('errorWithStack'),
|
||||
expectation;
|
||||
|
||||
spyOn(jasmineUnderTest.util, 'errorWithStack').and.returnValue(
|
||||
errorWithStack
|
||||
);
|
||||
|
||||
expectation = jasmineUnderTest.Expectation.asyncFactory({
|
||||
customAsyncMatchers: matchers,
|
||||
actual: 'an actual',
|
||||
addExpectationResult: addExpectationResult
|
||||
}).not;
|
||||
|
||||
return expectation.toFoo('hello').then(function() {
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(true, {
|
||||
matcherName: 'toFoo',
|
||||
passed: true,
|
||||
expected: 'hello',
|
||||
actual: actual,
|
||||
message: '',
|
||||
error: undefined,
|
||||
errorForStack: errorWithStack
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("reports a failing result and a custom fail message to the spec when the 'not' comparison fails, given a negativeCompare", function() {
|
||||
jasmine.getEnv().requirePromises();
|
||||
|
||||
var matchers = {
|
||||
toFoo: function() {
|
||||
return {
|
||||
compare: function() {
|
||||
return Promise.resolve({ pass: true });
|
||||
},
|
||||
negativeCompare: function() {
|
||||
return Promise.resolve({
|
||||
pass: false,
|
||||
message: "I'm a custom message"
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||
actual = 'an actual',
|
||||
errorWithStack = new Error('errorWithStack'),
|
||||
expectation;
|
||||
|
||||
spyOn(jasmineUnderTest.util, 'errorWithStack').and.returnValue(
|
||||
errorWithStack
|
||||
);
|
||||
|
||||
expectation = jasmineUnderTest.Expectation.asyncFactory({
|
||||
customAsyncMatchers: matchers,
|
||||
actual: 'an actual',
|
||||
addExpectationResult: addExpectationResult
|
||||
}).not;
|
||||
|
||||
return expectation.toFoo('hello').then(function() {
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(false, {
|
||||
matcherName: 'toFoo',
|
||||
passed: false,
|
||||
expected: 'hello',
|
||||
actual: actual,
|
||||
message: "I'm a custom message",
|
||||
error: undefined,
|
||||
errorForStack: errorWithStack
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('reports errorWithStack when a custom error message is returned', function() {
|
||||
jasmine.getEnv().requirePromises();
|
||||
|
||||
var customError = new Error('I am a custom error');
|
||||
var matchers = {
|
||||
toFoo: function() {
|
||||
return {
|
||||
compare: function() {
|
||||
return Promise.resolve({
|
||||
pass: false,
|
||||
message: 'I am a custom message',
|
||||
error: customError
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||
errorWithStack = new Error('errorWithStack'),
|
||||
expectation;
|
||||
|
||||
spyOn(jasmineUnderTest.util, 'errorWithStack').and.returnValue(
|
||||
errorWithStack
|
||||
);
|
||||
|
||||
expectation = jasmineUnderTest.Expectation.asyncFactory({
|
||||
actual: 'an actual',
|
||||
customAsyncMatchers: matchers,
|
||||
addExpectationResult: addExpectationResult
|
||||
});
|
||||
|
||||
return expectation.toFoo('hello').then(function() {
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(false, {
|
||||
matcherName: 'toFoo',
|
||||
passed: false,
|
||||
expected: 'hello',
|
||||
actual: 'an actual',
|
||||
message: 'I am a custom message',
|
||||
error: undefined,
|
||||
errorForStack: errorWithStack
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("reports a custom message to the spec when a 'not' comparison fails", function() {
|
||||
jasmine.getEnv().requirePromises();
|
||||
|
||||
var matchers = {
|
||||
toFoo: function() {
|
||||
return {
|
||||
compare: function() {
|
||||
return Promise.resolve({
|
||||
pass: true,
|
||||
message: 'I am a custom message'
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||
errorWithStack = new Error('errorWithStack'),
|
||||
expectation;
|
||||
|
||||
spyOn(jasmineUnderTest.util, 'errorWithStack').and.returnValue(
|
||||
errorWithStack
|
||||
);
|
||||
|
||||
expectation = jasmineUnderTest.Expectation.asyncFactory({
|
||||
actual: 'an actual',
|
||||
customAsyncMatchers: matchers,
|
||||
addExpectationResult: addExpectationResult
|
||||
}).not;
|
||||
|
||||
return expectation.toFoo('hello').then(function() {
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(false, {
|
||||
matcherName: 'toFoo',
|
||||
passed: false,
|
||||
expected: 'hello',
|
||||
actual: 'an actual',
|
||||
message: 'I am a custom message',
|
||||
error: undefined,
|
||||
errorForStack: errorWithStack
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("reports a custom message func to the spec when a 'not' comparison fails", function() {
|
||||
jasmine.getEnv().requirePromises();
|
||||
|
||||
var matchers = {
|
||||
toFoo: function() {
|
||||
return {
|
||||
compare: function() {
|
||||
return Promise.resolve({
|
||||
pass: true,
|
||||
message: function() {
|
||||
return 'I am a custom message';
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||
errorWithStack = new Error('errorWithStack'),
|
||||
expectation;
|
||||
|
||||
spyOn(jasmineUnderTest.util, 'errorWithStack').and.returnValue(
|
||||
errorWithStack
|
||||
);
|
||||
|
||||
expectation = jasmineUnderTest.Expectation.asyncFactory({
|
||||
actual: 'an actual',
|
||||
customAsyncMatchers: matchers,
|
||||
addExpectationResult: addExpectationResult
|
||||
}).not;
|
||||
|
||||
return expectation.toFoo('hello').then(function() {
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(false, {
|
||||
matcherName: 'toFoo',
|
||||
passed: false,
|
||||
expected: 'hello',
|
||||
actual: 'an actual',
|
||||
message: 'I am a custom message',
|
||||
error: undefined,
|
||||
errorForStack: errorWithStack
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function dummyPromise() {
|
||||
return new Promise(function(resolve, reject) {});
|
||||
}
|
||||
});
|
||||
@@ -1,5 +1,5 @@
|
||||
describe("CallTracker", function() {
|
||||
it("tracks that it was called when executed", function() {
|
||||
describe('CallTracker', function() {
|
||||
it('tracks that it was called when executed', function() {
|
||||
var callTracker = new jasmineUnderTest.CallTracker();
|
||||
|
||||
expect(callTracker.any()).toBe(false);
|
||||
@@ -9,7 +9,7 @@ describe("CallTracker", function() {
|
||||
expect(callTracker.any()).toBe(true);
|
||||
});
|
||||
|
||||
it("tracks that number of times that it is executed", function() {
|
||||
it('tracks that number of times that it is executed', function() {
|
||||
var callTracker = new jasmineUnderTest.CallTracker();
|
||||
|
||||
expect(callTracker.count()).toEqual(0);
|
||||
@@ -19,52 +19,66 @@ describe("CallTracker", function() {
|
||||
expect(callTracker.count()).toEqual(1);
|
||||
});
|
||||
|
||||
it("tracks the params from each execution", function() {
|
||||
it('tracks the params from each execution', function() {
|
||||
var callTracker = new jasmineUnderTest.CallTracker();
|
||||
|
||||
callTracker.track({object: void 0, args: []});
|
||||
callTracker.track({object: {}, args: [0, "foo"]});
|
||||
callTracker.track({ object: void 0, args: [] });
|
||||
callTracker.track({ object: {}, args: [0, 'foo'] });
|
||||
|
||||
expect(callTracker.argsFor(0)).toEqual([]);
|
||||
|
||||
expect(callTracker.argsFor(1)).toEqual([0, "foo"]);
|
||||
expect(callTracker.argsFor(1)).toEqual([0, 'foo']);
|
||||
});
|
||||
|
||||
it("returns any empty array when there was no call", function() {
|
||||
it("tracks the 'this' object from each execution", function() {
|
||||
var callTracker = new jasmineUnderTest.CallTracker();
|
||||
|
||||
var this0 = {},
|
||||
this1 = {};
|
||||
callTracker.track({ object: this0, args: [] });
|
||||
callTracker.track({ object: this1, args: [] });
|
||||
callTracker.track({ args: [] });
|
||||
|
||||
expect(callTracker.thisFor(0)).toBe(this0);
|
||||
expect(callTracker.thisFor(1)).toBe(this1);
|
||||
expect(callTracker.thisFor(2)).toBe(undefined);
|
||||
});
|
||||
|
||||
it('returns any empty array when there was no call', function() {
|
||||
var callTracker = new jasmineUnderTest.CallTracker();
|
||||
|
||||
expect(callTracker.argsFor(0)).toEqual([]);
|
||||
});
|
||||
|
||||
it("allows access for the arguments for all calls", function() {
|
||||
it('allows access for the arguments for all calls', function() {
|
||||
var callTracker = new jasmineUnderTest.CallTracker();
|
||||
|
||||
callTracker.track({object: {}, args: []});
|
||||
callTracker.track({object: {}, args: [0, "foo"]});
|
||||
callTracker.track({ object: {}, args: [] });
|
||||
callTracker.track({ object: {}, args: [0, 'foo'] });
|
||||
|
||||
expect(callTracker.allArgs()).toEqual([[], [0, "foo"]]);
|
||||
expect(callTracker.allArgs()).toEqual([[], [0, 'foo']]);
|
||||
});
|
||||
|
||||
it("tracks the context and arguments for each call", function() {
|
||||
it('tracks the context and arguments for each call', function() {
|
||||
var callTracker = new jasmineUnderTest.CallTracker();
|
||||
|
||||
callTracker.track({object: {}, args: []});
|
||||
callTracker.track({object: {}, args: [0, "foo"]});
|
||||
callTracker.track({ object: {}, args: [] });
|
||||
callTracker.track({ object: {}, args: [0, 'foo'] });
|
||||
|
||||
expect(callTracker.all()[0]).toEqual({object: {}, args: []});
|
||||
expect(callTracker.all()[0]).toEqual({ object: {}, args: [] });
|
||||
|
||||
expect(callTracker.all()[1]).toEqual({object: {}, args: [0, "foo"]});
|
||||
expect(callTracker.all()[1]).toEqual({ object: {}, args: [0, 'foo'] });
|
||||
});
|
||||
|
||||
it("simplifies access to the arguments for the last (most recent) call", function() {
|
||||
it('simplifies access to the arguments for the last (most recent) call', function() {
|
||||
var callTracker = new jasmineUnderTest.CallTracker();
|
||||
|
||||
callTracker.track();
|
||||
callTracker.track({object: {}, args: [0, "foo"]});
|
||||
callTracker.track({ object: {}, args: [0, 'foo'] });
|
||||
|
||||
expect(callTracker.mostRecent()).toEqual({
|
||||
object: {},
|
||||
args: [0, "foo"]
|
||||
args: [0, 'foo']
|
||||
});
|
||||
});
|
||||
|
||||
@@ -74,12 +88,12 @@ describe("CallTracker", function() {
|
||||
expect(callTracker.mostRecent()).toBeFalsy();
|
||||
});
|
||||
|
||||
it("simplifies access to the arguments for the first (oldest) call", function() {
|
||||
it('simplifies access to the arguments for the first (oldest) call', function() {
|
||||
var callTracker = new jasmineUnderTest.CallTracker();
|
||||
|
||||
callTracker.track({object: {}, args: [0, "foo"]});
|
||||
callTracker.track({ object: {}, args: [0, 'foo'] });
|
||||
|
||||
expect(callTracker.first()).toEqual({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() {
|
||||
@@ -88,12 +102,11 @@ describe("CallTracker", function() {
|
||||
expect(callTracker.first()).toBeFalsy();
|
||||
});
|
||||
|
||||
|
||||
it("allows the tracking to be reset", function() {
|
||||
it('allows the tracking to be reset', function() {
|
||||
var callTracker = new jasmineUnderTest.CallTracker();
|
||||
|
||||
callTracker.track();
|
||||
callTracker.track({object: {}, args: [0, "foo"]});
|
||||
callTracker.track({ object: {}, args: [0, 'foo'] });
|
||||
callTracker.reset();
|
||||
|
||||
expect(callTracker.any()).toBe(false);
|
||||
@@ -103,18 +116,31 @@ describe("CallTracker", function() {
|
||||
expect(callTracker.mostRecent()).toBeFalsy();
|
||||
});
|
||||
|
||||
it("allows object arguments to be shallow cloned", function() {
|
||||
it('allows object arguments to be shallow cloned', function() {
|
||||
var callTracker = new jasmineUnderTest.CallTracker();
|
||||
callTracker.saveArgumentsByValue();
|
||||
|
||||
var objectArg = {"foo": "bar"},
|
||||
arrayArg = ["foo", "bar"];
|
||||
var objectArg = { foo: 'bar' },
|
||||
arrayArg = ['foo', 'bar'];
|
||||
|
||||
callTracker.track({object: {}, args: [objectArg, arrayArg, false, undefined, null, NaN, "", 0, 1.0]});
|
||||
callTracker.track({
|
||||
object: {},
|
||||
args: [objectArg, arrayArg, false, undefined, null, NaN, '', 0, 1.0]
|
||||
});
|
||||
|
||||
expect(callTracker.mostRecent().args[0]).not.toBe(objectArg);
|
||||
expect(callTracker.mostRecent().args[0]).toEqual(objectArg);
|
||||
expect(callTracker.mostRecent().args[1]).not.toBe(arrayArg);
|
||||
expect(callTracker.mostRecent().args[1]).toEqual(arrayArg);
|
||||
});
|
||||
|
||||
it('saves primitive arguments by value', function() {
|
||||
var callTracker = new jasmineUnderTest.CallTracker(),
|
||||
args = [undefined, null, false, '', /\s/, 0, 1.2, NaN];
|
||||
|
||||
callTracker.saveArgumentsByValue();
|
||||
callTracker.track({ object: {}, args: args });
|
||||
|
||||
expect(callTracker.mostRecent().args).toEqual(args);
|
||||
});
|
||||
});
|
||||
|
||||
166
spec/core/ClearStackSpec.js
Normal file
166
spec/core/ClearStackSpec.js
Normal file
@@ -0,0 +1,166 @@
|
||||
describe('ClearStack', function() {
|
||||
it('works in an integrationy way', function(done) {
|
||||
var clearStack = jasmineUnderTest.getClearStack(
|
||||
jasmineUnderTest.getGlobal()
|
||||
);
|
||||
|
||||
clearStack(function() {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('uses setImmediate when available', function() {
|
||||
var setImmediate = jasmine
|
||||
.createSpy('setImmediate')
|
||||
.and.callFake(function(fn) {
|
||||
fn();
|
||||
}),
|
||||
global = { setImmediate: setImmediate },
|
||||
clearStack = jasmineUnderTest.getClearStack(global),
|
||||
called = false;
|
||||
|
||||
clearStack(function() {
|
||||
called = true;
|
||||
});
|
||||
|
||||
expect(called).toBe(true);
|
||||
expect(setImmediate).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('uses setTimeout instead of setImmediate every 10 calls to make sure we release the CPU', function() {
|
||||
var setImmediate = jasmine.createSpy('setImmediate'),
|
||||
setTimeout = jasmine.createSpy('setTimeout'),
|
||||
global = { setImmediate: setImmediate, setTimeout: setTimeout },
|
||||
clearStack = jasmineUnderTest.getClearStack(global);
|
||||
|
||||
clearStack(function() {});
|
||||
clearStack(function() {});
|
||||
clearStack(function() {});
|
||||
clearStack(function() {});
|
||||
clearStack(function() {});
|
||||
clearStack(function() {});
|
||||
clearStack(function() {});
|
||||
clearStack(function() {});
|
||||
clearStack(function() {});
|
||||
|
||||
expect(setImmediate).toHaveBeenCalled();
|
||||
expect(setTimeout).not.toHaveBeenCalled();
|
||||
|
||||
clearStack(function() {});
|
||||
expect(setImmediate.calls.count()).toEqual(9);
|
||||
expect(setTimeout.calls.count()).toEqual(1);
|
||||
|
||||
clearStack(function() {});
|
||||
expect(setImmediate.calls.count()).toEqual(10);
|
||||
expect(setTimeout.calls.count()).toEqual(1);
|
||||
});
|
||||
|
||||
it('uses MessageChannels when available', function() {
|
||||
var fakeChannel = {
|
||||
port1: {},
|
||||
port2: {
|
||||
postMessage: function() {
|
||||
fakeChannel.port1.onmessage();
|
||||
}
|
||||
}
|
||||
},
|
||||
global = {
|
||||
MessageChannel: function() {
|
||||
return fakeChannel;
|
||||
}
|
||||
},
|
||||
clearStack = jasmineUnderTest.getClearStack(global),
|
||||
called = false;
|
||||
|
||||
clearStack(function() {
|
||||
called = true;
|
||||
});
|
||||
|
||||
expect(called).toBe(true);
|
||||
});
|
||||
|
||||
it('uses setTimeout instead of MessageChannel every 10 calls to make sure we release the CPU', function() {
|
||||
var fakeChannel = {
|
||||
port1: {},
|
||||
port2: {
|
||||
postMessage: jasmine
|
||||
.createSpy('postMessage')
|
||||
.and.callFake(function() {
|
||||
fakeChannel.port1.onmessage();
|
||||
})
|
||||
}
|
||||
},
|
||||
setTimeout = jasmine.createSpy('setTimeout'),
|
||||
global = {
|
||||
MessageChannel: function() {
|
||||
return fakeChannel;
|
||||
},
|
||||
setTimeout: setTimeout
|
||||
},
|
||||
clearStack = jasmineUnderTest.getClearStack(global);
|
||||
|
||||
clearStack(function() {});
|
||||
clearStack(function() {});
|
||||
clearStack(function() {});
|
||||
clearStack(function() {});
|
||||
clearStack(function() {});
|
||||
clearStack(function() {});
|
||||
clearStack(function() {});
|
||||
clearStack(function() {});
|
||||
clearStack(function() {});
|
||||
|
||||
expect(fakeChannel.port2.postMessage).toHaveBeenCalled();
|
||||
expect(setTimeout).not.toHaveBeenCalled();
|
||||
|
||||
clearStack(function() {});
|
||||
expect(fakeChannel.port2.postMessage.calls.count()).toEqual(9);
|
||||
expect(setTimeout.calls.count()).toEqual(1);
|
||||
|
||||
clearStack(function() {});
|
||||
expect(fakeChannel.port2.postMessage.calls.count()).toEqual(10);
|
||||
expect(setTimeout.calls.count()).toEqual(1);
|
||||
});
|
||||
|
||||
it('calls setTimeout when onmessage is called recursively', function() {
|
||||
var fakeChannel = {
|
||||
port1: {},
|
||||
port2: {
|
||||
postMessage: function() {
|
||||
fakeChannel.port1.onmessage();
|
||||
}
|
||||
}
|
||||
},
|
||||
setTimeout = jasmine.createSpy('setTimeout'),
|
||||
global = {
|
||||
MessageChannel: function() {
|
||||
return fakeChannel;
|
||||
},
|
||||
setTimeout: setTimeout
|
||||
},
|
||||
clearStack = jasmineUnderTest.getClearStack(global),
|
||||
fn = jasmine.createSpy('second clearStack function');
|
||||
|
||||
clearStack(function() {
|
||||
clearStack(fn);
|
||||
});
|
||||
|
||||
expect(fn).not.toHaveBeenCalled();
|
||||
expect(setTimeout).toHaveBeenCalledWith(fn, 0);
|
||||
});
|
||||
|
||||
it('falls back to setTimeout', function() {
|
||||
var setTimeout = jasmine.createSpy('setTimeout').and.callFake(function(fn) {
|
||||
fn();
|
||||
}),
|
||||
global = { setTimeout: setTimeout },
|
||||
clearStack = jasmineUnderTest.getClearStack(global),
|
||||
called = false;
|
||||
|
||||
clearStack(function() {
|
||||
called = true;
|
||||
});
|
||||
|
||||
expect(called).toBe(true);
|
||||
expect(setTimeout).toHaveBeenCalledWith(jasmine.any(Function), 0);
|
||||
});
|
||||
});
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
describe("DelayedFunctionScheduler", function() {
|
||||
it("schedules a function for later execution", function() {
|
||||
describe('DelayedFunctionScheduler', function() {
|
||||
it('schedules a function for later execution', function() {
|
||||
var scheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
|
||||
fn = jasmine.createSpy('fn');
|
||||
|
||||
@@ -12,9 +12,9 @@ describe("DelayedFunctionScheduler", function() {
|
||||
expect(fn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("schedules a string for later execution", function() {
|
||||
it('schedules a string for later execution', function() {
|
||||
var scheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
|
||||
strfn = "horrible = true;";
|
||||
strfn = 'horrible = true;';
|
||||
|
||||
scheduler.scheduleFunction(strfn, 0);
|
||||
|
||||
@@ -23,7 +23,7 @@ describe("DelayedFunctionScheduler", function() {
|
||||
expect(horrible).toEqual(true);
|
||||
});
|
||||
|
||||
it("#tick defaults to 0", function() {
|
||||
it('#tick defaults to 0', function() {
|
||||
var scheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
|
||||
fn = jasmine.createSpy('fn');
|
||||
|
||||
@@ -36,7 +36,7 @@ describe("DelayedFunctionScheduler", function() {
|
||||
expect(fn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("defaults delay to 0", function() {
|
||||
it('defaults delay to 0', function() {
|
||||
var scheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
|
||||
fn = jasmine.createSpy('fn');
|
||||
|
||||
@@ -49,7 +49,7 @@ describe("DelayedFunctionScheduler", function() {
|
||||
expect(fn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("optionally passes params to scheduled functions", function() {
|
||||
it('optionally passes params to scheduled functions', function() {
|
||||
var scheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
|
||||
fn = jasmine.createSpy('fn');
|
||||
|
||||
@@ -62,7 +62,7 @@ describe("DelayedFunctionScheduler", function() {
|
||||
expect(fn).toHaveBeenCalledWith('foo', 'bar');
|
||||
});
|
||||
|
||||
it("scheduled fns can optionally reoccur", function() {
|
||||
it('scheduled fns can optionally reoccur', function() {
|
||||
var scheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
|
||||
fn = jasmine.createSpy('fn');
|
||||
|
||||
@@ -81,23 +81,20 @@ describe("DelayedFunctionScheduler", function() {
|
||||
scheduler.tick(21);
|
||||
|
||||
expect(fn.calls.count()).toBe(4);
|
||||
|
||||
});
|
||||
|
||||
it("increments scheduled fns ids unless one is passed", function() {
|
||||
it('increments scheduled fns ids unless one is passed', function() {
|
||||
var scheduler = new jasmineUnderTest.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);
|
||||
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() {
|
||||
it('#removeFunctionWithId removes a previously scheduled function with a given id', function() {
|
||||
var scheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
|
||||
fn = jasmine.createSpy('fn'),
|
||||
timeoutKey;
|
||||
@@ -113,7 +110,7 @@ describe("DelayedFunctionScheduler", function() {
|
||||
expect(fn).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("executes recurring functions interleaved with regular functions in the correct order", function() {
|
||||
it('executes recurring functions interleaved with regular functions in the correct order', function() {
|
||||
var scheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
|
||||
fn = jasmine.createSpy('fn'),
|
||||
recurringCallCount = 0,
|
||||
@@ -134,12 +131,12 @@ describe("DelayedFunctionScheduler", function() {
|
||||
expect(fn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("schedules a function for later execution during a tick", function () {
|
||||
it('schedules a function for later execution during a tick', function() {
|
||||
var scheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
|
||||
fn = jasmine.createSpy('fn'),
|
||||
fnDelay = 10;
|
||||
|
||||
scheduler.scheduleFunction(function () {
|
||||
scheduler.scheduleFunction(function() {
|
||||
scheduler.scheduleFunction(fn, fnDelay);
|
||||
}, 0);
|
||||
|
||||
@@ -150,13 +147,13 @@ describe("DelayedFunctionScheduler", function() {
|
||||
expect(fn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("#removeFunctionWithId removes a previously scheduled function with a given id during a tick", function () {
|
||||
it('#removeFunctionWithId removes a previously scheduled function with a given id during a tick', function() {
|
||||
var scheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
|
||||
fn = jasmine.createSpy('fn'),
|
||||
fnDelay = 10,
|
||||
timeoutKey;
|
||||
|
||||
scheduler.scheduleFunction(function () {
|
||||
scheduler.scheduleFunction(function() {
|
||||
scheduler.removeFunctionWithId(timeoutKey);
|
||||
}, 0);
|
||||
timeoutKey = scheduler.scheduleFunction(fn, fnDelay);
|
||||
@@ -168,7 +165,7 @@ describe("DelayedFunctionScheduler", function() {
|
||||
expect(fn).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("executes recurring functions interleaved with regular functions and functions scheduled during a tick in the correct order", function () {
|
||||
it('executes recurring functions interleaved with regular functions and functions scheduled during a tick in the correct order', function() {
|
||||
var scheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
|
||||
fn = jasmine.createSpy('fn'),
|
||||
recurringCallCount = 0,
|
||||
@@ -185,7 +182,7 @@ describe("DelayedFunctionScheduler", function() {
|
||||
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(innerFn, 10); // 41ms absolute
|
||||
});
|
||||
|
||||
scheduler.scheduleFunction(recurring, 10, [], true);
|
||||
@@ -201,7 +198,7 @@ describe("DelayedFunctionScheduler", function() {
|
||||
expect(innerFn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("executes recurring functions after rescheduling them", function () {
|
||||
it('executes recurring functions after rescheduling them', function() {
|
||||
var scheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
|
||||
recurring = function() {
|
||||
expect(scheduler.scheduleFunction).toHaveBeenCalled();
|
||||
@@ -209,38 +206,40 @@ describe("DelayedFunctionScheduler", function() {
|
||||
|
||||
scheduler.scheduleFunction(recurring, 10, [], true);
|
||||
|
||||
spyOn(scheduler, "scheduleFunction");
|
||||
spyOn(scheduler, 'scheduleFunction');
|
||||
|
||||
scheduler.tick(10);
|
||||
});
|
||||
|
||||
it("removes functions during a tick that runs the function", function() {
|
||||
it('removes functions during a tick that runs the function', function() {
|
||||
var scheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
|
||||
fn = jasmine.createSpy('fn'),
|
||||
spy = jasmine.createSpy('fn'),
|
||||
spyAndRemove = jasmine.createSpy('fn'),
|
||||
fnDelay = 10,
|
||||
timeoutKey;
|
||||
|
||||
timeoutKey = scheduler.scheduleFunction(fn, fnDelay, [], true);
|
||||
scheduler.scheduleFunction(function () {
|
||||
spyAndRemove.and.callFake(function() {
|
||||
scheduler.removeFunctionWithId(timeoutKey);
|
||||
}, 2 * fnDelay);
|
||||
});
|
||||
|
||||
expect(fn).not.toHaveBeenCalled();
|
||||
scheduler.scheduleFunction(spyAndRemove, fnDelay);
|
||||
|
||||
scheduler.tick(3 * fnDelay);
|
||||
timeoutKey = scheduler.scheduleFunction(spy, fnDelay, [], true);
|
||||
|
||||
expect(fn).toHaveBeenCalled();
|
||||
expect(fn.calls.count()).toBe(2);
|
||||
scheduler.tick(2 * fnDelay);
|
||||
|
||||
expect(spy).not.toHaveBeenCalled();
|
||||
expect(spyAndRemove).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("removes functions during the first tick that runs the function", function() {
|
||||
it('removes functions during the first tick that runs the function', function() {
|
||||
var scheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
|
||||
fn = jasmine.createSpy('fn'),
|
||||
fnDelay = 10,
|
||||
timeoutKey;
|
||||
|
||||
timeoutKey = scheduler.scheduleFunction(fn, fnDelay, [], true);
|
||||
scheduler.scheduleFunction(function () {
|
||||
scheduler.scheduleFunction(function() {
|
||||
scheduler.removeFunctionWithId(timeoutKey);
|
||||
}, fnDelay);
|
||||
|
||||
@@ -252,17 +251,31 @@ describe("DelayedFunctionScheduler", function() {
|
||||
expect(fn.calls.count()).toBe(1);
|
||||
});
|
||||
|
||||
it("updates the mockDate per scheduled time", function () {
|
||||
it("does not remove a function that hasn't been added yet", function() {
|
||||
var scheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
|
||||
fn = jasmine.createSpy('fn'),
|
||||
fnDelay = 10;
|
||||
|
||||
scheduler.removeFunctionWithId('foo');
|
||||
scheduler.scheduleFunction(fn, fnDelay, [], false, 'foo');
|
||||
|
||||
expect(fn).not.toHaveBeenCalled();
|
||||
|
||||
scheduler.tick(fnDelay + 1);
|
||||
|
||||
expect(fn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('updates the mockDate per scheduled time', function() {
|
||||
var scheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
|
||||
tickDate = jasmine.createSpy('tickDate');
|
||||
|
||||
scheduler.scheduleFunction(function() {});
|
||||
scheduler.scheduleFunction(function() {}, 1);
|
||||
scheduler.scheduleFunction(function() {});
|
||||
scheduler.scheduleFunction(function() {}, 1);
|
||||
|
||||
scheduler.tick(1, tickDate);
|
||||
scheduler.tick(1, tickDate);
|
||||
|
||||
expect(tickDate).toHaveBeenCalledWith(0);
|
||||
expect(tickDate).toHaveBeenCalledWith(1);
|
||||
})
|
||||
expect(tickDate).toHaveBeenCalledWith(0);
|
||||
expect(tickDate).toHaveBeenCalledWith(1);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -1,68 +1,550 @@
|
||||
// TODO: Fix these unit tests!
|
||||
describe("Env", function() {
|
||||
describe('Env', function() {
|
||||
var env;
|
||||
beforeEach(function() {
|
||||
env = new jasmineUnderTest.Env();
|
||||
});
|
||||
|
||||
describe("#pending", function() {
|
||||
it("throws the Pending Spec exception", function() {
|
||||
afterEach(function() {
|
||||
env.cleanup_();
|
||||
});
|
||||
|
||||
describe('#pending', function() {
|
||||
it('throws the Pending Spec exception', function() {
|
||||
expect(function() {
|
||||
env.pending();
|
||||
}).toThrow(jasmineUnderTest.Spec.pendingSpecExceptionMessage);
|
||||
});
|
||||
|
||||
it("throws the Pending Spec exception with a custom message", function() {
|
||||
it('throws the Pending Spec exception with a custom message', function() {
|
||||
expect(function() {
|
||||
env.pending('custom message');
|
||||
}).toThrow(jasmineUnderTest.Spec.pendingSpecExceptionMessage + 'custom message');
|
||||
}).toThrow(
|
||||
jasmineUnderTest.Spec.pendingSpecExceptionMessage + 'custom message'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#topSuite", function() {
|
||||
it("returns the Jasmine top suite for users to traverse the spec tree", function() {
|
||||
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');
|
||||
});
|
||||
});
|
||||
|
||||
describe('#describe', function () {
|
||||
var spec = function(done){};
|
||||
it("throws the error", function() {
|
||||
expect(function() {
|
||||
env.describe('done method', spec);
|
||||
}).toThrow(new Error('describe does not expect any arguments'));
|
||||
});
|
||||
it('accepts its own current configureation', function() {
|
||||
env.configure(env.configuration());
|
||||
});
|
||||
|
||||
it('can configure specs to throw errors on expectation failures', function() {
|
||||
env.throwOnExpectationFailure(true);
|
||||
env.configure({ oneFailurePerSpec: true });
|
||||
|
||||
spyOn(jasmineUnderTest, 'Spec');
|
||||
env.it('foo', function() {});
|
||||
expect(jasmineUnderTest.Spec).toHaveBeenCalledWith(jasmine.objectContaining({
|
||||
throwOnExpectationFailure: true
|
||||
}));
|
||||
expect(jasmineUnderTest.Spec).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
throwOnExpectationFailure: true
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('can configure suites to throw errors on expectation failures', function() {
|
||||
env.throwOnExpectationFailure(true);
|
||||
env.configure({ oneFailurePerSpec: true });
|
||||
|
||||
spyOn(jasmineUnderTest, 'Suite');
|
||||
env.describe('foo', function() {});
|
||||
expect(jasmineUnderTest.Suite).toHaveBeenCalledWith(jasmine.objectContaining({
|
||||
throwOnExpectationFailure: true
|
||||
}));
|
||||
expect(jasmineUnderTest.Suite).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
throwOnExpectationFailure: true
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('ignores configuration properties that are present but undefined', function() {
|
||||
var initialConfig = {
|
||||
random: true,
|
||||
seed: '123',
|
||||
failFast: true,
|
||||
failSpecWithNoExpectations: true,
|
||||
oneFailurePerSpec: true,
|
||||
stopSpecOnExpectationFailure: true,
|
||||
stopOnSpecFailure: true,
|
||||
hideDisabled: true
|
||||
};
|
||||
env.configure(initialConfig);
|
||||
|
||||
env.configure({
|
||||
random: undefined,
|
||||
seed: undefined,
|
||||
failFast: undefined,
|
||||
failSpecWithNoExpectations: undefined,
|
||||
oneFailurePerSpec: undefined,
|
||||
stopSpecOnExpectationFailure: undefined,
|
||||
stopOnSpecFailure: undefined,
|
||||
hideDisabled: undefined
|
||||
});
|
||||
|
||||
expect(env.configuration()).toEqual(
|
||||
jasmine.objectContaining(initialConfig)
|
||||
);
|
||||
});
|
||||
|
||||
it('sets stopOnSpecFailure when failFast is set, and vice versa', function() {
|
||||
env.configure({ failFast: true });
|
||||
expect(env.configuration()).toEqual(
|
||||
jasmine.objectContaining({
|
||||
failFast: true,
|
||||
stopOnSpecFailure: true
|
||||
})
|
||||
);
|
||||
|
||||
env.configure({ stopOnSpecFailure: false });
|
||||
expect(env.configuration()).toEqual(
|
||||
jasmine.objectContaining({
|
||||
failFast: false,
|
||||
stopOnSpecFailure: false
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('rejects a single call that sets stopOnSpecFailure and failFast to different values', function() {
|
||||
expect(function() {
|
||||
env.configure({ failFast: true, stopOnSpecFailure: false });
|
||||
}).toThrowError(
|
||||
'stopOnSpecFailure and failFast are aliases for each ' +
|
||||
"other. Don't set failFast if you also set stopOnSpecFailure."
|
||||
);
|
||||
});
|
||||
|
||||
it('sets stopSpecOnExpectationFailure when oneFailurePerSpec is set, and vice versa', function() {
|
||||
env.configure({ oneFailurePerSpec: true });
|
||||
expect(env.configuration()).toEqual(
|
||||
jasmine.objectContaining({
|
||||
oneFailurePerSpec: true,
|
||||
stopSpecOnExpectationFailure: true
|
||||
})
|
||||
);
|
||||
|
||||
env.configure({ stopSpecOnExpectationFailure: false });
|
||||
expect(env.configuration()).toEqual(
|
||||
jasmine.objectContaining({
|
||||
oneFailurePerSpec: false,
|
||||
stopSpecOnExpectationFailure: false
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('rejects a single call that sets stopSpecOnExpectationFailure and oneFailurePerSpec to different values', function() {
|
||||
expect(function() {
|
||||
env.configure({
|
||||
oneFailurePerSpec: true,
|
||||
stopSpecOnExpectationFailure: false
|
||||
});
|
||||
}).toThrowError(
|
||||
'stopSpecOnExpectationFailure and oneFailurePerSpec are ' +
|
||||
"aliases for each other. Don't set oneFailurePerSpec if you also set " +
|
||||
'stopSpecOnExpectationFailure.'
|
||||
);
|
||||
});
|
||||
|
||||
describe('promise library', function() {
|
||||
it('can be configured without a custom library', function() {
|
||||
env.configure({});
|
||||
env.configure({ Promise: undefined });
|
||||
});
|
||||
|
||||
it('can be configured with a custom library', function() {
|
||||
var myLibrary = {
|
||||
resolve: jasmine.createSpy(),
|
||||
reject: jasmine.createSpy()
|
||||
};
|
||||
env.configure({ Promise: myLibrary });
|
||||
});
|
||||
|
||||
it('cannot be configured with an invalid promise library', function() {
|
||||
var myLibrary = {};
|
||||
|
||||
expect(function() {
|
||||
env.configure({ Promise: myLibrary });
|
||||
}).toThrowError(
|
||||
'Custom promise library missing `resolve`/`reject` functions'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('defaults to multiple failures for specs', function() {
|
||||
spyOn(jasmineUnderTest, 'Spec');
|
||||
env.it('bar', function() {});
|
||||
expect(jasmineUnderTest.Spec).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
throwOnExpectationFailure: false
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('defaults to multiple failures for suites', function() {
|
||||
spyOn(jasmineUnderTest, 'Suite');
|
||||
env.describe('foo', function() {});
|
||||
expect(jasmineUnderTest.Suite).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
throwOnExpectationFailure: false
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
describe('#describe', function() {
|
||||
it('throws an error when given arguments', function() {
|
||||
expect(function() {
|
||||
env.describe('done method', function(done) {});
|
||||
}).toThrowError('describe does not expect any arguments');
|
||||
});
|
||||
|
||||
it('throws an error when it receives a non-fn argument', function() {
|
||||
// Some versions of PhantomJS return [object DOMWindow] when
|
||||
// Object.prototype.toString.apply is called with `undefined` or `null`.
|
||||
// In a similar fashion, IE8 gives [object Object] for both `undefined`
|
||||
// and `null`. We mostly just want these tests to check that using
|
||||
// anything other than a function throws an error.
|
||||
expect(function() {
|
||||
env.describe('undefined arg', undefined);
|
||||
}).toThrowError(
|
||||
/describe expects a function argument; received \[object (Undefined|DOMWindow|Object)\]/
|
||||
);
|
||||
expect(function() {
|
||||
env.describe('null arg', null);
|
||||
}).toThrowError(
|
||||
/describe expects a function argument; received \[object (Null|DOMWindow|Object)\]/
|
||||
);
|
||||
|
||||
expect(function() {
|
||||
env.describe('array arg', []);
|
||||
}).toThrowError(
|
||||
'describe expects a function argument; received [object Array]'
|
||||
);
|
||||
expect(function() {
|
||||
env.describe('object arg', {});
|
||||
}).toThrowError(
|
||||
'describe expects a function argument; received [object Object]'
|
||||
);
|
||||
|
||||
expect(function() {
|
||||
env.describe('fn arg', function() {});
|
||||
}).not.toThrowError(
|
||||
'describe expects a function argument; received [object Function]'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#it', function() {
|
||||
it('throws an error when it receives a non-fn argument', function() {
|
||||
expect(function() {
|
||||
env.it('undefined arg', null);
|
||||
}).toThrowError(
|
||||
/it expects a function argument; received \[object (Null|DOMWindow|Object)\]/
|
||||
);
|
||||
});
|
||||
|
||||
it('does not throw when it is not given a fn argument', function() {
|
||||
expect(function() {
|
||||
env.it('pending spec');
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('accepts an async function', function() {
|
||||
jasmine.getEnv().requireAsyncAwait();
|
||||
expect(function() {
|
||||
env.it('async', jasmine.getEnv().makeAsyncAwaitFunction());
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('throws an error when the timeout value is too large for setTimeout', function() {
|
||||
expect(function() {
|
||||
env.it('huge timeout', function() {}, 2147483648);
|
||||
}).toThrowError('Timeout value cannot be greater than 2147483647');
|
||||
});
|
||||
});
|
||||
|
||||
describe('#xit', function() {
|
||||
it('calls spec.exclude with "Temporarily disabled with xit"', function() {
|
||||
var excludeSpy = jasmine.createSpy();
|
||||
spyOn(env, 'it').and.returnValue({
|
||||
exclude: excludeSpy
|
||||
});
|
||||
env.xit('foo', function() {});
|
||||
expect(excludeSpy).toHaveBeenCalledWith('Temporarily disabled with xit');
|
||||
});
|
||||
|
||||
it('calls spec.pend with "Temporarily disabled with xit"', function() {
|
||||
var pendSpy = jasmine.createSpy();
|
||||
var realExclude = jasmineUnderTest.Spec.prototype.exclude;
|
||||
|
||||
spyOn(env, 'it').and.returnValue({
|
||||
exclude: realExclude,
|
||||
pend: pendSpy
|
||||
});
|
||||
env.xit();
|
||||
env.xit('foo', function() {});
|
||||
expect(pendSpy).toHaveBeenCalledWith('Temporarily disabled with xit');
|
||||
});
|
||||
|
||||
it('throws an error when it receives a non-fn argument', function() {
|
||||
expect(function() {
|
||||
env.xit('undefined arg', null);
|
||||
}).toThrowError(
|
||||
/xit expects a function argument; received \[object (Null|DOMWindow|Object)\]/
|
||||
);
|
||||
});
|
||||
|
||||
it('does not throw when it is not given a fn argument', function() {
|
||||
expect(function() {
|
||||
env.xit('pending spec');
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('accepts an async function', function() {
|
||||
jasmine.getEnv().requireAsyncAwait();
|
||||
expect(function() {
|
||||
env.xit('async', jasmine.getEnv().makeAsyncAwaitFunction());
|
||||
}).not.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe('#fit', function() {
|
||||
it('throws an error when it receives a non-fn argument', function() {
|
||||
expect(function() {
|
||||
env.fit('undefined arg', undefined);
|
||||
}).toThrowError(
|
||||
/fit expects a function argument; received \[object (Undefined|DOMWindow|Object)\]/
|
||||
);
|
||||
});
|
||||
|
||||
it('throws an error when the timeout value is too large for setTimeout', function() {
|
||||
expect(function() {
|
||||
env.fit('huge timeout', function() {}, 2147483648);
|
||||
}).toThrowError('Timeout value cannot be greater than 2147483647');
|
||||
});
|
||||
});
|
||||
|
||||
describe('#beforeEach', function() {
|
||||
it('throws an error when it receives a non-fn argument', function() {
|
||||
expect(function() {
|
||||
env.beforeEach(undefined);
|
||||
}).toThrowError(
|
||||
/beforeEach expects a function argument; received \[object (Undefined|DOMWindow|Object)\]/
|
||||
);
|
||||
});
|
||||
|
||||
it('accepts an async function', function() {
|
||||
jasmine.getEnv().requireAsyncAwait();
|
||||
expect(function() {
|
||||
env.beforeEach(jasmine.getEnv().makeAsyncAwaitFunction());
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('throws an error when the timeout value is too large for setTimeout', function() {
|
||||
expect(function() {
|
||||
env.beforeEach(function() {}, 2147483648);
|
||||
}).toThrowError('Timeout value cannot be greater than 2147483647');
|
||||
});
|
||||
});
|
||||
|
||||
describe('#beforeAll', function() {
|
||||
it('throws an error when it receives a non-fn argument', function() {
|
||||
expect(function() {
|
||||
env.beforeAll(undefined);
|
||||
}).toThrowError(
|
||||
/beforeAll expects a function argument; received \[object (Undefined|DOMWindow|Object)\]/
|
||||
);
|
||||
});
|
||||
|
||||
it('accepts an async function', function() {
|
||||
jasmine.getEnv().requireAsyncAwait();
|
||||
expect(function() {
|
||||
env.beforeAll(jasmine.getEnv().makeAsyncAwaitFunction());
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('throws an error when the timeout value is too large for setTimeout', function() {
|
||||
expect(function() {
|
||||
env.beforeAll(function() {}, 2147483648);
|
||||
}).toThrowError('Timeout value cannot be greater than 2147483647');
|
||||
});
|
||||
});
|
||||
|
||||
describe('#afterEach', function() {
|
||||
it('throws an error when it receives a non-fn argument', function() {
|
||||
expect(function() {
|
||||
env.afterEach(undefined);
|
||||
}).toThrowError(
|
||||
/afterEach expects a function argument; received \[object (Undefined|DOMWindow|Object)\]/
|
||||
);
|
||||
});
|
||||
|
||||
it('accepts an async function', function() {
|
||||
jasmine.getEnv().requireAsyncAwait();
|
||||
expect(function() {
|
||||
env.afterEach(jasmine.getEnv().makeAsyncAwaitFunction());
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('throws an error when the timeout value is too large for setTimeout', function() {
|
||||
expect(function() {
|
||||
env.afterEach(function() {}, 2147483648);
|
||||
}).toThrowError('Timeout value cannot be greater than 2147483647');
|
||||
});
|
||||
});
|
||||
|
||||
describe('#afterAll', function() {
|
||||
it('throws an error when it receives a non-fn argument', function() {
|
||||
expect(function() {
|
||||
env.afterAll(undefined);
|
||||
}).toThrowError(
|
||||
/afterAll expects a function argument; received \[object (Undefined|DOMWindow|Object)\]/
|
||||
);
|
||||
});
|
||||
|
||||
it('accepts an async function', function() {
|
||||
jasmine.getEnv().requireAsyncAwait();
|
||||
expect(function() {
|
||||
env.afterAll(jasmine.getEnv().makeAsyncAwaitFunction());
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('throws an error when the timeout value is too large for setTimeout', function() {
|
||||
expect(function() {
|
||||
env.afterAll(function() {}, 2147483648);
|
||||
}).toThrowError('Timeout value cannot be greater than 2147483647');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when not constructed with suppressLoadErrors: true', function() {
|
||||
it('installs a global error handler on construction', function() {
|
||||
var globalErrors = jasmine.createSpyObj('globalErrors', [
|
||||
'install',
|
||||
'uninstall',
|
||||
'pushListener',
|
||||
'popListener'
|
||||
]);
|
||||
spyOn(jasmineUnderTest, 'GlobalErrors').and.returnValue(globalErrors);
|
||||
env.cleanup_();
|
||||
env = new jasmineUnderTest.Env();
|
||||
expect(globalErrors.install).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when constructed with suppressLoadErrors: true', function() {
|
||||
it('does not install a global error handler until execute is called', function() {
|
||||
var globalErrors = jasmine.createSpyObj('globalErrors', [
|
||||
'install',
|
||||
'uninstall',
|
||||
'pushListener',
|
||||
'popListener'
|
||||
]);
|
||||
spyOn(jasmineUnderTest, 'GlobalErrors').and.returnValue(globalErrors);
|
||||
env.cleanup_();
|
||||
env = new jasmineUnderTest.Env({ suppressLoadErrors: true });
|
||||
expect(globalErrors.install).not.toHaveBeenCalled();
|
||||
env.execute();
|
||||
expect(globalErrors.install).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
it('creates an expectationFactory that uses the current custom equality testers and object formatters', function(done) {
|
||||
function customEqualityTester() {}
|
||||
function customObjectFormatter() {}
|
||||
function prettyPrinter() {}
|
||||
var RealSpec = jasmineUnderTest.Spec,
|
||||
specInstance,
|
||||
expectationFactory;
|
||||
spyOn(jasmineUnderTest, 'MatchersUtil');
|
||||
spyOn(jasmineUnderTest, 'makePrettyPrinter').and.returnValue(prettyPrinter);
|
||||
spyOn(jasmineUnderTest, 'Spec').and.callFake(function(options) {
|
||||
expectationFactory = options.expectationFactory;
|
||||
specInstance = new RealSpec(options);
|
||||
return specInstance;
|
||||
});
|
||||
|
||||
env.it('spec', function() {
|
||||
env.addCustomEqualityTester(customEqualityTester);
|
||||
env.addCustomObjectFormatter(customObjectFormatter);
|
||||
expectationFactory('actual', specInstance);
|
||||
});
|
||||
|
||||
env.execute(null, function() {
|
||||
expect(jasmineUnderTest.makePrettyPrinter).toHaveBeenCalledWith([
|
||||
customObjectFormatter
|
||||
]);
|
||||
expect(jasmineUnderTest.MatchersUtil).toHaveBeenCalledWith({
|
||||
customTesters: [customEqualityTester],
|
||||
pp: prettyPrinter
|
||||
});
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('creates an asyncExpectationFactory that uses the current custom equality testers and object formatters', function(done) {
|
||||
function customEqualityTester() {}
|
||||
function customObjectFormatter() {}
|
||||
function prettyPrinter() {}
|
||||
var RealSpec = jasmineUnderTest.Spec,
|
||||
specInstance,
|
||||
asyncExpectationFactory;
|
||||
spyOn(jasmineUnderTest, 'MatchersUtil');
|
||||
spyOn(jasmineUnderTest, 'makePrettyPrinter').and.returnValue(prettyPrinter);
|
||||
spyOn(jasmineUnderTest, 'Spec').and.callFake(function(options) {
|
||||
asyncExpectationFactory = options.asyncExpectationFactory;
|
||||
specInstance = new RealSpec(options);
|
||||
return specInstance;
|
||||
});
|
||||
|
||||
env.it('spec', function() {
|
||||
env.addCustomEqualityTester(customEqualityTester);
|
||||
env.addCustomObjectFormatter(customObjectFormatter);
|
||||
asyncExpectationFactory('actual', specInstance);
|
||||
});
|
||||
|
||||
env.execute(null, function() {
|
||||
expect(jasmineUnderTest.makePrettyPrinter).toHaveBeenCalledWith([
|
||||
customObjectFormatter
|
||||
]);
|
||||
expect(jasmineUnderTest.MatchersUtil).toHaveBeenCalledWith({
|
||||
customTesters: [customEqualityTester],
|
||||
pp: prettyPrinter
|
||||
});
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('#execute', function() {
|
||||
it('returns a promise when the environment supports promises', function() {
|
||||
jasmine.getEnv().requirePromises();
|
||||
expect(env.execute()).toBeInstanceOf(Promise);
|
||||
});
|
||||
|
||||
it('returns a promise when a custom promise constructor is provided', function() {
|
||||
function CustomPromise() {}
|
||||
CustomPromise.resolve = function() {};
|
||||
CustomPromise.reject = function() {};
|
||||
|
||||
env.configure({ Promise: CustomPromise });
|
||||
expect(env.execute()).toBeInstanceOf(CustomPromise);
|
||||
});
|
||||
|
||||
it('returns undefined when promises are unavailable', function() {
|
||||
jasmine.getEnv().requireNoPromises();
|
||||
expect(env.execute()).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should reset the topSuite when run twice', function() {
|
||||
jasmine.getEnv().requirePromises();
|
||||
spyOn(env.topSuite(), 'reset');
|
||||
return env
|
||||
.execute() // 1
|
||||
.then(function() {
|
||||
return env.execute(); // 2
|
||||
})
|
||||
.then(function() {
|
||||
expect(env.topSuite().reset).toHaveBeenCalledOnceWith();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
describe("ExceptionFormatter", function() {
|
||||
describe("#message", function() {
|
||||
describe('ExceptionFormatter', function() {
|
||||
describe('#message', function() {
|
||||
it('formats Firefox exception messages', function() {
|
||||
var sampleFirefoxException = {
|
||||
fileName: 'foo.js',
|
||||
@@ -10,7 +10,9 @@ describe("ExceptionFormatter", function() {
|
||||
exceptionFormatter = new jasmineUnderTest.ExceptionFormatter(),
|
||||
message = exceptionFormatter.message(sampleFirefoxException);
|
||||
|
||||
expect(message).toEqual('A Classic Mistake: you got your foo in my bar in foo.js (line 1978)');
|
||||
expect(message).toEqual(
|
||||
'A Classic Mistake: you got your foo in my bar in foo.js (line 1978)'
|
||||
);
|
||||
});
|
||||
|
||||
it('formats Webkit exception messages', function() {
|
||||
@@ -23,7 +25,9 @@ describe("ExceptionFormatter", function() {
|
||||
exceptionFormatter = new jasmineUnderTest.ExceptionFormatter(),
|
||||
message = exceptionFormatter.message(sampleWebkitException);
|
||||
|
||||
expect(message).toEqual('A Classic Mistake: you got your foo in my bar in foo.js (line 1978)');
|
||||
expect(message).toEqual(
|
||||
'A Classic Mistake: you got your foo in my bar in foo.js (line 1978)'
|
||||
);
|
||||
});
|
||||
|
||||
it('formats V8 exception messages', function() {
|
||||
@@ -37,27 +41,189 @@ describe("ExceptionFormatter", function() {
|
||||
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 jasmineUnderTest.ExceptionFormatter(),
|
||||
message = exceptionFormatter.message(thrown);
|
||||
it('formats unnamed exceptions with message', function() {
|
||||
var unnamedError = { message: 'This is an unnamed error message.' };
|
||||
|
||||
expect(message).toEqual("crazy error thrown");
|
||||
var exceptionFormatter = new jasmineUnderTest.ExceptionFormatter(),
|
||||
message = exceptionFormatter.message(unnamedError);
|
||||
|
||||
expect(message).toEqual('This is an unnamed error message.');
|
||||
});
|
||||
|
||||
it('formats empty exceptions with toString format', function() {
|
||||
var EmptyError = function() {};
|
||||
EmptyError.prototype.toString = function() {
|
||||
return '[EmptyError]';
|
||||
};
|
||||
var emptyError = new EmptyError();
|
||||
|
||||
var exceptionFormatter = new jasmineUnderTest.ExceptionFormatter(),
|
||||
message = exceptionFormatter.message(emptyError);
|
||||
|
||||
expect(message).toEqual('[EmptyError] thrown');
|
||||
});
|
||||
|
||||
it("formats thrown exceptions that aren't errors", function() {
|
||||
var thrown = 'crazy error',
|
||||
exceptionFormatter = new jasmineUnderTest.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; }
|
||||
|
||||
describe('#stack', function() {
|
||||
it('formats stack traces', function() {
|
||||
var error;
|
||||
try { throw new Error("an error") } catch(e) { error = e; }
|
||||
try {
|
||||
throw new Error('an error');
|
||||
} catch (e) {
|
||||
error = e;
|
||||
}
|
||||
|
||||
expect(new jasmineUnderTest.ExceptionFormatter().stack(error)).toMatch(/ExceptionFormatterSpec\.js.*\d+/)
|
||||
expect(new jasmineUnderTest.ExceptionFormatter().stack(error)).toMatch(
|
||||
/ExceptionFormatterSpec\.js.*\d+/
|
||||
);
|
||||
});
|
||||
|
||||
it("returns null if no Error provided", function() {
|
||||
it('filters Jasmine stack frames from V8-style traces but leaves unmatched lines intact', function() {
|
||||
var error = {
|
||||
message: 'nope',
|
||||
stack:
|
||||
'C:\\__spec__\\core\\UtilSpec.ts:120\n' +
|
||||
" new Error('nope');\n" +
|
||||
' ^\n' +
|
||||
'\n' +
|
||||
'Error: nope\n' +
|
||||
' at fn1 (C:\\__spec__\\core\\UtilSpec.js:115:19)\n' +
|
||||
' -> C:\\__spec__\\core\\UtilSpec.ts:120:15\n' +
|
||||
' at fn2 (C:\\__jasmine__\\lib\\jasmine-core\\jasmine.js:7533:40)\n' +
|
||||
' at fn3 (C:\\__jasmine__\\lib\\jasmine-core\\jasmine.js:7575:25)\n' +
|
||||
' at fn4 (node:internal/timers:462:21)\n'
|
||||
};
|
||||
var subject = new jasmineUnderTest.ExceptionFormatter({
|
||||
jasmineFile: 'C:\\__jasmine__\\lib\\jasmine-core\\jasmine.js'
|
||||
});
|
||||
var result = subject.stack(error);
|
||||
expect(result).toEqual(
|
||||
'C:\\__spec__\\core\\UtilSpec.ts:120\n' +
|
||||
" new Error('nope');\n" +
|
||||
' ^\n' +
|
||||
'Error: nope\n' +
|
||||
' at fn1 (C:\\__spec__\\core\\UtilSpec.js:115:19)\n' +
|
||||
' -> C:\\__spec__\\core\\UtilSpec.ts:120:15\n' +
|
||||
' at <Jasmine>\n' +
|
||||
' at fn4 (node:internal/timers:462:21)'
|
||||
);
|
||||
});
|
||||
|
||||
it('filters Jasmine stack frames from V8 style traces', function() {
|
||||
var error = {
|
||||
message: 'nope',
|
||||
stack:
|
||||
'Error: nope\n' +
|
||||
' at fn1 (http://localhost:8888/__spec__/core/UtilSpec.js:115:19)\n' +
|
||||
' at fn2 (http://localhost:8888/__jasmine__/jasmine.js:4320:20)\n' +
|
||||
' at fn3 (http://localhost:8888/__jasmine__/jasmine.js:4320:20)\n' +
|
||||
' at fn4 (http://localhost:8888/__spec__/core/UtilSpec.js:110:19)\n'
|
||||
};
|
||||
var subject = new jasmineUnderTest.ExceptionFormatter({
|
||||
jasmineFile: 'http://localhost:8888/__jasmine__/jasmine.js'
|
||||
});
|
||||
var result = subject.stack(error);
|
||||
expect(result).toEqual(
|
||||
'Error: nope\n' +
|
||||
' at fn1 (http://localhost:8888/__spec__/core/UtilSpec.js:115:19)\n' +
|
||||
' at <Jasmine>\n' +
|
||||
' at fn4 (http://localhost:8888/__spec__/core/UtilSpec.js:110:19)'
|
||||
);
|
||||
});
|
||||
|
||||
it('filters Jasmine stack frames from Webkit style traces', function() {
|
||||
var error = {
|
||||
stack:
|
||||
'http://localhost:8888/__spec__/core/UtilSpec.js:115:28\n' +
|
||||
'fn1@http://localhost:8888/__jasmine__/jasmine.js:4320:27\n' +
|
||||
'fn2@http://localhost:8888/__jasmine__/jasmine.js:4320:27\n' +
|
||||
'http://localhost:8888/__spec__/core/UtilSpec.js:115:28'
|
||||
};
|
||||
var subject = new jasmineUnderTest.ExceptionFormatter({
|
||||
jasmineFile: 'http://localhost:8888/__jasmine__/jasmine.js'
|
||||
});
|
||||
var result = subject.stack(error);
|
||||
expect(result).toEqual(
|
||||
'http://localhost:8888/__spec__/core/UtilSpec.js:115:28\n' +
|
||||
'<Jasmine>\n' +
|
||||
'http://localhost:8888/__spec__/core/UtilSpec.js:115:28'
|
||||
);
|
||||
});
|
||||
|
||||
it('filters Jasmine stack frames in this environment', function() {
|
||||
var error, i;
|
||||
try {
|
||||
throw new Error('an error');
|
||||
} catch (e) {
|
||||
error = e;
|
||||
}
|
||||
var subject = new jasmineUnderTest.ExceptionFormatter({
|
||||
jasmineFile: jasmine.util.jasmineFile()
|
||||
});
|
||||
var result = subject.stack(error);
|
||||
var lines = result.split('\n');
|
||||
|
||||
if (lines[0].match(/an error/)) {
|
||||
lines.shift();
|
||||
}
|
||||
|
||||
expect(lines[0]).toMatch(/ExceptionFormatterSpec.js/);
|
||||
expect(lines[1]).toMatch(/<Jasmine>/);
|
||||
|
||||
// Node has some number of additional frames below Jasmine.
|
||||
for (i = 2; i < lines.length; i++) {
|
||||
expect(lines[i]).not.toMatch(/jasmine.js/);
|
||||
}
|
||||
});
|
||||
|
||||
it('handles multiline error messages in this environment', function() {
|
||||
var error,
|
||||
msg = 'an error\nwith two lines';
|
||||
try {
|
||||
throw new Error(msg);
|
||||
} catch (e) {
|
||||
error = e;
|
||||
}
|
||||
|
||||
if (error.stack.indexOf(msg) === -1) {
|
||||
pending("Stack traces don't have messages in this environment");
|
||||
}
|
||||
var subject = new jasmineUnderTest.ExceptionFormatter({
|
||||
jasmineFile: jasmine.util.jasmineFile()
|
||||
});
|
||||
var result = subject.stack(error);
|
||||
var lines = result.split('\n');
|
||||
|
||||
expect(lines[0]).toMatch(/an error/);
|
||||
expect(lines[1]).toMatch(/with two lines/);
|
||||
expect(lines[2]).toMatch(/ExceptionFormatterSpec.js/);
|
||||
expect(lines[3]).toMatch(/<Jasmine>/);
|
||||
});
|
||||
|
||||
it('returns null if no Error provided', function() {
|
||||
expect(new jasmineUnderTest.ExceptionFormatter().stack()).toBeNull();
|
||||
});
|
||||
|
||||
it('includes error properties in stack', function() {
|
||||
var error;
|
||||
try {
|
||||
throw new Error('an error');
|
||||
} catch (e) {
|
||||
error = e;
|
||||
}
|
||||
error.someProperty = 'hello there';
|
||||
|
||||
var result = new jasmineUnderTest.ExceptionFormatter().stack(error);
|
||||
|
||||
expect(result).toMatch(/error properties:.*someProperty.*hello there/);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -5,64 +5,49 @@ describe('Exceptions:', function() {
|
||||
env = new jasmineUnderTest.Env();
|
||||
});
|
||||
|
||||
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');
|
||||
|
||||
try {
|
||||
env.execute();
|
||||
spy();
|
||||
}
|
||||
catch (e) {}
|
||||
|
||||
expect(spy).not.toHaveBeenCalled();
|
||||
});
|
||||
afterEach(function() {
|
||||
env.cleanup_();
|
||||
});
|
||||
|
||||
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() {
|
||||
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);
|
||||
});
|
||||
|
||||
var expectations = function() {
|
||||
expect(secondTest).toHaveBeenCalled();
|
||||
done();
|
||||
};
|
||||
|
||||
env.addReporter({ jasmineDone: expectations });
|
||||
env.execute();
|
||||
}
|
||||
);
|
||||
env.it(
|
||||
'should be a passing test that runs after exceptions are thrown from a async test',
|
||||
secondTest
|
||||
);
|
||||
});
|
||||
|
||||
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);
|
||||
});
|
||||
var expectations = function() {
|
||||
expect(secondTest).toHaveBeenCalled();
|
||||
done();
|
||||
};
|
||||
|
||||
throw new Error("top level error");
|
||||
env.execute(null, expectations);
|
||||
});
|
||||
|
||||
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);
|
||||
});
|
||||
env.describe("a suite that doesn't throw an exception", secondDescribe);
|
||||
|
||||
var expectations = function() {
|
||||
expect(secondDescribe).toHaveBeenCalled();
|
||||
done();
|
||||
};
|
||||
|
||||
env.addReporter({ jasmineDone: expectations });
|
||||
env.execute();
|
||||
throw new Error('top level error');
|
||||
});
|
||||
env.describe("a suite that doesn't throw an exception", secondDescribe);
|
||||
|
||||
var expectations = function() {
|
||||
expect(secondDescribe).toHaveBeenCalled();
|
||||
done();
|
||||
};
|
||||
|
||||
env.execute(null, expectations);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
123
spec/core/ExpectationFilterChainSpec.js
Normal file
123
spec/core/ExpectationFilterChainSpec.js
Normal file
@@ -0,0 +1,123 @@
|
||||
describe('ExpectationFilterChain', function() {
|
||||
describe('#addFilter', function() {
|
||||
it('returns a new filter chain with the added filter', function() {
|
||||
var first = jasmine.createSpy('first'),
|
||||
second = jasmine.createSpy('second'),
|
||||
orig = new jasmineUnderTest.ExpectationFilterChain({
|
||||
modifyFailureMessage: first
|
||||
}),
|
||||
added = orig.addFilter({ selectComparisonFunc: second });
|
||||
|
||||
added.modifyFailureMessage();
|
||||
expect(first).toHaveBeenCalled();
|
||||
added.selectComparisonFunc();
|
||||
expect(second).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('does not modify the original filter chain', function() {
|
||||
var orig = new jasmineUnderTest.ExpectationFilterChain({}),
|
||||
f = jasmine.createSpy('f');
|
||||
|
||||
orig.addFilter({ selectComparisonFunc: f });
|
||||
|
||||
orig.selectComparisonFunc();
|
||||
expect(f).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('#selectComparisonFunc', function() {
|
||||
describe('When no filters have #selectComparisonFunc', function() {
|
||||
it('returns undefined', function() {
|
||||
var chain = new jasmineUnderTest.ExpectationFilterChain();
|
||||
chain.addFilter({});
|
||||
expect(chain.selectComparisonFunc()).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('When some filters have #selectComparisonFunc', function() {
|
||||
it('calls the first filter that has #selectComparisonFunc', function() {
|
||||
var first = jasmine.createSpy('first').and.returnValue('first'),
|
||||
second = jasmine.createSpy('second').and.returnValue('second'),
|
||||
chain = new jasmineUnderTest.ExpectationFilterChain()
|
||||
.addFilter({ selectComparisonFunc: first })
|
||||
.addFilter({ selectComparisonFunc: second }),
|
||||
matcher = {},
|
||||
result;
|
||||
|
||||
result = chain.selectComparisonFunc(matcher);
|
||||
|
||||
expect(first).toHaveBeenCalledWith(matcher);
|
||||
expect(second).not.toHaveBeenCalled();
|
||||
expect(result).toEqual('first');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#buildFailureMessage', function() {
|
||||
describe('When no filters have #buildFailureMessage', function() {
|
||||
it('returns undefined', function() {
|
||||
var chain = new jasmineUnderTest.ExpectationFilterChain();
|
||||
chain.addFilter({});
|
||||
expect(chain.buildFailureMessage()).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('When some filters have #buildFailureMessage', function() {
|
||||
it('calls the first filter that has #buildFailureMessage', function() {
|
||||
var first = jasmine.createSpy('first').and.returnValue('first'),
|
||||
second = jasmine.createSpy('second').and.returnValue('second'),
|
||||
chain = new jasmineUnderTest.ExpectationFilterChain()
|
||||
.addFilter({ buildFailureMessage: first })
|
||||
.addFilter({ buildFailureMessage: second }),
|
||||
matcherResult = { pass: false },
|
||||
matcherName = 'foo',
|
||||
args = [],
|
||||
matchersUtil = {},
|
||||
result;
|
||||
|
||||
result = chain.buildFailureMessage(
|
||||
matcherResult,
|
||||
matcherName,
|
||||
args,
|
||||
matchersUtil
|
||||
);
|
||||
|
||||
expect(first).toHaveBeenCalledWith(
|
||||
matcherResult,
|
||||
matcherName,
|
||||
args,
|
||||
matchersUtil
|
||||
);
|
||||
expect(second).not.toHaveBeenCalled();
|
||||
expect(result).toEqual('first');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#modifyFailureMessage', function() {
|
||||
describe('When no filters have #modifyFailureMessage', function() {
|
||||
it('returns the original message', function() {
|
||||
var chain = new jasmineUnderTest.ExpectationFilterChain();
|
||||
chain.addFilter({});
|
||||
expect(chain.modifyFailureMessage('msg')).toEqual('msg');
|
||||
});
|
||||
});
|
||||
|
||||
describe('When some filters have #modifyFailureMessage', function() {
|
||||
it('calls the first filter that has #modifyFailureMessage', function() {
|
||||
var first = jasmine.createSpy('first').and.returnValue('first'),
|
||||
second = jasmine.createSpy('second').and.returnValue('second'),
|
||||
chain = new jasmineUnderTest.ExpectationFilterChain()
|
||||
.addFilter({ modifyFailureMessage: first })
|
||||
.addFilter({ modifyFailureMessage: second }),
|
||||
result;
|
||||
|
||||
result = chain.modifyFailureMessage('original');
|
||||
|
||||
expect(first).toHaveBeenCalledWith('original');
|
||||
expect(second).not.toHaveBeenCalled();
|
||||
expect(result).toEqual('first');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,61 +1,126 @@
|
||||
describe("buildExpectationResult", function() {
|
||||
it("defaults to passed", function() {
|
||||
var result = jasmineUnderTest.buildExpectationResult({passed: 'some-value'});
|
||||
describe('buildExpectationResult', function() {
|
||||
it('defaults to passed', function() {
|
||||
var result = jasmineUnderTest.buildExpectationResult({
|
||||
passed: 'some-value'
|
||||
});
|
||||
expect(result.passed).toBe('some-value');
|
||||
});
|
||||
|
||||
it("message defaults to Passed for passing specs", function() {
|
||||
var result = jasmineUnderTest.buildExpectationResult({passed: true, message: 'some-value'});
|
||||
it('message defaults to Passed for passing specs', function() {
|
||||
var result = jasmineUnderTest.buildExpectationResult({
|
||||
passed: true,
|
||||
message: 'some-value'
|
||||
});
|
||||
expect(result.message).toBe('Passed.');
|
||||
});
|
||||
|
||||
it("message returns the message for failing expectations", function() {
|
||||
var result = jasmineUnderTest.buildExpectationResult({passed: false, message: 'some-value'});
|
||||
it('message returns the message for failing expectations', function() {
|
||||
var result = jasmineUnderTest.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);
|
||||
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 = jasmineUnderTest.buildExpectationResult(
|
||||
{
|
||||
passed: false,
|
||||
error: fakeError,
|
||||
messageFormatter: messageFormatter
|
||||
});
|
||||
var result = jasmineUnderTest.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);
|
||||
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 = jasmineUnderTest.buildExpectationResult(
|
||||
{
|
||||
passed: false,
|
||||
error: fakeError,
|
||||
stackFormatter: stackFormatter
|
||||
});
|
||||
var result = jasmineUnderTest.buildExpectationResult({
|
||||
passed: false,
|
||||
error: fakeError,
|
||||
stackFormatter: stackFormatter
|
||||
});
|
||||
|
||||
expect(stackFormatter).toHaveBeenCalledWith(fakeError);
|
||||
expect(result.stack).toEqual('foo');
|
||||
});
|
||||
|
||||
it("matcherName returns passed matcherName", function() {
|
||||
var result = jasmineUnderTest.buildExpectationResult({matcherName: 'some-value'});
|
||||
it('delegates stack formatting to the provided formatter if there was a provided errorForStack', function() {
|
||||
var fakeError = { stack: 'foo' },
|
||||
stackFormatter = jasmine
|
||||
.createSpy('stack formatter')
|
||||
.and.returnValue(fakeError.stack);
|
||||
|
||||
var result = jasmineUnderTest.buildExpectationResult({
|
||||
passed: false,
|
||||
errorForStack: fakeError,
|
||||
stackFormatter: stackFormatter
|
||||
});
|
||||
|
||||
expect(stackFormatter).toHaveBeenCalledWith(fakeError);
|
||||
expect(result.stack).toEqual('foo');
|
||||
});
|
||||
|
||||
it('matcherName returns passed matcherName', function() {
|
||||
var result = jasmineUnderTest.buildExpectationResult({
|
||||
matcherName: 'some-value'
|
||||
});
|
||||
expect(result.matcherName).toBe('some-value');
|
||||
});
|
||||
|
||||
it("expected returns passed expected", function() {
|
||||
var result = jasmineUnderTest.buildExpectationResult({expected: 'some-value'});
|
||||
it('expected returns passed expected', function() {
|
||||
var result = jasmineUnderTest.buildExpectationResult({
|
||||
expected: 'some-value'
|
||||
});
|
||||
expect(result.expected).toBe('some-value');
|
||||
});
|
||||
|
||||
it("actual returns passed actual", function() {
|
||||
var result = jasmineUnderTest.buildExpectationResult({actual: 'some-value'});
|
||||
it('actual returns passed actual', function() {
|
||||
var result = jasmineUnderTest.buildExpectationResult({
|
||||
actual: 'some-value'
|
||||
});
|
||||
expect(result.actual).toBe('some-value');
|
||||
});
|
||||
|
||||
it('handles nodejs assertions', function() {
|
||||
if (typeof require === 'undefined') {
|
||||
return;
|
||||
}
|
||||
var assert = require('assert');
|
||||
var error;
|
||||
var value = 8421;
|
||||
var expectedValue = 'JasmineExpectationTestValue';
|
||||
try {
|
||||
assert.equal(value, expectedValue);
|
||||
} catch (e) {
|
||||
error = e;
|
||||
}
|
||||
|
||||
expect(error.code).toEqual('ERR_ASSERTION');
|
||||
expect(error.actual).toEqual(value);
|
||||
expect(error.expected).toEqual(expectedValue);
|
||||
expect(error.operator).toEqual('==');
|
||||
|
||||
var result = jasmineUnderTest.buildExpectationResult({
|
||||
passed: false,
|
||||
matcherName: '',
|
||||
expected: '',
|
||||
actual: '',
|
||||
error: error
|
||||
});
|
||||
|
||||
expect(result.code).toEqual('ERR_ASSERTION');
|
||||
expect(result.actual).toEqual(value);
|
||||
expect(result.expected).toEqual(expectedValue);
|
||||
expect(result.matcherName).toEqual('assert ==');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
describe("Expectation", function() {
|
||||
it("makes custom matchers available to this expectation", function() {
|
||||
describe('Expectation', function() {
|
||||
it('makes custom matchers available to this expectation', function() {
|
||||
var matchers = {
|
||||
toFoo: function() {},
|
||||
toBar: function() {}
|
||||
},
|
||||
expectation;
|
||||
|
||||
expectation = new jasmineUnderTest.Expectation({
|
||||
expectation = jasmineUnderTest.Expectation.factory({
|
||||
customMatchers: matchers
|
||||
});
|
||||
|
||||
@@ -14,7 +14,7 @@ describe("Expectation", function() {
|
||||
expect(expectation.toBar).toBeDefined();
|
||||
});
|
||||
|
||||
it(".addCoreMatchers makes matchers available to any expectation", function() {
|
||||
it('.addCoreMatchers makes matchers available to any expectation', function() {
|
||||
var coreMatchers = {
|
||||
toQuux: function() {}
|
||||
},
|
||||
@@ -22,45 +22,48 @@ describe("Expectation", function() {
|
||||
|
||||
jasmineUnderTest.Expectation.addCoreMatchers(coreMatchers);
|
||||
|
||||
expectation = new jasmineUnderTest.Expectation({});
|
||||
expectation = jasmineUnderTest.Expectation.factory({});
|
||||
|
||||
expect(expectation.toQuux).toBeDefined();
|
||||
});
|
||||
|
||||
it("Factory builds an expectation/negative expectation", function() {
|
||||
var builtExpectation = jasmineUnderTest.Expectation.Factory();
|
||||
|
||||
expect(builtExpectation instanceof jasmineUnderTest.Expectation).toBe(true);
|
||||
expect(builtExpectation.not instanceof jasmineUnderTest.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 }),
|
||||
var fakeCompare = function() {
|
||||
return { pass: true };
|
||||
},
|
||||
matcherFactory = jasmine
|
||||
.createSpy('matcher')
|
||||
.and.returnValue({ compare: fakeCompare }),
|
||||
matchers = {
|
||||
toFoo: matcherFactory
|
||||
},
|
||||
util = {},
|
||||
matchersUtil = {
|
||||
buildFailureMessage: jasmine.createSpy('buildFailureMessage')
|
||||
},
|
||||
customEqualityTesters = ['a'],
|
||||
addExpectationResult = jasmine.createSpy("addExpectationResult"),
|
||||
addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||
expectation;
|
||||
|
||||
expectation = new jasmineUnderTest.Expectation({
|
||||
util: util,
|
||||
expectation = jasmineUnderTest.Expectation.factory({
|
||||
matchersUtil: matchersUtil,
|
||||
customMatchers: matchers,
|
||||
customEqualityTesters: customEqualityTesters,
|
||||
actual: "an actual",
|
||||
actual: 'an actual',
|
||||
addExpectationResult: addExpectationResult
|
||||
});
|
||||
|
||||
expectation.toFoo("hello");
|
||||
expectation.toFoo('hello');
|
||||
|
||||
expect(matcherFactory).toHaveBeenCalledWith(util, customEqualityTesters)
|
||||
expect(matcherFactory).toHaveBeenCalledWith(
|
||||
matchersUtil,
|
||||
customEqualityTesters
|
||||
);
|
||||
});
|
||||
|
||||
it("wraps matchers's compare functions, passing the actual and expected", function() {
|
||||
var fakeCompare = jasmine.createSpy('fake-compare').and.returnValue({pass: true}),
|
||||
var fakeCompare = jasmine
|
||||
.createSpy('fake-compare')
|
||||
.and.returnValue({ pass: true }),
|
||||
matchers = {
|
||||
toFoo: function() {
|
||||
return {
|
||||
@@ -68,253 +71,275 @@ describe("Expectation", function() {
|
||||
};
|
||||
}
|
||||
},
|
||||
util = {
|
||||
matchersUtil = {
|
||||
buildFailureMessage: jasmine.createSpy('buildFailureMessage')
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy("addExpectationResult"),
|
||||
addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||
expectation;
|
||||
|
||||
expectation = new jasmineUnderTest.Expectation({
|
||||
util: util,
|
||||
expectation = jasmineUnderTest.Expectation.factory({
|
||||
matchersUtil: matchersUtil,
|
||||
customMatchers: matchers,
|
||||
actual: "an actual",
|
||||
actual: 'an actual',
|
||||
addExpectationResult: addExpectationResult
|
||||
});
|
||||
|
||||
expectation.toFoo("hello");
|
||||
expectation.toFoo('hello');
|
||||
|
||||
expect(fakeCompare).toHaveBeenCalledWith("an actual", "hello");
|
||||
expect(fakeCompare).toHaveBeenCalledWith('an actual', 'hello');
|
||||
});
|
||||
|
||||
it("reports a passing result to the spec when the comparison passes", function() {
|
||||
it('reports a passing result to the spec when the comparison passes', function() {
|
||||
var matchers = {
|
||||
toFoo: function() {
|
||||
return {
|
||||
compare: function() { return { pass: true }; }
|
||||
compare: function() {
|
||||
return { pass: true };
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
util = {
|
||||
matchersUtil = {
|
||||
buildFailureMessage: jasmine.createSpy('buildFailureMessage')
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy("addExpectationResult"),
|
||||
addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||
expectation;
|
||||
|
||||
expectation = new jasmineUnderTest.Expectation({
|
||||
expectation = jasmineUnderTest.Expectation.factory({
|
||||
customMatchers: matchers,
|
||||
util: util,
|
||||
actual: "an actual",
|
||||
matchersUtil: matchersUtil,
|
||||
actual: 'an actual',
|
||||
addExpectationResult: addExpectationResult
|
||||
});
|
||||
|
||||
expectation.toFoo("hello");
|
||||
expectation.toFoo('hello');
|
||||
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(true, {
|
||||
matcherName: "toFoo",
|
||||
matcherName: 'toFoo',
|
||||
passed: true,
|
||||
message: "",
|
||||
expected: "hello",
|
||||
actual: "an actual"
|
||||
message: '',
|
||||
error: undefined,
|
||||
expected: 'hello',
|
||||
actual: 'an actual',
|
||||
errorForStack: undefined
|
||||
});
|
||||
});
|
||||
|
||||
it("reports a failing result to the spec when the comparison fails", function() {
|
||||
it('reports a failing result to the spec when the comparison fails', function() {
|
||||
var matchers = {
|
||||
toFoo: function() {
|
||||
return {
|
||||
compare: function() { return { pass: false }; }
|
||||
compare: function() {
|
||||
return { pass: false };
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
util = {
|
||||
buildFailureMessage: function() { return ""; }
|
||||
matchersUtil = {
|
||||
buildFailureMessage: function() {
|
||||
return '';
|
||||
}
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy("addExpectationResult"),
|
||||
addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||
expectation;
|
||||
|
||||
expectation = new jasmineUnderTest.Expectation({
|
||||
expectation = jasmineUnderTest.Expectation.factory({
|
||||
customMatchers: matchers,
|
||||
util: util,
|
||||
actual: "an actual",
|
||||
matchersUtil: matchersUtil,
|
||||
actual: 'an actual',
|
||||
addExpectationResult: addExpectationResult
|
||||
});
|
||||
|
||||
expectation.toFoo("hello");
|
||||
expectation.toFoo('hello');
|
||||
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(false, {
|
||||
matcherName: "toFoo",
|
||||
matcherName: 'toFoo',
|
||||
passed: false,
|
||||
expected: "hello",
|
||||
actual: "an actual",
|
||||
message: ""
|
||||
expected: 'hello',
|
||||
actual: 'an actual',
|
||||
message: '',
|
||||
error: undefined,
|
||||
errorForStack: undefined
|
||||
});
|
||||
});
|
||||
|
||||
it("reports a failing result and a custom fail message to the spec when the comparison fails", function() {
|
||||
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"
|
||||
message: 'I am a custom message'
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy("addExpectationResult"),
|
||||
addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||
expectation;
|
||||
|
||||
expectation = new jasmineUnderTest.Expectation({
|
||||
actual: "an actual",
|
||||
expectation = jasmineUnderTest.Expectation.factory({
|
||||
actual: 'an actual',
|
||||
customMatchers: matchers,
|
||||
addExpectationResult: addExpectationResult
|
||||
});
|
||||
|
||||
expectation.toFoo("hello");
|
||||
expectation.toFoo('hello');
|
||||
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(false, {
|
||||
matcherName: "toFoo",
|
||||
matcherName: 'toFoo',
|
||||
passed: false,
|
||||
expected: "hello",
|
||||
actual: "an actual",
|
||||
message: "I am a custom message"
|
||||
expected: 'hello',
|
||||
actual: 'an actual',
|
||||
message: 'I am a custom message',
|
||||
error: undefined,
|
||||
errorForStack: undefined
|
||||
});
|
||||
});
|
||||
|
||||
it("reports a failing result with a custom fail message function to the spec when the comparison fails", function() {
|
||||
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"; }
|
||||
message: function() {
|
||||
return 'I am a custom message';
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy("addExpectationResult"),
|
||||
addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||
expectation;
|
||||
|
||||
expectation = new jasmineUnderTest.Expectation({
|
||||
expectation = jasmineUnderTest.Expectation.factory({
|
||||
customMatchers: matchers,
|
||||
actual: "an actual",
|
||||
actual: 'an actual',
|
||||
addExpectationResult: addExpectationResult
|
||||
});
|
||||
|
||||
expectation.toFoo("hello");
|
||||
expectation.toFoo('hello');
|
||||
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(false, {
|
||||
matcherName: "toFoo",
|
||||
matcherName: 'toFoo',
|
||||
passed: false,
|
||||
expected: "hello",
|
||||
actual: "an actual",
|
||||
message: "I am a custom message"
|
||||
expected: 'hello',
|
||||
actual: 'an actual',
|
||||
message: 'I am a custom message',
|
||||
error: undefined,
|
||||
errorForStack: undefined
|
||||
});
|
||||
});
|
||||
|
||||
it("reports a passing result to the spec when the comparison fails for a negative expectation", function() {
|
||||
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 }; }
|
||||
compare: function() {
|
||||
return { pass: false };
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
util = {
|
||||
buildFailureMessage: function() { return ""; }
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy("addExpectationResult"),
|
||||
actual = "an actual",
|
||||
addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||
actual = 'an actual',
|
||||
expectation;
|
||||
|
||||
expectation = new jasmineUnderTest.Expectation({
|
||||
expectation = jasmineUnderTest.Expectation.factory({
|
||||
customMatchers: matchers,
|
||||
actual: "an actual",
|
||||
addExpectationResult: addExpectationResult,
|
||||
isNot: true
|
||||
});
|
||||
actual: 'an actual',
|
||||
addExpectationResult: addExpectationResult
|
||||
}).not;
|
||||
|
||||
expectation.toFoo("hello");
|
||||
expectation.toFoo('hello');
|
||||
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(true, {
|
||||
matcherName: "toFoo",
|
||||
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 jasmineUnderTest.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",
|
||||
message: '',
|
||||
error: undefined,
|
||||
expected: 'hello',
|
||||
actual: actual,
|
||||
message: "default message"
|
||||
errorForStack: undefined
|
||||
});
|
||||
});
|
||||
|
||||
it("reports a failing result and a custom fail message to the spec when the comparison passes for a negative expectation", function() {
|
||||
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 };
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
matchersUtil = {
|
||||
buildFailureMessage: function() {
|
||||
return 'default message';
|
||||
}
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||
actual = 'an actual',
|
||||
expectation;
|
||||
|
||||
expectation = jasmineUnderTest.Expectation.factory({
|
||||
customMatchers: matchers,
|
||||
actual: 'an actual',
|
||||
matchersUtil: matchersUtil,
|
||||
addExpectationResult: addExpectationResult
|
||||
}).not;
|
||||
|
||||
expectation.toFoo('hello');
|
||||
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(false, {
|
||||
matcherName: 'toFoo',
|
||||
passed: false,
|
||||
expected: 'hello',
|
||||
actual: actual,
|
||||
message: 'default message',
|
||||
error: undefined,
|
||||
errorForStack: undefined
|
||||
});
|
||||
});
|
||||
|
||||
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"
|
||||
message: 'I am a custom message'
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy("addExpectationResult"),
|
||||
actual = "an actual",
|
||||
addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||
actual = 'an actual',
|
||||
expectation;
|
||||
|
||||
expectation = new jasmineUnderTest.Expectation({
|
||||
expectation = jasmineUnderTest.Expectation.factory({
|
||||
customMatchers: matchers,
|
||||
actual: "an actual",
|
||||
addExpectationResult: addExpectationResult,
|
||||
isNot: true
|
||||
});
|
||||
actual: 'an actual',
|
||||
addExpectationResult: addExpectationResult
|
||||
}).not;
|
||||
|
||||
expectation.toFoo("hello");
|
||||
expectation.toFoo('hello');
|
||||
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(false, {
|
||||
matcherName: "toFoo",
|
||||
matcherName: 'toFoo',
|
||||
passed: false,
|
||||
expected: "hello",
|
||||
expected: 'hello',
|
||||
actual: actual,
|
||||
message: "I am a custom message"
|
||||
message: 'I am a custom message',
|
||||
error: undefined,
|
||||
errorForStack: undefined
|
||||
});
|
||||
});
|
||||
|
||||
@@ -322,30 +347,35 @@ describe("Expectation", function() {
|
||||
var matchers = {
|
||||
toFoo: function() {
|
||||
return {
|
||||
compare: function() { return { pass: true }; },
|
||||
negativeCompare: function() { return { pass: true }; }
|
||||
compare: function() {
|
||||
return { pass: true };
|
||||
},
|
||||
negativeCompare: function() {
|
||||
return { pass: true };
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy("addExpectationResult"),
|
||||
actual = "an actual",
|
||||
addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||
actual = 'an actual',
|
||||
expectation;
|
||||
|
||||
expectation = new jasmineUnderTest.Expectation({
|
||||
expectation = jasmineUnderTest.Expectation.factory({
|
||||
customMatchers: matchers,
|
||||
actual: "an actual",
|
||||
addExpectationResult: addExpectationResult,
|
||||
isNot: true
|
||||
});
|
||||
actual: 'an actual',
|
||||
addExpectationResult: addExpectationResult
|
||||
}).not;
|
||||
|
||||
expectation.toFoo("hello");
|
||||
expectation.toFoo('hello');
|
||||
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(true, {
|
||||
matcherName: "toFoo",
|
||||
matcherName: 'toFoo',
|
||||
passed: true,
|
||||
expected: "hello",
|
||||
expected: 'hello',
|
||||
actual: actual,
|
||||
message: ""
|
||||
message: '',
|
||||
error: undefined,
|
||||
errorForStack: undefined
|
||||
});
|
||||
});
|
||||
|
||||
@@ -353,7 +383,9 @@ describe("Expectation", function() {
|
||||
var matchers = {
|
||||
toFoo: function() {
|
||||
return {
|
||||
compare: function() { return { pass: true }; },
|
||||
compare: function() {
|
||||
return { pass: true };
|
||||
},
|
||||
negativeCompare: function() {
|
||||
return {
|
||||
pass: false,
|
||||
@@ -363,27 +395,322 @@ describe("Expectation", function() {
|
||||
};
|
||||
}
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy("addExpectationResult"),
|
||||
actual = "an actual",
|
||||
addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||
actual = 'an actual',
|
||||
expectation;
|
||||
|
||||
expectation = new jasmineUnderTest.Expectation({
|
||||
expectation = jasmineUnderTest.Expectation.factory({
|
||||
customMatchers: matchers,
|
||||
actual: "an actual",
|
||||
addExpectationResult: addExpectationResult,
|
||||
isNot: true
|
||||
});
|
||||
actual: 'an actual',
|
||||
addExpectationResult: addExpectationResult
|
||||
}).not;
|
||||
|
||||
expectation.toFoo("hello");
|
||||
expectation.toFoo('hello');
|
||||
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(false, {
|
||||
matcherName: "toFoo",
|
||||
matcherName: 'toFoo',
|
||||
passed: false,
|
||||
expected: "hello",
|
||||
expected: 'hello',
|
||||
actual: actual,
|
||||
message: "I'm a custom message"
|
||||
message: "I'm a custom message",
|
||||
error: undefined,
|
||||
errorForStack: undefined
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
it('reports a custom error message to the spec', function() {
|
||||
var customError = new Error('I am a custom error');
|
||||
var matchers = {
|
||||
toFoo: function() {
|
||||
return {
|
||||
compare: function() {
|
||||
return {
|
||||
pass: false,
|
||||
message: 'I am a custom message',
|
||||
error: customError
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||
expectation;
|
||||
|
||||
expectation = jasmineUnderTest.Expectation.factory({
|
||||
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',
|
||||
error: customError,
|
||||
errorForStack: undefined
|
||||
});
|
||||
});
|
||||
|
||||
it("reports a custom message to the spec when a 'not' comparison fails", function() {
|
||||
var customError = new Error('I am a custom error');
|
||||
var matchers = {
|
||||
toFoo: function() {
|
||||
return {
|
||||
compare: function() {
|
||||
return {
|
||||
pass: true,
|
||||
message: 'I am a custom message',
|
||||
error: customError
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||
expectation;
|
||||
|
||||
expectation = jasmineUnderTest.Expectation.factory({
|
||||
actual: 'an actual',
|
||||
customMatchers: matchers,
|
||||
addExpectationResult: addExpectationResult
|
||||
}).not;
|
||||
|
||||
expectation.toFoo('hello');
|
||||
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(false, {
|
||||
matcherName: 'toFoo',
|
||||
passed: false,
|
||||
expected: 'hello',
|
||||
actual: 'an actual',
|
||||
message: 'I am a custom message',
|
||||
error: customError,
|
||||
errorForStack: undefined
|
||||
});
|
||||
});
|
||||
|
||||
it("reports a custom message func to the spec when a 'not' comparison fails", function() {
|
||||
var customError = new Error('I am a custom error');
|
||||
var matchers = {
|
||||
toFoo: function() {
|
||||
return {
|
||||
compare: function() {
|
||||
return {
|
||||
pass: true,
|
||||
message: function() {
|
||||
return 'I am a custom message';
|
||||
},
|
||||
error: customError
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||
expectation;
|
||||
|
||||
expectation = jasmineUnderTest.Expectation.factory({
|
||||
actual: 'an actual',
|
||||
customMatchers: matchers,
|
||||
addExpectationResult: addExpectationResult
|
||||
}).not;
|
||||
|
||||
expectation.toFoo('hello');
|
||||
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(false, {
|
||||
matcherName: 'toFoo',
|
||||
passed: false,
|
||||
expected: 'hello',
|
||||
actual: 'an actual',
|
||||
message: 'I am a custom message',
|
||||
error: customError,
|
||||
errorForStack: undefined
|
||||
});
|
||||
});
|
||||
|
||||
describe('#withContext', function() {
|
||||
it('prepends the context to the generated failure message', function() {
|
||||
var matchers = {
|
||||
toFoo: function() {
|
||||
return {
|
||||
compare: function() {
|
||||
return { pass: false };
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
matchersUtil = {
|
||||
buildFailureMessage: function() {
|
||||
return 'failure message';
|
||||
}
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||
expectation = jasmineUnderTest.Expectation.factory({
|
||||
customMatchers: matchers,
|
||||
matchersUtil: matchersUtil,
|
||||
actual: 'an actual',
|
||||
addExpectationResult: addExpectationResult
|
||||
});
|
||||
|
||||
expectation.withContext('Some context').toFoo('hello');
|
||||
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(
|
||||
false,
|
||||
jasmine.objectContaining({
|
||||
message: 'Some context: failure message'
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('prepends the context to a custom failure message', function() {
|
||||
var matchers = {
|
||||
toFoo: function() {
|
||||
return {
|
||||
compare: function() {
|
||||
return { pass: false, message: 'msg' };
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||
expectation = jasmineUnderTest.Expectation.factory({
|
||||
customMatchers: matchers,
|
||||
actual: 'an actual',
|
||||
addExpectationResult: addExpectationResult
|
||||
});
|
||||
|
||||
expectation.withContext('Some context').toFoo('hello');
|
||||
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(
|
||||
false,
|
||||
jasmine.objectContaining({
|
||||
message: 'Some context: msg'
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('indents a multiline failure message', function() {
|
||||
var matchers = {
|
||||
toFoo: function() {
|
||||
return {
|
||||
compare: function() {
|
||||
return { pass: false, message: 'a\nmultiline\nmessage' };
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||
expectation = jasmineUnderTest.Expectation.factory({
|
||||
customMatchers: matchers,
|
||||
actual: 'an actual',
|
||||
addExpectationResult: addExpectationResult
|
||||
}),
|
||||
actualMessage;
|
||||
|
||||
expectation.withContext('Some context').toFoo('hello');
|
||||
|
||||
actualMessage = addExpectationResult.calls.argsFor(0)[1].message;
|
||||
expect(actualMessage).toEqual(
|
||||
'Some context:\n a\n multiline\n message'
|
||||
);
|
||||
});
|
||||
|
||||
it('prepends the context to a custom failure message from a function', function() {
|
||||
var matchers = {
|
||||
toFoo: function() {
|
||||
return {
|
||||
compare: function() {
|
||||
return {
|
||||
pass: false,
|
||||
message: function() {
|
||||
return 'msg';
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||
expectation = jasmineUnderTest.Expectation.factory({
|
||||
customMatchers: matchers,
|
||||
actual: 'an actual',
|
||||
addExpectationResult: addExpectationResult
|
||||
});
|
||||
|
||||
expectation.withContext('Some context').toFoo('hello');
|
||||
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(
|
||||
false,
|
||||
jasmine.objectContaining({
|
||||
message: 'Some context: msg'
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('works with #not', function() {
|
||||
var matchers = {
|
||||
toFoo: function() {
|
||||
return {
|
||||
compare: function() {
|
||||
return { pass: true };
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||
pp = jasmineUnderTest.makePrettyPrinter(),
|
||||
expectation = jasmineUnderTest.Expectation.factory({
|
||||
customMatchers: matchers,
|
||||
matchersUtil: new jasmineUnderTest.MatchersUtil({ pp: pp }),
|
||||
actual: 'an actual',
|
||||
addExpectationResult: addExpectationResult
|
||||
});
|
||||
|
||||
expectation.withContext('Some context').not.toFoo();
|
||||
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(
|
||||
false,
|
||||
jasmine.objectContaining({
|
||||
message: "Some context: Expected 'an actual' not to foo."
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('works with #not and a custom message', function() {
|
||||
var customError = new Error('I am a custom error');
|
||||
var matchers = {
|
||||
toFoo: function() {
|
||||
return {
|
||||
compare: function() {
|
||||
return {
|
||||
pass: true,
|
||||
message: function() {
|
||||
return 'I am a custom message';
|
||||
},
|
||||
error: customError
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||
expectation = jasmineUnderTest.Expectation.factory({
|
||||
actual: 'an actual',
|
||||
customMatchers: matchers,
|
||||
addExpectationResult: addExpectationResult
|
||||
});
|
||||
|
||||
expectation.withContext('Some context').not.toFoo('hello');
|
||||
|
||||
expect(addExpectationResult).toHaveBeenCalledWith(
|
||||
false,
|
||||
jasmine.objectContaining({
|
||||
message: 'Some context: I am a custom message'
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
421
spec/core/GlobalErrorsSpec.js
Normal file
421
spec/core/GlobalErrorsSpec.js
Normal file
@@ -0,0 +1,421 @@
|
||||
describe('GlobalErrors', function() {
|
||||
it('calls the added handler on error', function() {
|
||||
var fakeGlobal = { onerror: null },
|
||||
handler = jasmine.createSpy('errorHandler'),
|
||||
errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
|
||||
|
||||
errors.install();
|
||||
errors.pushListener(handler);
|
||||
|
||||
fakeGlobal.onerror('foo');
|
||||
|
||||
expect(handler).toHaveBeenCalledWith('foo');
|
||||
});
|
||||
|
||||
it('enables external interception of error by overriding global.onerror', function() {
|
||||
var fakeGlobal = { onerror: null },
|
||||
handler = jasmine.createSpy('errorHandler'),
|
||||
hijackHandler = jasmine.createSpy('hijackErrorHandler'),
|
||||
errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
|
||||
|
||||
errors.install();
|
||||
errors.pushListener(handler);
|
||||
|
||||
fakeGlobal.onerror = hijackHandler;
|
||||
|
||||
fakeGlobal.onerror('foo');
|
||||
|
||||
expect(hijackHandler).toHaveBeenCalledWith('foo');
|
||||
expect(handler).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('calls the global error handler with all parameters', function() {
|
||||
var fakeGlobal = { onerror: null },
|
||||
handler = jasmine.createSpy('errorHandler'),
|
||||
errors = new jasmineUnderTest.GlobalErrors(fakeGlobal),
|
||||
fooError = new Error('foo');
|
||||
|
||||
errors.install();
|
||||
errors.pushListener(handler);
|
||||
|
||||
fakeGlobal.onerror(fooError.message, 'foo.js', 1, 1, fooError);
|
||||
|
||||
expect(handler).toHaveBeenCalledWith(
|
||||
fooError.message,
|
||||
'foo.js',
|
||||
1,
|
||||
1,
|
||||
fooError
|
||||
);
|
||||
});
|
||||
|
||||
it('only calls the most recent handler', function() {
|
||||
var fakeGlobal = { onerror: null },
|
||||
handler1 = jasmine.createSpy('errorHandler1'),
|
||||
handler2 = jasmine.createSpy('errorHandler2'),
|
||||
errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
|
||||
|
||||
errors.install();
|
||||
errors.pushListener(handler1);
|
||||
errors.pushListener(handler2);
|
||||
|
||||
fakeGlobal.onerror('foo');
|
||||
|
||||
expect(handler1).not.toHaveBeenCalled();
|
||||
expect(handler2).toHaveBeenCalledWith('foo');
|
||||
});
|
||||
|
||||
it('calls previous handlers when one is removed', function() {
|
||||
var fakeGlobal = { onerror: null },
|
||||
handler1 = jasmine.createSpy('errorHandler1'),
|
||||
handler2 = jasmine.createSpy('errorHandler2'),
|
||||
errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
|
||||
|
||||
errors.install();
|
||||
errors.pushListener(handler1);
|
||||
errors.pushListener(handler2);
|
||||
|
||||
errors.popListener(handler2);
|
||||
|
||||
fakeGlobal.onerror('foo');
|
||||
|
||||
expect(handler1).toHaveBeenCalledWith('foo');
|
||||
expect(handler2).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('throws when no listener is passed to #popListener', function() {
|
||||
var errors = new jasmineUnderTest.GlobalErrors({});
|
||||
expect(function() {
|
||||
errors.popListener();
|
||||
}).toThrowError('popListener expects a listener');
|
||||
});
|
||||
|
||||
it('uninstalls itself, putting back a previous callback', function() {
|
||||
var originalCallback = jasmine.createSpy('error'),
|
||||
fakeGlobal = { onerror: originalCallback },
|
||||
errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
|
||||
|
||||
expect(fakeGlobal.onerror).toBe(originalCallback);
|
||||
|
||||
errors.install();
|
||||
|
||||
expect(fakeGlobal.onerror).not.toBe(originalCallback);
|
||||
|
||||
errors.uninstall();
|
||||
|
||||
expect(fakeGlobal.onerror).toBe(originalCallback);
|
||||
});
|
||||
|
||||
it('rethrows the original error when there is no handler', function() {
|
||||
var fakeGlobal = {},
|
||||
errors = new jasmineUnderTest.GlobalErrors(fakeGlobal),
|
||||
originalError = new Error('nope');
|
||||
|
||||
errors.install();
|
||||
|
||||
try {
|
||||
fakeGlobal.onerror(originalError);
|
||||
} catch (e) {
|
||||
expect(e).toBe(originalError);
|
||||
}
|
||||
|
||||
errors.uninstall();
|
||||
});
|
||||
|
||||
it('reports uncaught exceptions in node.js', function() {
|
||||
var fakeGlobal = {
|
||||
process: {
|
||||
on: jasmine.createSpy('process.on'),
|
||||
removeListener: jasmine.createSpy('process.removeListener'),
|
||||
listeners: jasmine
|
||||
.createSpy('process.listeners')
|
||||
.and.returnValue(['foo']),
|
||||
removeAllListeners: jasmine.createSpy('process.removeAllListeners')
|
||||
}
|
||||
},
|
||||
handler = jasmine.createSpy('errorHandler'),
|
||||
errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
|
||||
|
||||
errors.install();
|
||||
expect(fakeGlobal.process.on).toHaveBeenCalledWith(
|
||||
'uncaughtException',
|
||||
jasmine.any(Function)
|
||||
);
|
||||
expect(fakeGlobal.process.listeners).toHaveBeenCalledWith(
|
||||
'uncaughtException'
|
||||
);
|
||||
expect(fakeGlobal.process.removeAllListeners).toHaveBeenCalledWith(
|
||||
'uncaughtException'
|
||||
);
|
||||
|
||||
errors.pushListener(handler);
|
||||
|
||||
var addedListener = fakeGlobal.process.on.calls.argsFor(0)[1];
|
||||
addedListener(new Error('bar'));
|
||||
|
||||
expect(handler).toHaveBeenCalledWith(new Error('bar'));
|
||||
expect(handler.calls.argsFor(0)[0].jasmineMessage).toBe(
|
||||
'Uncaught exception: Error: bar'
|
||||
);
|
||||
|
||||
errors.uninstall();
|
||||
|
||||
expect(fakeGlobal.process.removeListener).toHaveBeenCalledWith(
|
||||
'uncaughtException',
|
||||
addedListener
|
||||
);
|
||||
expect(fakeGlobal.process.on).toHaveBeenCalledWith(
|
||||
'uncaughtException',
|
||||
'foo'
|
||||
);
|
||||
});
|
||||
|
||||
describe('Reporting unhandled promise rejections in node.js', function() {
|
||||
it('reports rejections with `Error` reasons', function() {
|
||||
var fakeGlobal = {
|
||||
process: {
|
||||
on: jasmine.createSpy('process.on'),
|
||||
removeListener: jasmine.createSpy('process.removeListener'),
|
||||
listeners: jasmine
|
||||
.createSpy('process.listeners')
|
||||
.and.returnValue(['foo']),
|
||||
removeAllListeners: jasmine.createSpy('process.removeAllListeners')
|
||||
}
|
||||
},
|
||||
handler = jasmine.createSpy('errorHandler'),
|
||||
errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
|
||||
|
||||
errors.install();
|
||||
expect(fakeGlobal.process.on).toHaveBeenCalledWith(
|
||||
'unhandledRejection',
|
||||
jasmine.any(Function)
|
||||
);
|
||||
expect(fakeGlobal.process.listeners).toHaveBeenCalledWith(
|
||||
'unhandledRejection'
|
||||
);
|
||||
expect(fakeGlobal.process.removeAllListeners).toHaveBeenCalledWith(
|
||||
'unhandledRejection'
|
||||
);
|
||||
|
||||
errors.pushListener(handler);
|
||||
|
||||
var addedListener = fakeGlobal.process.on.calls.argsFor(1)[1];
|
||||
addedListener(new Error('bar'));
|
||||
|
||||
expect(handler).toHaveBeenCalledWith(new Error('bar'));
|
||||
expect(handler.calls.argsFor(0)[0].jasmineMessage).toBe(
|
||||
'Unhandled promise rejection: Error: bar'
|
||||
);
|
||||
|
||||
errors.uninstall();
|
||||
|
||||
expect(fakeGlobal.process.removeListener).toHaveBeenCalledWith(
|
||||
'unhandledRejection',
|
||||
addedListener
|
||||
);
|
||||
expect(fakeGlobal.process.on).toHaveBeenCalledWith(
|
||||
'unhandledRejection',
|
||||
'foo'
|
||||
);
|
||||
});
|
||||
|
||||
it('reports rejections with non-`Error` reasons', function() {
|
||||
var fakeGlobal = {
|
||||
process: {
|
||||
on: jasmine.createSpy('process.on'),
|
||||
removeListener: function() {},
|
||||
listeners: function() {
|
||||
return [];
|
||||
},
|
||||
removeAllListeners: function() {}
|
||||
}
|
||||
},
|
||||
handler = jasmine.createSpy('errorHandler'),
|
||||
errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
|
||||
|
||||
errors.install();
|
||||
errors.pushListener(handler);
|
||||
|
||||
expect(fakeGlobal.process.on.calls.argsFor(1)[0]).toEqual(
|
||||
'unhandledRejection'
|
||||
);
|
||||
var addedListener = fakeGlobal.process.on.calls.argsFor(1)[1];
|
||||
addedListener(17);
|
||||
|
||||
expect(handler).toHaveBeenCalledWith(
|
||||
new Error(
|
||||
'Unhandled promise rejection: 17\n' +
|
||||
'(Tip: to get a useful stack trace, use ' +
|
||||
'Promise.reject(new Error(...)) instead of Promise.reject(...).)'
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
it('reports rejections with no reason provided', function() {
|
||||
var fakeGlobal = {
|
||||
process: {
|
||||
on: jasmine.createSpy('process.on'),
|
||||
removeListener: function() {},
|
||||
listeners: function() {
|
||||
return [];
|
||||
},
|
||||
removeAllListeners: function() {}
|
||||
}
|
||||
},
|
||||
handler = jasmine.createSpy('errorHandler'),
|
||||
errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
|
||||
|
||||
errors.install();
|
||||
errors.pushListener(handler);
|
||||
|
||||
expect(fakeGlobal.process.on.calls.argsFor(1)[0]).toEqual(
|
||||
'unhandledRejection'
|
||||
);
|
||||
var addedListener = fakeGlobal.process.on.calls.argsFor(1)[1];
|
||||
addedListener(undefined);
|
||||
|
||||
expect(handler).toHaveBeenCalledWith(
|
||||
new Error(
|
||||
'Unhandled promise rejection with no error or message\n' +
|
||||
'(Tip: to get a useful stack trace, use ' +
|
||||
'Promise.reject(new Error(...)) instead of Promise.reject().)'
|
||||
)
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Reporting unhandled promise rejections in the browser', function() {
|
||||
it('subscribes and unsubscribes from the unhandledrejection event', function() {
|
||||
var fakeGlobal = jasmine.createSpyObj('globalErrors', [
|
||||
'addEventListener',
|
||||
'removeEventListener',
|
||||
'onerror'
|
||||
]),
|
||||
errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
|
||||
|
||||
errors.install();
|
||||
expect(fakeGlobal.addEventListener).toHaveBeenCalledWith(
|
||||
'unhandledrejection',
|
||||
jasmine.any(Function)
|
||||
);
|
||||
|
||||
var addedListener = fakeGlobal.addEventListener.calls.argsFor(0)[1];
|
||||
errors.uninstall();
|
||||
|
||||
expect(fakeGlobal.removeEventListener).toHaveBeenCalledWith(
|
||||
'unhandledrejection',
|
||||
addedListener
|
||||
);
|
||||
});
|
||||
|
||||
it('reports rejections whose reason is a string', function() {
|
||||
var fakeGlobal = jasmine.createSpyObj('globalErrors', [
|
||||
'addEventListener',
|
||||
'removeEventListener',
|
||||
'onerror'
|
||||
]),
|
||||
handler = jasmine.createSpy('errorHandler'),
|
||||
errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
|
||||
|
||||
errors.install();
|
||||
errors.pushListener(handler);
|
||||
|
||||
var addedListener = fakeGlobal.addEventListener.calls.argsFor(0)[1];
|
||||
addedListener({ reason: 'nope' });
|
||||
|
||||
expect(handler).toHaveBeenCalledWith('Unhandled promise rejection: nope');
|
||||
});
|
||||
|
||||
it('reports rejections whose reason is an Error', function() {
|
||||
var fakeGlobal = jasmine.createSpyObj('globalErrors', [
|
||||
'addEventListener',
|
||||
'removeEventListener',
|
||||
'onerror'
|
||||
]),
|
||||
handler = jasmine.createSpy('errorHandler'),
|
||||
errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
|
||||
|
||||
errors.install();
|
||||
errors.pushListener(handler);
|
||||
|
||||
var addedListener = fakeGlobal.addEventListener.calls.argsFor(0)[1];
|
||||
var reason;
|
||||
|
||||
try {
|
||||
// Throwing ensures that we get a stack property in all browsers
|
||||
throw new Error('bar');
|
||||
} catch (e) {
|
||||
reason = e;
|
||||
}
|
||||
|
||||
addedListener({ reason: reason });
|
||||
|
||||
expect(handler).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
jasmineMessage: 'Unhandled promise rejection: Error: bar',
|
||||
message: reason.message,
|
||||
stack: reason.stack
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
describe('Enabling external interception of reported rejections by overriding global.onerror', function() {
|
||||
it('overriding global.onerror intercepts rejections whose reason is a string', function() {
|
||||
var fakeGlobal = jasmine.createSpyObj('globalErrors', [
|
||||
'addEventListener'
|
||||
]),
|
||||
handler = jasmine.createSpy('errorHandler'),
|
||||
hijackHandler = jasmine.createSpy('hijackErrorHandler'),
|
||||
errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
|
||||
|
||||
errors.install();
|
||||
errors.pushListener(handler);
|
||||
|
||||
fakeGlobal.onerror = hijackHandler;
|
||||
|
||||
var addedListener = fakeGlobal.addEventListener.calls.argsFor(0)[1];
|
||||
addedListener({ reason: 'nope' });
|
||||
|
||||
expect(hijackHandler).toHaveBeenCalledWith(
|
||||
'Unhandled promise rejection: nope'
|
||||
);
|
||||
expect(handler).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('overriding global.onerror intercepts rejections whose reason is an Error', function() {
|
||||
var fakeGlobal = jasmine.createSpyObj('globalErrors', [
|
||||
'addEventListener'
|
||||
]),
|
||||
handler = jasmine.createSpy('errorHandler'),
|
||||
hijackHandler = jasmine.createSpy('hijackErrorHandler'),
|
||||
errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
|
||||
|
||||
errors.install();
|
||||
errors.pushListener(handler);
|
||||
|
||||
fakeGlobal.onerror = hijackHandler;
|
||||
|
||||
var addedListener = fakeGlobal.addEventListener.calls.argsFor(0)[1];
|
||||
var reason;
|
||||
|
||||
try {
|
||||
// Throwing ensures that we get a stack property in all browsers
|
||||
throw new Error('bar');
|
||||
} catch (e) {
|
||||
reason = e;
|
||||
}
|
||||
|
||||
addedListener({ reason: reason });
|
||||
|
||||
expect(hijackHandler).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
jasmineMessage: 'Unhandled promise rejection: Error: bar',
|
||||
message: reason.message,
|
||||
stack: reason.stack
|
||||
})
|
||||
);
|
||||
expect(handler).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,87 +1,5 @@
|
||||
xdescribe('JsApiReporter (integration specs)', function() {
|
||||
describe('results', function() {
|
||||
var reporter, spec1, spec2;
|
||||
var env;
|
||||
var suite, nestedSuite, nestedSpec;
|
||||
|
||||
beforeEach(function() {
|
||||
env = new jasmineUnderTest.Env();
|
||||
|
||||
suite = env.describe("top-level suite", function() {
|
||||
spec1 = env.it("spec 1", function() {
|
||||
this.expect(true).toEqual(true);
|
||||
|
||||
});
|
||||
|
||||
spec2 = env.it("spec 2", function() {
|
||||
this.expect(true).toEqual(false);
|
||||
});
|
||||
|
||||
nestedSuite = env.describe("nested suite", function() {
|
||||
nestedSpec = env.it("nested spec", function() {
|
||||
expect(true).toEqual(true);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
reporter = new jasmineUnderTest.JsApiReporter({});
|
||||
env.addReporter(reporter);
|
||||
|
||||
env.execute();
|
||||
|
||||
});
|
||||
|
||||
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() {
|
||||
expect(reporter.suites()).toEqual([
|
||||
{ id: 0, name: 'top-level suite', type: 'suite',
|
||||
children: [
|
||||
{ id: 0, name: 'spec 1', type: 'spec', children: [ ] },
|
||||
{ id: 1, name: 'spec 2', type: 'spec', children: [ ] },
|
||||
{ id: 1, name: 'nested suite', type: 'suite',
|
||||
children: [
|
||||
{ id: 2, name: 'nested spec', type: 'spec', children: [ ] }
|
||||
]
|
||||
},
|
||||
]
|
||||
}
|
||||
]);
|
||||
});
|
||||
|
||||
describe("#summarizeResult_", function() {
|
||||
it("should summarize a passing result", function() {
|
||||
var result = reporter.results()[spec1.id];
|
||||
var summarizedResult = reporter.summarizeResult_(result);
|
||||
expect(summarizedResult.result).toEqual('passed');
|
||||
expect(summarizedResult.messages.length).toEqual(0);
|
||||
});
|
||||
|
||||
it("should have a stack trace for failing specs", function() {
|
||||
var result = reporter.results()[spec2.id];
|
||||
var summarizedResult = reporter.summarizeResult_(result);
|
||||
expect(summarizedResult.result).toEqual('failed');
|
||||
expect(summarizedResult.messages[0].trace.stack).toEqual(result.messages[0].trace.stack);
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe("JsApiReporter", function() {
|
||||
|
||||
it("knows when a full environment is started", function() {
|
||||
describe('JsApiReporter', function() {
|
||||
it('knows when a full environment is started', function() {
|
||||
var reporter = new jasmineUnderTest.JsApiReporter({});
|
||||
|
||||
expect(reporter.started).toBe(false);
|
||||
@@ -93,7 +11,7 @@ describe("JsApiReporter", function() {
|
||||
expect(reporter.finished).toBe(false);
|
||||
});
|
||||
|
||||
it("knows when a full environment is done", function() {
|
||||
it('knows when a full environment is done', function() {
|
||||
var reporter = new jasmineUnderTest.JsApiReporter({});
|
||||
|
||||
expect(reporter.started).toBe(false);
|
||||
@@ -127,58 +45,60 @@ describe("JsApiReporter", function() {
|
||||
expect(reporter.status()).toEqual('done');
|
||||
});
|
||||
|
||||
it("tracks a suite", function() {
|
||||
it('tracks a suite', function() {
|
||||
var reporter = new jasmineUnderTest.JsApiReporter({});
|
||||
|
||||
reporter.suiteStarted({
|
||||
id: 123,
|
||||
description: "A suite"
|
||||
description: 'A suite'
|
||||
});
|
||||
|
||||
var suites = reporter.suites();
|
||||
|
||||
expect(suites).toEqual({123: {id: 123, description: "A suite"}});
|
||||
expect(suites).toEqual({ 123: { id: 123, description: 'A suite' } });
|
||||
|
||||
reporter.suiteDone({
|
||||
id: 123,
|
||||
description: "A suite",
|
||||
description: 'A suite',
|
||||
status: 'passed'
|
||||
});
|
||||
|
||||
expect(suites).toEqual({123: {id: 123, description: "A suite", status: 'passed'}});
|
||||
expect(suites).toEqual({
|
||||
123: { id: 123, description: 'A suite', status: 'passed' }
|
||||
});
|
||||
});
|
||||
|
||||
describe("#specResults", function() {
|
||||
describe('#specResults', function() {
|
||||
var reporter, specResult1, specResult2;
|
||||
beforeEach(function() {
|
||||
reporter = new jasmineUnderTest.JsApiReporter({});
|
||||
specResult1 = {
|
||||
id: 1,
|
||||
description: "A spec"
|
||||
description: 'A spec'
|
||||
};
|
||||
specResult2 = {
|
||||
id: 2,
|
||||
description: "Another spec"
|
||||
description: 'Another spec'
|
||||
};
|
||||
|
||||
reporter.specDone(specResult1);
|
||||
reporter.specDone(specResult2);
|
||||
});
|
||||
|
||||
it("should return a slice of results", function() {
|
||||
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() {
|
||||
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(){
|
||||
describe('#suiteResults', function() {
|
||||
var reporter, suiteResult1, suiteResult2;
|
||||
beforeEach(function() {
|
||||
reporter = new jasmineUnderTest.JsApiReporter({});
|
||||
@@ -192,7 +112,7 @@ describe("JsApiReporter", function() {
|
||||
};
|
||||
suiteResult2 = {
|
||||
id: 2,
|
||||
status: 'finished'
|
||||
status: 'passed'
|
||||
};
|
||||
|
||||
reporter.suiteStarted(suiteStarted1);
|
||||
@@ -200,37 +120,37 @@ describe("JsApiReporter", function() {
|
||||
reporter.suiteDone(suiteResult2);
|
||||
});
|
||||
|
||||
it('should not include suite starts', function(){
|
||||
expect(reporter.suiteResults(0,3).length).toEqual(2);
|
||||
it('should not include suite starts', function() {
|
||||
expect(reporter.suiteResults(0, 3).length).toEqual(2);
|
||||
});
|
||||
|
||||
it("should return a slice of results", function() {
|
||||
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() {
|
||||
it('returns nothing for out of bounds indices', 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() {
|
||||
describe('#executionTime', function() {
|
||||
it('should start the timer when jasmine starts', function() {
|
||||
var timerSpy = jasmine.createSpyObj('timer', ['start', 'elapsed']),
|
||||
reporter = new jasmineUnderTest.JsApiReporter({
|
||||
timer: timerSpy
|
||||
});
|
||||
reporter = new jasmineUnderTest.JsApiReporter({
|
||||
timer: timerSpy
|
||||
});
|
||||
|
||||
reporter.jasmineStarted();
|
||||
expect(timerSpy.start).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should return the time it took the specs to run, in ms", function() {
|
||||
it('should return the time it took the specs to run, in ms', function() {
|
||||
var timerSpy = jasmine.createSpyObj('timer', ['start', 'elapsed']),
|
||||
reporter = new jasmineUnderTest.JsApiReporter({
|
||||
timer: timerSpy
|
||||
});
|
||||
reporter = new jasmineUnderTest.JsApiReporter({
|
||||
timer: timerSpy
|
||||
});
|
||||
|
||||
timerSpy.elapsed.and.returnValue(1000);
|
||||
reporter.jasmineDone();
|
||||
@@ -238,11 +158,11 @@ describe("JsApiReporter", function() {
|
||||
});
|
||||
|
||||
describe("when the specs haven't finished being run", function() {
|
||||
it("should return undefined", function() {
|
||||
it('should return undefined', function() {
|
||||
var timerSpy = jasmine.createSpyObj('timer', ['start', 'elapsed']),
|
||||
reporter = new jasmineUnderTest.JsApiReporter({
|
||||
timer: timerSpy
|
||||
});
|
||||
reporter = new jasmineUnderTest.JsApiReporter({
|
||||
timer: timerSpy
|
||||
});
|
||||
|
||||
expect(reporter.executionTime()).toBeUndefined();
|
||||
});
|
||||
@@ -252,8 +172,8 @@ describe("JsApiReporter", function() {
|
||||
describe('#runDetails', function() {
|
||||
it('should have details about the run', function() {
|
||||
var reporter = new jasmineUnderTest.JsApiReporter({});
|
||||
reporter.jasmineDone({some: {run: 'details'}});
|
||||
expect(reporter.runDetails).toEqual({some: {run: 'details'}});
|
||||
reporter.jasmineDone({ some: { run: 'details' } });
|
||||
expect(reporter.runDetails).toEqual({ some: { run: 'details' } });
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
describe("FakeDate", function() {
|
||||
it("does not fail if no global date is found", function() {
|
||||
describe('FakeDate', function() {
|
||||
it('does not fail if no global date is found', function() {
|
||||
var fakeGlobal = {},
|
||||
mockDate = new jasmineUnderTest.MockDate(fakeGlobal);
|
||||
|
||||
@@ -10,11 +10,11 @@ describe("FakeDate", function() {
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it("replaces the global Date when it is installed", function() {
|
||||
var globalDate = jasmine.createSpy("global Date").and.callFake(function() {
|
||||
it('replaces the global Date when it is installed', function() {
|
||||
var globalDate = jasmine.createSpy('global Date').and.callFake(function() {
|
||||
return {
|
||||
getTime: function() {}
|
||||
}
|
||||
};
|
||||
}),
|
||||
fakeGlobal = { Date: globalDate },
|
||||
mockDate = new jasmineUnderTest.MockDate(fakeGlobal);
|
||||
@@ -25,11 +25,11 @@ describe("FakeDate", function() {
|
||||
expect(fakeGlobal.Date).not.toEqual(globalDate);
|
||||
});
|
||||
|
||||
it("replaces the global Date on uninstall", function() {
|
||||
var globalDate = jasmine.createSpy("global Date").and.callFake(function() {
|
||||
it('replaces the global Date on uninstall', function() {
|
||||
var globalDate = jasmine.createSpy('global Date').and.callFake(function() {
|
||||
return {
|
||||
getTime: function() {}
|
||||
}
|
||||
};
|
||||
}),
|
||||
fakeGlobal = { Date: globalDate },
|
||||
mockDate = new jasmineUnderTest.MockDate(fakeGlobal);
|
||||
@@ -40,13 +40,13 @@ describe("FakeDate", function() {
|
||||
expect(fakeGlobal.Date).toEqual(globalDate);
|
||||
});
|
||||
|
||||
it("takes the current time as the base when installing without parameters", function() {
|
||||
var globalDate = jasmine.createSpy("global Date").and.callFake(function() {
|
||||
it('takes the current time as the base when installing without parameters', function() {
|
||||
var globalDate = jasmine.createSpy('global Date').and.callFake(function() {
|
||||
return {
|
||||
getTime: function() {
|
||||
return 1000;
|
||||
}
|
||||
}
|
||||
};
|
||||
}),
|
||||
fakeGlobal = { Date: globalDate },
|
||||
mockDate = new jasmineUnderTest.MockDate(fakeGlobal);
|
||||
@@ -58,7 +58,7 @@ describe("FakeDate", function() {
|
||||
expect(globalDate).toHaveBeenCalledWith(1000);
|
||||
});
|
||||
|
||||
it("can accept a date as time base when installing", function() {
|
||||
it('can accept a date as time base when installing', function() {
|
||||
var fakeGlobal = { Date: Date },
|
||||
mockDate = new jasmineUnderTest.MockDate(fakeGlobal),
|
||||
baseDate = new Date();
|
||||
@@ -69,7 +69,7 @@ describe("FakeDate", function() {
|
||||
expect(new fakeGlobal.Date().getTime()).toEqual(123);
|
||||
});
|
||||
|
||||
it("makes real dates", function() {
|
||||
it('makes real dates', function() {
|
||||
var fakeGlobal = { Date: Date },
|
||||
mockDate = new jasmineUnderTest.MockDate(fakeGlobal);
|
||||
|
||||
@@ -78,13 +78,13 @@ describe("FakeDate", function() {
|
||||
expect(new fakeGlobal.Date() instanceof fakeGlobal.Date).toBe(true);
|
||||
});
|
||||
|
||||
it("fakes current time when using Date.now()", function() {
|
||||
var globalDate = jasmine.createSpy("global Date").and.callFake(function() {
|
||||
it('fakes current time when using Date.now()', function() {
|
||||
var globalDate = jasmine.createSpy('global Date').and.callFake(function() {
|
||||
return {
|
||||
getTime: function() {
|
||||
return 1000;
|
||||
}
|
||||
}
|
||||
};
|
||||
}),
|
||||
fakeGlobal = { Date: globalDate };
|
||||
|
||||
@@ -97,28 +97,30 @@ describe("FakeDate", function() {
|
||||
});
|
||||
|
||||
it("does not stub Date.now() if it doesn't already exist", function() {
|
||||
var globalDate = jasmine.createSpy("global Date").and.callFake(function() {
|
||||
var globalDate = jasmine.createSpy('global Date').and.callFake(function() {
|
||||
return {
|
||||
getTime: function() {
|
||||
return 1000;
|
||||
}
|
||||
}
|
||||
};
|
||||
}),
|
||||
fakeGlobal = { Date: globalDate },
|
||||
mockDate = new jasmineUnderTest.MockDate(fakeGlobal);
|
||||
|
||||
mockDate.install();
|
||||
|
||||
expect(fakeGlobal.Date.now).toThrowError("Browser does not support Date.now()");
|
||||
expect(fakeGlobal.Date.now).toThrowError(
|
||||
'Browser does not support Date.now()'
|
||||
);
|
||||
});
|
||||
|
||||
it("makes time passes using tick", function() {
|
||||
var globalDate = jasmine.createSpy("global Date").and.callFake(function() {
|
||||
it('makes time passes using tick', function() {
|
||||
var globalDate = jasmine.createSpy('global Date').and.callFake(function() {
|
||||
return {
|
||||
getTime: function() {
|
||||
return 1000;
|
||||
}
|
||||
}
|
||||
};
|
||||
}),
|
||||
fakeGlobal = { Date: globalDate };
|
||||
|
||||
@@ -136,13 +138,13 @@ describe("FakeDate", function() {
|
||||
expect(fakeGlobal.Date.now()).toEqual(2100);
|
||||
});
|
||||
|
||||
it("allows to increase 0 milliseconds using tick", function() {
|
||||
var globalDate = jasmine.createSpy("global Date").and.callFake(function() {
|
||||
it('allows to increase 0 milliseconds using tick', function() {
|
||||
var globalDate = jasmine.createSpy('global Date').and.callFake(function() {
|
||||
return {
|
||||
getTime: function() {
|
||||
return 1000;
|
||||
}
|
||||
}
|
||||
};
|
||||
}),
|
||||
fakeGlobal = { Date: globalDate };
|
||||
|
||||
@@ -158,14 +160,16 @@ describe("FakeDate", function() {
|
||||
expect(fakeGlobal.Date.now()).toEqual(1000);
|
||||
});
|
||||
|
||||
it("allows creation of a Date in a different time than the mocked time", function() {
|
||||
it('allows creation of a Date in a different time than the mocked time', function() {
|
||||
var fakeGlobal = { Date: Date },
|
||||
mockDate = new jasmineUnderTest.MockDate(fakeGlobal);
|
||||
|
||||
mockDate.install();
|
||||
|
||||
var otherDate = new fakeGlobal.Date(2013, 9, 23, 0, 0, 1, 0);
|
||||
expect(otherDate.getTime()).toEqual(new Date(2013, 9, 23, 0, 0, 1, 0).getTime());
|
||||
expect(otherDate.getTime()).toEqual(
|
||||
new Date(2013, 9, 23, 0, 0, 1, 0).getTime()
|
||||
);
|
||||
});
|
||||
|
||||
it("allows creation of a Date that isn't fully specified", function() {
|
||||
@@ -189,7 +193,7 @@ describe("FakeDate", function() {
|
||||
expect(otherDate.getTime()).toEqual(now);
|
||||
});
|
||||
|
||||
it("copies all Date properties to the mocked date", function() {
|
||||
it('copies all Date properties to the mocked date', function() {
|
||||
var fakeGlobal = { Date: Date },
|
||||
mockDate = new jasmineUnderTest.MockDate(fakeGlobal);
|
||||
|
||||
|
||||
@@ -1,136 +1,305 @@
|
||||
describe("jasmineUnderTest.pp", function () {
|
||||
it("should wrap strings in single quotes", function() {
|
||||
expect(jasmineUnderTest.pp("some string")).toEqual("'some string'");
|
||||
expect(jasmineUnderTest.pp("som' string")).toEqual("'som' string'");
|
||||
describe('PrettyPrinter', function() {
|
||||
it('should wrap strings in single quotes', function() {
|
||||
var pp = jasmineUnderTest.makePrettyPrinter();
|
||||
expect(pp('some string')).toEqual("'some string'");
|
||||
expect(pp("som' string")).toEqual("'som' string'");
|
||||
});
|
||||
|
||||
it("should stringify primitives properly", function() {
|
||||
expect(jasmineUnderTest.pp(true)).toEqual("true");
|
||||
expect(jasmineUnderTest.pp(false)).toEqual("false");
|
||||
expect(jasmineUnderTest.pp(null)).toEqual("null");
|
||||
expect(jasmineUnderTest.pp(jasmine.undefined)).toEqual("undefined");
|
||||
expect(jasmineUnderTest.pp(3)).toEqual("3");
|
||||
expect(jasmineUnderTest.pp(-3.14)).toEqual("-3.14");
|
||||
expect(jasmineUnderTest.pp(-0)).toEqual("-0");
|
||||
it('should stringify primitives properly', function() {
|
||||
var pp = jasmineUnderTest.makePrettyPrinter();
|
||||
expect(pp(true)).toEqual('true');
|
||||
expect(pp(false)).toEqual('false');
|
||||
expect(pp(null)).toEqual('null');
|
||||
expect(pp(jasmine.undefined)).toEqual('undefined');
|
||||
expect(pp(3)).toEqual('3');
|
||||
expect(pp(-3.14)).toEqual('-3.14');
|
||||
expect(pp(-0)).toEqual('-0');
|
||||
});
|
||||
|
||||
describe('stringify arrays', function() {
|
||||
it("should stringify arrays properly", function() {
|
||||
expect(jasmineUnderTest.pp([1, 2])).toEqual("[ 1, 2 ]");
|
||||
expect(jasmineUnderTest.pp([1, 'foo', {}, jasmine.undefined, null])).toEqual("[ 1, 'foo', Object({ }), undefined, null ]");
|
||||
describe('stringify sets', function() {
|
||||
it('should stringify sets properly', function() {
|
||||
jasmine.getEnv().requireFunctioningSets();
|
||||
var set = new Set(); // eslint-disable-line compat/compat
|
||||
set.add(1);
|
||||
set.add(2);
|
||||
var pp = jasmineUnderTest.makePrettyPrinter();
|
||||
expect(pp(set)).toEqual('Set( 1, 2 )');
|
||||
});
|
||||
|
||||
it("should truncate arrays that are longer than jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH", function() {
|
||||
var originalMaxLength = jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH;
|
||||
var array = [1, 2, 3];
|
||||
it('should truncate sets with more elements than jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH', function() {
|
||||
jasmine.getEnv().requireFunctioningSets();
|
||||
var originalMaxSize = jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH;
|
||||
|
||||
try {
|
||||
jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = 2;
|
||||
expect(jasmineUnderTest.pp(array)).toEqual("[ 1, 2, ... ]");
|
||||
var set = new Set(); // eslint-disable-line compat/compat
|
||||
set.add('a');
|
||||
set.add('b');
|
||||
set.add('c');
|
||||
var pp = jasmineUnderTest.makePrettyPrinter();
|
||||
expect(pp(set)).toEqual("Set( 'a', 'b', ... )");
|
||||
} finally {
|
||||
jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = originalMaxSize;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('stringify maps', function() {
|
||||
it('should stringify maps properly', function() {
|
||||
jasmine.getEnv().requireFunctioningMaps();
|
||||
var map = new Map(); // eslint-disable-line compat/compat
|
||||
map.set(1, 2);
|
||||
var pp = jasmineUnderTest.makePrettyPrinter();
|
||||
expect(pp(map)).toEqual('Map( [ 1, 2 ] )');
|
||||
});
|
||||
|
||||
it('should truncate maps with more elements than jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH', function() {
|
||||
jasmine.getEnv().requireFunctioningMaps();
|
||||
var originalMaxSize = jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH;
|
||||
|
||||
try {
|
||||
jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = 2;
|
||||
var map = new Map(); // eslint-disable-line compat/compat
|
||||
map.set('a', 1);
|
||||
map.set('b', 2);
|
||||
map.set('c', 3);
|
||||
var pp = jasmineUnderTest.makePrettyPrinter();
|
||||
expect(pp(map)).toEqual("Map( [ 'a', 1 ], [ 'b', 2 ], ... )");
|
||||
} finally {
|
||||
jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = originalMaxSize;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('stringify arrays', function() {
|
||||
it('should stringify arrays properly', function() {
|
||||
var pp = jasmineUnderTest.makePrettyPrinter();
|
||||
expect(pp([1, 2])).toEqual('[ 1, 2 ]');
|
||||
expect(pp([1, 'foo', {}, jasmine.undefined, null])).toEqual(
|
||||
"[ 1, 'foo', Object({ }), undefined, null ]"
|
||||
);
|
||||
});
|
||||
|
||||
it('should truncate arrays that are longer than jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH', function() {
|
||||
var originalMaxLength = jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH;
|
||||
var array = [1, 2, 3];
|
||||
var pp = jasmineUnderTest.makePrettyPrinter();
|
||||
|
||||
try {
|
||||
jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = 2;
|
||||
expect(pp(array)).toEqual('[ 1, 2, ... ]');
|
||||
} finally {
|
||||
jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = originalMaxLength;
|
||||
}
|
||||
});
|
||||
|
||||
it("should stringify arrays with properties properly", function() {
|
||||
it('should stringify arrays with properties properly', function() {
|
||||
var pp = jasmineUnderTest.makePrettyPrinter();
|
||||
var arr = [1, 2];
|
||||
arr.foo = 'bar';
|
||||
arr.baz = {};
|
||||
expect(jasmineUnderTest.pp(arr)).toEqual("[ 1, 2, foo: 'bar', baz: Object({ }) ]");
|
||||
expect(pp(arr)).toEqual("[ 1, 2, foo: 'bar', baz: Object({ }) ]");
|
||||
});
|
||||
|
||||
it("should stringify empty arrays with properties properly", function() {
|
||||
it('should stringify empty arrays with properties properly', function() {
|
||||
var pp = jasmineUnderTest.makePrettyPrinter();
|
||||
var empty = [];
|
||||
empty.foo = 'bar';
|
||||
empty.baz = {};
|
||||
expect(jasmineUnderTest.pp(empty)).toEqual("[ foo: 'bar', baz: Object({ }) ]");
|
||||
expect(pp(empty)).toEqual("[ foo: 'bar', baz: Object({ }) ]");
|
||||
});
|
||||
|
||||
it("should stringify long arrays with properties properly", function() {
|
||||
it('should stringify long arrays with properties properly', function() {
|
||||
var pp = jasmineUnderTest.makePrettyPrinter();
|
||||
var originalMaxLength = jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH;
|
||||
var long = [1,2,3];
|
||||
var long = [1, 2, 3];
|
||||
long.foo = 'bar';
|
||||
long.baz = {};
|
||||
|
||||
try {
|
||||
jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = 2;
|
||||
expect(jasmineUnderTest.pp(long)).toEqual("[ 1, 2, ..., foo: 'bar', baz: Object({ }) ]");
|
||||
expect(pp(long)).toEqual(
|
||||
"[ 1, 2, ..., foo: 'bar', baz: Object({ }) ]"
|
||||
);
|
||||
} finally {
|
||||
jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = originalMaxLength;
|
||||
}
|
||||
});
|
||||
|
||||
it("should indicate circular array references", function() {
|
||||
it('should indicate circular array references', function() {
|
||||
var pp = jasmineUnderTest.makePrettyPrinter();
|
||||
var array1 = [1, 2];
|
||||
var array2 = [array1];
|
||||
array1.push(array2);
|
||||
expect(jasmineUnderTest.pp(array1)).toEqual("[ 1, 2, [ <circular reference: Array> ] ]");
|
||||
expect(pp(array1)).toEqual('[ 1, 2, [ <circular reference: Array> ] ]');
|
||||
});
|
||||
|
||||
it("should not indicate circular references incorrectly", function() {
|
||||
var array = [ [1] ];
|
||||
expect(jasmineUnderTest.pp(array)).toEqual("[ [ 1 ] ]");
|
||||
it('should not indicate circular references incorrectly', function() {
|
||||
var pp = jasmineUnderTest.makePrettyPrinter();
|
||||
var array = [[1]];
|
||||
expect(pp(array)).toEqual('[ [ 1 ] ]');
|
||||
});
|
||||
});
|
||||
|
||||
it("should stringify objects properly", function() {
|
||||
expect(jasmineUnderTest.pp({foo: 'bar'})).toEqual("Object({ foo: 'bar' })");
|
||||
expect(jasmineUnderTest.pp({foo:'bar', baz:3, nullValue: null, undefinedValue: jasmine.undefined})).toEqual("Object({ foo: 'bar', baz: 3, nullValue: null, undefinedValue: undefined })");
|
||||
expect(jasmineUnderTest.pp({foo: function () {
|
||||
}, bar: [1, 2, 3]})).toEqual("Object({ foo: Function, bar: [ 1, 2, 3 ] })");
|
||||
it('should stringify objects properly', function() {
|
||||
var pp = jasmineUnderTest.makePrettyPrinter();
|
||||
expect(pp({ foo: 'bar' })).toEqual("Object({ foo: 'bar' })");
|
||||
expect(
|
||||
pp({
|
||||
foo: 'bar',
|
||||
baz: 3,
|
||||
nullValue: null,
|
||||
undefinedValue: jasmine.undefined
|
||||
})
|
||||
).toEqual(
|
||||
"Object({ foo: 'bar', baz: 3, nullValue: null, undefinedValue: undefined })"
|
||||
);
|
||||
expect(pp({ foo: function() {}, bar: [1, 2, 3] })).toEqual(
|
||||
'Object({ foo: Function, bar: [ 1, 2, 3 ] })'
|
||||
);
|
||||
});
|
||||
|
||||
it("should not include inherited properties when stringifying an object", function() {
|
||||
it('should stringify objects that almost look like DOM nodes', function() {
|
||||
var pp = jasmineUnderTest.makePrettyPrinter();
|
||||
expect(pp({ nodeType: 1 })).toEqual('Object({ nodeType: 1 })');
|
||||
});
|
||||
|
||||
it('should truncate objects with too many keys', function() {
|
||||
var pp = jasmineUnderTest.makePrettyPrinter();
|
||||
var originalMaxLength = jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH;
|
||||
var long = { a: 1, b: 2, c: 3 };
|
||||
|
||||
try {
|
||||
jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = 2;
|
||||
expect(pp(long)).toEqual('Object({ a: 1, b: 2, ... })');
|
||||
} finally {
|
||||
jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH = originalMaxLength;
|
||||
}
|
||||
});
|
||||
|
||||
function withMaxChars(maxChars, fn) {
|
||||
var originalMaxChars = jasmineUnderTest.MAX_PRETTY_PRINT_CHARS;
|
||||
|
||||
try {
|
||||
jasmineUnderTest.MAX_PRETTY_PRINT_CHARS = maxChars;
|
||||
fn();
|
||||
} finally {
|
||||
jasmineUnderTest.MAX_PRETTY_PRINT_CHARS = originalMaxChars;
|
||||
}
|
||||
}
|
||||
|
||||
it('should truncate outputs that are too long', function() {
|
||||
var pp = jasmineUnderTest.makePrettyPrinter();
|
||||
var big = [{ a: 1, b: 'a long string' }, {}];
|
||||
|
||||
withMaxChars(34, function() {
|
||||
expect(pp(big)).toEqual("[ Object({ a: 1, b: 'a long st ...");
|
||||
});
|
||||
});
|
||||
|
||||
it('should not serialize more objects after hitting MAX_PRETTY_PRINT_CHARS', function() {
|
||||
var a = {
|
||||
jasmineToString: function() {
|
||||
return 'object a';
|
||||
}
|
||||
},
|
||||
b = {
|
||||
jasmineToString: function() {
|
||||
return 'object b';
|
||||
}
|
||||
},
|
||||
c = {
|
||||
jasmineToString: jasmine
|
||||
.createSpy('c jasmineToString')
|
||||
.and.returnValue('')
|
||||
},
|
||||
d = {
|
||||
jasmineToString: jasmine
|
||||
.createSpy('d jasmineToString')
|
||||
.and.returnValue('')
|
||||
},
|
||||
pp = jasmineUnderTest.makePrettyPrinter();
|
||||
|
||||
withMaxChars(30, function() {
|
||||
pp([{ a: a, b: b, c: c }, d]);
|
||||
expect(c.jasmineToString).not.toHaveBeenCalled();
|
||||
expect(d.jasmineToString).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
it("should print 'null' as the constructor of an object with its own constructor property", function() {
|
||||
var pp = jasmineUnderTest.makePrettyPrinter();
|
||||
expect(pp({ constructor: function() {} })).toContain('null({');
|
||||
expect(pp({ constructor: 'foo' })).toContain('null({');
|
||||
});
|
||||
|
||||
it('should not include inherited properties when stringifying an object', function() {
|
||||
var pp = jasmineUnderTest.makePrettyPrinter();
|
||||
var SomeClass = function SomeClass() {};
|
||||
SomeClass.prototype.foo = "inherited foo";
|
||||
SomeClass.prototype.foo = 'inherited foo';
|
||||
var instance = new SomeClass();
|
||||
instance.bar = "my own bar";
|
||||
expect(jasmineUnderTest.pp(instance)).toEqual("SomeClass({ bar: 'my own bar' })");
|
||||
instance.bar = 'my own bar';
|
||||
expect(pp(instance)).toEqual("SomeClass({ bar: 'my own bar' })");
|
||||
});
|
||||
|
||||
it("should not recurse objects and arrays more deeply than jasmineUnderTest.MAX_PRETTY_PRINT_DEPTH", function() {
|
||||
it('should not recurse objects and arrays more deeply than jasmineUnderTest.MAX_PRETTY_PRINT_DEPTH', function() {
|
||||
var pp = jasmineUnderTest.makePrettyPrinter();
|
||||
var originalMaxDepth = jasmineUnderTest.MAX_PRETTY_PRINT_DEPTH;
|
||||
var nestedObject = { level1: { level2: { level3: { level4: "leaf" } } } };
|
||||
var nestedArray = [1, [2, [3, [4, "leaf"]]]];
|
||||
var nestedObject = { level1: { level2: { level3: { level4: 'leaf' } } } };
|
||||
var nestedArray = [1, [2, [3, [4, 'leaf']]]];
|
||||
|
||||
try {
|
||||
jasmineUnderTest.MAX_PRETTY_PRINT_DEPTH = 2;
|
||||
expect(jasmineUnderTest.pp(nestedObject)).toEqual("Object({ level1: Object({ level2: Object }) })");
|
||||
expect(jasmineUnderTest.pp(nestedArray)).toEqual("[ 1, [ 2, Array ] ]");
|
||||
expect(pp(nestedObject)).toEqual(
|
||||
'Object({ level1: Object({ level2: Object }) })'
|
||||
);
|
||||
expect(pp(nestedArray)).toEqual('[ 1, [ 2, Array ] ]');
|
||||
|
||||
jasmineUnderTest.MAX_PRETTY_PRINT_DEPTH = 3;
|
||||
expect(jasmineUnderTest.pp(nestedObject)).toEqual("Object({ level1: Object({ level2: Object({ level3: Object }) }) })");
|
||||
expect(jasmineUnderTest.pp(nestedArray)).toEqual("[ 1, [ 2, [ 3, Array ] ] ]");
|
||||
expect(pp(nestedObject)).toEqual(
|
||||
'Object({ level1: Object({ level2: Object({ level3: Object }) }) })'
|
||||
);
|
||||
expect(pp(nestedArray)).toEqual('[ 1, [ 2, [ 3, Array ] ] ]');
|
||||
|
||||
jasmineUnderTest.MAX_PRETTY_PRINT_DEPTH = 4;
|
||||
expect(jasmineUnderTest.pp(nestedObject)).toEqual("Object({ level1: Object({ level2: Object({ level3: Object({ level4: 'leaf' }) }) }) })");
|
||||
expect(jasmineUnderTest.pp(nestedArray)).toEqual("[ 1, [ 2, [ 3, [ 4, 'leaf' ] ] ] ]");
|
||||
expect(pp(nestedObject)).toEqual(
|
||||
"Object({ level1: Object({ level2: Object({ level3: Object({ level4: 'leaf' }) }) }) })"
|
||||
);
|
||||
expect(pp(nestedArray)).toEqual("[ 1, [ 2, [ 3, [ 4, 'leaf' ] ] ] ]");
|
||||
} finally {
|
||||
jasmineUnderTest.MAX_PRETTY_PRINT_DEPTH = originalMaxDepth;
|
||||
}
|
||||
});
|
||||
|
||||
it("should stringify immutable circular objects", function(){
|
||||
if(Object.freeze){
|
||||
var frozenObject = {foo: {bar: 'baz'}};
|
||||
it('should stringify immutable circular objects', function() {
|
||||
if (Object.freeze) {
|
||||
var pp = jasmineUnderTest.makePrettyPrinter();
|
||||
var frozenObject = { foo: { bar: 'baz' } };
|
||||
frozenObject.circular = frozenObject;
|
||||
frozenObject = Object.freeze(frozenObject);
|
||||
expect(jasmineUnderTest.pp(frozenObject)).toEqual("Object({ foo: Object({ bar: 'baz' }), circular: <circular reference: Object> })");
|
||||
expect(pp(frozenObject)).toEqual(
|
||||
"Object({ foo: Object({ bar: 'baz' }), circular: <circular reference: Object> })"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
it("should stringify RegExp objects properly", function() {
|
||||
expect(jasmineUnderTest.pp(/x|y|z/)).toEqual("/x|y|z/");
|
||||
it('should stringify RegExp objects properly', function() {
|
||||
var pp = jasmineUnderTest.makePrettyPrinter();
|
||||
expect(pp(/x|y|z/)).toEqual('/x|y|z/');
|
||||
});
|
||||
|
||||
it("should indicate circular object references", function() {
|
||||
var sampleValue = {foo: 'hello'};
|
||||
it('should indicate circular object references', function() {
|
||||
var pp = jasmineUnderTest.makePrettyPrinter();
|
||||
var sampleValue = { foo: 'hello' };
|
||||
sampleValue.nested = sampleValue;
|
||||
expect(jasmineUnderTest.pp(sampleValue)).toEqual("Object({ foo: 'hello', nested: <circular reference: Object> })");
|
||||
expect(pp(sampleValue)).toEqual(
|
||||
"Object({ foo: 'hello', nested: <circular reference: Object> })"
|
||||
);
|
||||
});
|
||||
|
||||
it("should indicate getters on objects as such", function() {
|
||||
var sampleValue = {id: 1};
|
||||
it('should indicate getters on objects as such', function() {
|
||||
var pp = jasmineUnderTest.makePrettyPrinter();
|
||||
var sampleValue = { id: 1 };
|
||||
if (sampleValue.__defineGetter__) {
|
||||
//not supported in IE!
|
||||
sampleValue.__defineGetter__('calculatedValue', function() {
|
||||
@@ -138,72 +307,260 @@ describe("jasmineUnderTest.pp", function () {
|
||||
});
|
||||
}
|
||||
if (sampleValue.__defineGetter__) {
|
||||
expect(jasmineUnderTest.pp(sampleValue)).toEqual("Object({ id: 1, calculatedValue: <getter> })");
|
||||
}
|
||||
else {
|
||||
expect(jasmineUnderTest.pp(sampleValue)).toEqual("Object({ id: 1 })");
|
||||
expect(pp(sampleValue)).toEqual(
|
||||
'Object({ id: 1, calculatedValue: <getter> })'
|
||||
);
|
||||
} else {
|
||||
expect(pp(sampleValue)).toEqual('Object({ id: 1 })');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
it('should not do HTML escaping of strings', function() {
|
||||
expect(jasmineUnderTest.pp('some <b>html string</b> &', false)).toEqual('\'some <b>html string</b> &\'');
|
||||
var pp = jasmineUnderTest.makePrettyPrinter();
|
||||
expect(pp('some <b>html string</b> &', false)).toEqual(
|
||||
"'some <b>html string</b> &'"
|
||||
);
|
||||
});
|
||||
|
||||
it("should abbreviate the global (usually window) object", function() {
|
||||
expect(jasmineUnderTest.pp(jasmine.getGlobal())).toEqual("<global>");
|
||||
it('should abbreviate the global (usually window) object', function() {
|
||||
var pp = jasmineUnderTest.makePrettyPrinter();
|
||||
expect(pp(jasmine.getGlobal())).toEqual('<global>');
|
||||
});
|
||||
|
||||
it("should stringify Date objects properly", function() {
|
||||
it('should stringify Date objects properly', function() {
|
||||
var pp = jasmineUnderTest.makePrettyPrinter();
|
||||
var now = new Date();
|
||||
expect(jasmineUnderTest.pp(now)).toEqual("Date(" + now.toString() + ")");
|
||||
expect(pp(now)).toEqual('Date(' + now.toString() + ')');
|
||||
});
|
||||
|
||||
it("should stringify spy objects properly", function() {
|
||||
var TestObject = {
|
||||
describe('with a spy object', function() {
|
||||
var env, pp;
|
||||
|
||||
beforeEach(function() {
|
||||
env = new jasmineUnderTest.Env();
|
||||
pp = jasmineUnderTest.makePrettyPrinter();
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
env.cleanup_();
|
||||
});
|
||||
|
||||
it('should stringify spy objects properly', function() {
|
||||
var TestObject = {
|
||||
someFunction: function() {}
|
||||
};
|
||||
|
||||
var spyRegistry = new jasmineUnderTest.SpyRegistry({
|
||||
currentSpies: function() {
|
||||
return [];
|
||||
},
|
||||
createSpy: function(name, originalFn) {
|
||||
return jasmineUnderTest.Spy(name, originalFn);
|
||||
}
|
||||
});
|
||||
|
||||
spyRegistry.spyOn(TestObject, 'someFunction');
|
||||
expect(pp(TestObject.someFunction)).toEqual('spy on someFunction');
|
||||
|
||||
expect(pp(env.createSpy('something'))).toEqual('spy on something');
|
||||
});
|
||||
|
||||
it('should stringify spyOn toString properly', function() {
|
||||
var TestObject = {
|
||||
someFunction: function() {}
|
||||
},
|
||||
env = new jasmineUnderTest.Env();
|
||||
env = new jasmineUnderTest.Env(),
|
||||
pp = jasmineUnderTest.makePrettyPrinter();
|
||||
|
||||
var spyRegistry = new jasmineUnderTest.SpyRegistry({currentSpies: function() {return [];}});
|
||||
var spyRegistry = new jasmineUnderTest.SpyRegistry({
|
||||
currentSpies: function() {
|
||||
return [];
|
||||
},
|
||||
createSpy: function(name, originalFn) {
|
||||
return jasmineUnderTest.Spy(name, originalFn);
|
||||
}
|
||||
});
|
||||
|
||||
spyRegistry.spyOn(TestObject, 'someFunction');
|
||||
expect(jasmineUnderTest.pp(TestObject.someFunction)).toEqual("spy on someFunction");
|
||||
spyRegistry.spyOn(TestObject, 'toString');
|
||||
var testSpyObj = env.createSpyObj('TheClassName', ['toString']);
|
||||
|
||||
expect(jasmineUnderTest.pp(jasmineUnderTest.createSpy("something"))).toEqual("spy on something");
|
||||
expect(pp(testSpyObj)).toEqual('spy on TheClassName.toString');
|
||||
});
|
||||
});
|
||||
|
||||
it("should stringify objects that implement jasmineToString", function () {
|
||||
it('should stringify objects that implement jasmineToString', function() {
|
||||
var pp = jasmineUnderTest.makePrettyPrinter();
|
||||
var obj = {
|
||||
jasmineToString: function () { return "strung"; }
|
||||
jasmineToString: function() {
|
||||
return 'strung';
|
||||
}
|
||||
};
|
||||
|
||||
expect(jasmineUnderTest.pp(obj)).toEqual("strung");
|
||||
expect(pp(obj)).toEqual('strung');
|
||||
});
|
||||
|
||||
it("should stringify objects that implement custom toString", function () {
|
||||
it('should pass itself to jasmineToString', function() {
|
||||
var pp = jasmineUnderTest.makePrettyPrinter([]);
|
||||
var obj = {
|
||||
toString: function () { return "my toString"; }
|
||||
jasmineToString: jasmine.createSpy('jasmineToString').and.returnValue('')
|
||||
};
|
||||
|
||||
expect(jasmineUnderTest.pp(obj)).toEqual("my toString");
|
||||
pp(obj);
|
||||
expect(obj.jasmineToString).toHaveBeenCalledWith(pp);
|
||||
});
|
||||
|
||||
it("should stringify objects from anonymous constructors with custom toString", function () {
|
||||
var MyAnonymousConstructor = (function() { return function () {}; })();
|
||||
MyAnonymousConstructor.toString = function () { return ''; };
|
||||
it('should stringify objects that implement custom toString', function() {
|
||||
var pp = jasmineUnderTest.makePrettyPrinter();
|
||||
var obj = {
|
||||
toString: function() {
|
||||
return 'my toString';
|
||||
}
|
||||
};
|
||||
|
||||
expect(pp(obj)).toEqual('my toString');
|
||||
|
||||
// Simulate object from another global context (e.g. an iframe or Web Worker) that does not actually have a custom
|
||||
// toString despite obj.toString !== Object.prototype.toString
|
||||
var objFromOtherContext = {
|
||||
foo: 'bar',
|
||||
toString: function() {
|
||||
return Object.prototype.toString.call(this);
|
||||
}
|
||||
};
|
||||
|
||||
expect(pp(objFromOtherContext)).toEqual(
|
||||
"Object({ foo: 'bar', toString: Function })"
|
||||
);
|
||||
});
|
||||
|
||||
it("should stringify objects have have a toString that isn't a function", function() {
|
||||
var pp = jasmineUnderTest.makePrettyPrinter();
|
||||
var obj = {
|
||||
toString: 'foo'
|
||||
};
|
||||
|
||||
expect(pp(obj)).toEqual("Object({ toString: 'foo' })");
|
||||
});
|
||||
|
||||
it('should stringify objects from anonymous constructors with custom toString', function() {
|
||||
var pp = jasmineUnderTest.makePrettyPrinter();
|
||||
var MyAnonymousConstructor = (function() {
|
||||
return function() {};
|
||||
})();
|
||||
MyAnonymousConstructor.toString = function() {
|
||||
return '';
|
||||
};
|
||||
|
||||
var a = new MyAnonymousConstructor();
|
||||
|
||||
expect(jasmineUnderTest.pp(a)).toEqual("<anonymous>({ })");
|
||||
expect(pp(a)).toEqual('<anonymous>({ })');
|
||||
});
|
||||
|
||||
it("should handle objects with null prototype", function() {
|
||||
if (jasmine.getEnv().ieVersion < 9) { return; }
|
||||
|
||||
it('should handle objects with null prototype', function() {
|
||||
var pp = jasmineUnderTest.makePrettyPrinter();
|
||||
var obj = Object.create(null);
|
||||
obj.foo = 'bar';
|
||||
|
||||
expect(jasmineUnderTest.pp(obj)).toEqual("null({ foo: 'bar' })");
|
||||
expect(pp(obj)).toEqual("null({ foo: 'bar' })");
|
||||
});
|
||||
|
||||
it('should gracefully handle objects with invalid toString implementations', function() {
|
||||
var pp = jasmineUnderTest.makePrettyPrinter();
|
||||
var obj = {
|
||||
foo: {
|
||||
toString: function() {
|
||||
// Invalid: toString returning a number
|
||||
return 3;
|
||||
}
|
||||
},
|
||||
bar: {
|
||||
toString: function() {
|
||||
// Really invalid: a nested bad toString().
|
||||
return {
|
||||
toString: function() {
|
||||
return new Date();
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
// Valid: an actual number
|
||||
baz: 3,
|
||||
// Valid: an actual Error object
|
||||
qux: new Error('bar'),
|
||||
//
|
||||
baddy: {
|
||||
toString: function() {
|
||||
throw new Error('I am a bad toString');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
expect(pp(obj)).toEqual(
|
||||
'Object({ foo: [object Number], bar: [object Object], baz: 3, qux: Error: bar, baddy: has-invalid-toString-method })'
|
||||
);
|
||||
});
|
||||
|
||||
describe('Custom object formatters', function() {
|
||||
it('should use the first custom object formatter that does not return undefined', function() {
|
||||
var customObjectFormatters = [
|
||||
function(obj) {
|
||||
return undefined;
|
||||
},
|
||||
function(obj) {
|
||||
return '2nd: ' + obj.foo;
|
||||
},
|
||||
function(obj) {
|
||||
return '3rd: ' + obj.foo;
|
||||
}
|
||||
],
|
||||
pp = jasmineUnderTest.makePrettyPrinter(customObjectFormatters),
|
||||
obj = { foo: 'bar' };
|
||||
|
||||
expect(pp(obj)).toEqual('2nd: bar');
|
||||
});
|
||||
|
||||
it('should fall back to built in logic if all custom object formatters return undefined', function() {
|
||||
var customObjectFormatters = [
|
||||
function(obj) {
|
||||
return undefined;
|
||||
}
|
||||
],
|
||||
pp = jasmineUnderTest.makePrettyPrinter(customObjectFormatters),
|
||||
obj = { foo: 'bar' };
|
||||
|
||||
expect(pp(obj)).toEqual("Object({ foo: 'bar' })");
|
||||
});
|
||||
});
|
||||
|
||||
describe('#customFormat_', function() {
|
||||
it('should use the first custom object formatter that does not return undefined', function() {
|
||||
var customObjectFormatters = [
|
||||
function(obj) {
|
||||
return undefined;
|
||||
},
|
||||
function(obj) {
|
||||
return '2nd: ' + obj.foo;
|
||||
},
|
||||
function(obj) {
|
||||
return '3rd: ' + obj.foo;
|
||||
}
|
||||
],
|
||||
pp = jasmineUnderTest.makePrettyPrinter(customObjectFormatters),
|
||||
obj = { foo: 'bar' };
|
||||
|
||||
expect(pp.customFormat_(obj)).toEqual('2nd: bar');
|
||||
});
|
||||
|
||||
it('should return undefined if all custom object formatters return undefined', function() {
|
||||
var customObjectFormatters = [
|
||||
function(obj) {
|
||||
return undefined;
|
||||
}
|
||||
],
|
||||
pp = jasmineUnderTest.makePrettyPrinter(customObjectFormatters),
|
||||
obj = { foo: 'bar' };
|
||||
|
||||
expect(pp.customFormat_(obj)).toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
describe("QueueRunner", function() {
|
||||
|
||||
describe('QueueRunner', function() {
|
||||
it("runs all the functions it's passed", function() {
|
||||
var calls = [],
|
||||
queueableFn1 = { fn: jasmine.createSpy('fn1') },
|
||||
@@ -19,24 +18,49 @@ describe("QueueRunner", function() {
|
||||
expect(calls).toEqual(['fn1', 'fn2']);
|
||||
});
|
||||
|
||||
it('runs cleanup functions after the others', function() {
|
||||
var calls = [],
|
||||
queueableFn1 = { fn: jasmine.createSpy('fn1') },
|
||||
queueableFn2 = { fn: jasmine.createSpy('fn2') },
|
||||
queueRunner = new jasmineUnderTest.QueueRunner({
|
||||
queueableFns: [queueableFn1],
|
||||
cleanupFns: [queueableFn2]
|
||||
});
|
||||
queueableFn1.fn.and.callFake(function() {
|
||||
calls.push('fn1');
|
||||
});
|
||||
queueableFn2.fn.and.callFake(function() {
|
||||
calls.push('fn2');
|
||||
});
|
||||
|
||||
queueRunner.execute();
|
||||
|
||||
expect(calls).toEqual(['fn1', 'fn2']);
|
||||
});
|
||||
|
||||
it("calls each function with a consistent 'this'-- an empty object", function() {
|
||||
var queueableFn1 = { fn: jasmine.createSpy('fn1') },
|
||||
queueableFn2 = { fn: jasmine.createSpy('fn2') },
|
||||
queueableFn3 = { fn: function(done) { asyncContext = this; done(); } },
|
||||
queueRunner = new jasmineUnderTest.QueueRunner({
|
||||
queueableFns: [queueableFn1, queueableFn2, queueableFn3]
|
||||
}),
|
||||
asyncContext;
|
||||
queueableFn2 = { fn: jasmine.createSpy('fn2') },
|
||||
queueableFn3 = {
|
||||
fn: function(done) {
|
||||
asyncContext = this;
|
||||
done();
|
||||
}
|
||||
},
|
||||
queueRunner = new jasmineUnderTest.QueueRunner({
|
||||
queueableFns: [queueableFn1, queueableFn2, queueableFn3]
|
||||
}),
|
||||
asyncContext;
|
||||
|
||||
queueRunner.execute();
|
||||
|
||||
var context = queueableFn1.fn.calls.first().object;
|
||||
expect(context).toEqual({});
|
||||
expect(context).toEqual(new jasmineUnderTest.UserContext());
|
||||
expect(queueableFn2.fn.calls.first().object).toBe(context);
|
||||
expect(asyncContext).toBe(context);
|
||||
});
|
||||
|
||||
describe("with an asynchronous function", function() {
|
||||
describe('with an asynchronous function', function() {
|
||||
beforeEach(function() {
|
||||
jasmine.clock().install();
|
||||
});
|
||||
@@ -45,7 +69,7 @@ describe("QueueRunner", function() {
|
||||
jasmine.clock().uninstall();
|
||||
});
|
||||
|
||||
it("supports asynchronous functions, only advancing to next function after a done() callback", function() {
|
||||
it('supports asynchronous functions, only advancing to next function after a done() callback', function() {
|
||||
//TODO: it would be nice if spy arity could match the fake, so we could do something like:
|
||||
//createSpy('asyncfn').and.callFake(function(done) {});
|
||||
|
||||
@@ -53,18 +77,24 @@ describe("QueueRunner", function() {
|
||||
beforeCallback = jasmine.createSpy('beforeCallback'),
|
||||
fnCallback = jasmine.createSpy('fnCallback'),
|
||||
afterCallback = jasmine.createSpy('afterCallback'),
|
||||
queueableFn1 = { fn: function(done) {
|
||||
beforeCallback();
|
||||
setTimeout(done, 100);
|
||||
} },
|
||||
queueableFn2 = { fn: function(done) {
|
||||
fnCallback();
|
||||
setTimeout(done, 100);
|
||||
} },
|
||||
queueableFn3 = { fn: function(done) {
|
||||
afterCallback();
|
||||
setTimeout(done, 100);
|
||||
} },
|
||||
queueableFn1 = {
|
||||
fn: function(done) {
|
||||
beforeCallback();
|
||||
setTimeout(done, 100);
|
||||
}
|
||||
},
|
||||
queueableFn2 = {
|
||||
fn: function(done) {
|
||||
fnCallback();
|
||||
setTimeout(done, 100);
|
||||
}
|
||||
},
|
||||
queueableFn3 = {
|
||||
fn: function(done) {
|
||||
afterCallback();
|
||||
setTimeout(done, 100);
|
||||
}
|
||||
},
|
||||
queueRunner = new jasmineUnderTest.QueueRunner({
|
||||
queueableFns: [queueableFn1, queueableFn2, queueableFn3],
|
||||
onComplete: onComplete
|
||||
@@ -93,10 +123,14 @@ describe("QueueRunner", function() {
|
||||
expect(onComplete).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("explicitly fails an async function with a provided fail function and moves to the next function", function() {
|
||||
var queueableFn1 = { fn: function(done) {
|
||||
setTimeout(function() { done.fail('foo'); }, 100);
|
||||
} },
|
||||
it('explicitly fails an async function with a provided fail function and moves to the next function', function() {
|
||||
var queueableFn1 = {
|
||||
fn: function(done) {
|
||||
setTimeout(function() {
|
||||
done.fail('foo');
|
||||
}, 100);
|
||||
}
|
||||
},
|
||||
queueableFn2 = { fn: jasmine.createSpy('fn2') },
|
||||
failFn = jasmine.createSpy('fail'),
|
||||
queueRunner = new jasmineUnderTest.QueueRunner({
|
||||
@@ -115,9 +149,63 @@ describe("QueueRunner", function() {
|
||||
expect(queueableFn2.fn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('explicitly fails an async function when next is called with an Error and moves to the next function', function() {
|
||||
var err = new Error('foo'),
|
||||
queueableFn1 = {
|
||||
fn: function(done) {
|
||||
setTimeout(function() {
|
||||
done(err);
|
||||
}, 100);
|
||||
}
|
||||
},
|
||||
queueableFn2 = { fn: jasmine.createSpy('fn2') },
|
||||
failFn = jasmine.createSpy('fail'),
|
||||
queueRunner = new jasmineUnderTest.QueueRunner({
|
||||
queueableFns: [queueableFn1, queueableFn2],
|
||||
fail: failFn
|
||||
});
|
||||
|
||||
queueRunner.execute();
|
||||
|
||||
expect(failFn).not.toHaveBeenCalled();
|
||||
expect(queueableFn2.fn).not.toHaveBeenCalled();
|
||||
|
||||
jasmine.clock().tick(100);
|
||||
|
||||
expect(failFn).toHaveBeenCalledWith(err);
|
||||
expect(queueableFn2.fn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('does not cause an explicit fail if execution is being stopped', function() {
|
||||
var err = new jasmineUnderTest.StopExecutionError('foo'),
|
||||
queueableFn1 = {
|
||||
fn: function(done) {
|
||||
setTimeout(function() {
|
||||
done(err);
|
||||
}, 100);
|
||||
}
|
||||
},
|
||||
queueableFn2 = { fn: jasmine.createSpy('fn2') },
|
||||
failFn = jasmine.createSpy('fail'),
|
||||
queueRunner = new jasmineUnderTest.QueueRunner({
|
||||
queueableFns: [queueableFn1, queueableFn2],
|
||||
fail: failFn
|
||||
});
|
||||
|
||||
queueRunner.execute();
|
||||
|
||||
expect(failFn).not.toHaveBeenCalled();
|
||||
expect(queueableFn2.fn).not.toHaveBeenCalled();
|
||||
|
||||
jasmine.clock().tick(100);
|
||||
|
||||
expect(failFn).not.toHaveBeenCalled();
|
||||
expect(queueableFn2.fn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("sets a timeout if requested for asynchronous functions so they don't go on forever", function() {
|
||||
var timeout = 3,
|
||||
beforeFn = { fn: function(done) { }, type: 'before', timeout: function() { return timeout; } },
|
||||
beforeFn = { fn: function(done) {}, type: 'before', timeout: timeout },
|
||||
queueableFn = { fn: jasmine.createSpy('fn'), type: 'queueable' },
|
||||
onComplete = jasmine.createSpy('onComplete'),
|
||||
onException = jasmine.createSpy('onException'),
|
||||
@@ -137,15 +225,15 @@ describe("QueueRunner", function() {
|
||||
expect(onComplete).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("by default does not set a timeout for asynchronous functions", function() {
|
||||
var beforeFn = { fn: function(done) { } },
|
||||
it('by default does not set a timeout for asynchronous functions', function() {
|
||||
var beforeFn = { fn: function(done) {} },
|
||||
queueableFn = { fn: jasmine.createSpy('fn') },
|
||||
onComplete = jasmine.createSpy('onComplete'),
|
||||
onException = jasmine.createSpy('onException'),
|
||||
queueRunner = new jasmineUnderTest.QueueRunner({
|
||||
queueableFns: [beforeFn, queueableFn],
|
||||
onComplete: onComplete,
|
||||
onException: onException,
|
||||
onException: onException
|
||||
});
|
||||
|
||||
queueRunner.execute();
|
||||
@@ -158,8 +246,12 @@ describe("QueueRunner", function() {
|
||||
expect(onComplete).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("clears the timeout when an async function throws an exception, to prevent additional exception reporting", function() {
|
||||
var queueableFn = { fn: function(done) { throw new Error("error!"); } },
|
||||
it('clears the timeout when an async function throws an exception, to prevent additional exception reporting', function() {
|
||||
var queueableFn = {
|
||||
fn: function(done) {
|
||||
throw new Error('error!');
|
||||
}
|
||||
},
|
||||
onComplete = jasmine.createSpy('onComplete'),
|
||||
onException = jasmine.createSpy('onException'),
|
||||
queueRunner = new jasmineUnderTest.QueueRunner({
|
||||
@@ -177,8 +269,12 @@ describe("QueueRunner", function() {
|
||||
expect(onException.calls.count()).toEqual(1);
|
||||
});
|
||||
|
||||
it("clears the timeout when the done callback is called", function() {
|
||||
var queueableFn = { fn: function(done) { done(); } },
|
||||
it('clears the timeout when the done callback is called', function() {
|
||||
var queueableFn = {
|
||||
fn: function(done) {
|
||||
done();
|
||||
}
|
||||
},
|
||||
onComplete = jasmine.createSpy('onComplete'),
|
||||
onException = jasmine.createSpy('onException'),
|
||||
queueRunner = new jasmineUnderTest.QueueRunner({
|
||||
@@ -189,44 +285,55 @@ describe("QueueRunner", function() {
|
||||
|
||||
queueRunner.execute();
|
||||
|
||||
jasmine.clock().tick(1);
|
||||
expect(onComplete).toHaveBeenCalled();
|
||||
|
||||
jasmine.clock().tick(jasmineUnderTest.DEFAULT_TIMEOUT_INTERVAL);
|
||||
expect(onException).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("only moves to the next spec the first time you call done", function() {
|
||||
var queueableFn = { fn: function(done) {done(); done();} },
|
||||
nextQueueableFn = { fn: jasmine.createSpy('nextFn') };
|
||||
queueRunner = new jasmineUnderTest.QueueRunner({
|
||||
queueableFns: [queueableFn, nextQueueableFn]
|
||||
});
|
||||
|
||||
queueRunner.execute();
|
||||
expect(nextQueueableFn.fn.calls.count()).toEqual(1);
|
||||
});
|
||||
|
||||
it("does not move to the next spec if done is called after an exception has ended the spec", function() {
|
||||
var queueableFn = { fn: function(done) {
|
||||
setTimeout(done, 1);
|
||||
throw new Error('error!');
|
||||
} },
|
||||
nextQueueableFn = { fn: jasmine.createSpy('nextFn') };
|
||||
queueRunner = new jasmineUnderTest.QueueRunner({
|
||||
queueableFns: [queueableFn, nextQueueableFn]
|
||||
});
|
||||
it('only moves to the next spec the first time you call done', function() {
|
||||
var queueableFn = {
|
||||
fn: function(done) {
|
||||
done();
|
||||
done();
|
||||
}
|
||||
},
|
||||
nextQueueableFn = { fn: jasmine.createSpy('nextFn') },
|
||||
queueRunner = new jasmineUnderTest.QueueRunner({
|
||||
queueableFns: [queueableFn, nextQueueableFn]
|
||||
});
|
||||
|
||||
queueRunner.execute();
|
||||
jasmine.clock().tick(1);
|
||||
expect(nextQueueableFn.fn.calls.count()).toEqual(1);
|
||||
});
|
||||
|
||||
it("should return a null when you call done", function () {
|
||||
it('does not move to the next spec if done is called after an exception has ended the spec', function() {
|
||||
var queueableFn = {
|
||||
fn: function(done) {
|
||||
setTimeout(done, 1);
|
||||
throw new Error('error!');
|
||||
}
|
||||
},
|
||||
nextQueueableFn = { fn: jasmine.createSpy('nextFn') },
|
||||
queueRunner = new jasmineUnderTest.QueueRunner({
|
||||
queueableFns: [queueableFn, nextQueueableFn]
|
||||
});
|
||||
|
||||
queueRunner.execute();
|
||||
jasmine.clock().tick(1);
|
||||
expect(nextQueueableFn.fn.calls.count()).toEqual(1);
|
||||
});
|
||||
|
||||
it('should return a null when you call done', function() {
|
||||
// Some promises want handlers to return anything but undefined to help catch "forgotten returns".
|
||||
var doneReturn,
|
||||
queueableFn = { fn: function(done) {
|
||||
doneReturn = done();
|
||||
} },
|
||||
queueableFn = {
|
||||
fn: function(done) {
|
||||
doneReturn = done();
|
||||
}
|
||||
},
|
||||
queueRunner = new jasmineUnderTest.QueueRunner({
|
||||
queueableFns: [queueableFn]
|
||||
});
|
||||
@@ -234,13 +341,256 @@ describe("QueueRunner", function() {
|
||||
queueRunner.execute();
|
||||
expect(doneReturn).toBe(null);
|
||||
});
|
||||
|
||||
it('continues running functions when an exception is thrown in async code without timing out', function() {
|
||||
var queueableFn = {
|
||||
fn: function(done) {
|
||||
throwAsync();
|
||||
},
|
||||
timeout: 1
|
||||
},
|
||||
nextQueueableFn = { fn: jasmine.createSpy('nextFunction') },
|
||||
onException = jasmine.createSpy('onException'),
|
||||
globalErrors = {
|
||||
pushListener: jasmine.createSpy('pushListener'),
|
||||
popListener: jasmine.createSpy('popListener')
|
||||
},
|
||||
queueRunner = new jasmineUnderTest.QueueRunner({
|
||||
queueableFns: [queueableFn, nextQueueableFn],
|
||||
onException: onException,
|
||||
globalErrors: globalErrors
|
||||
}),
|
||||
throwAsync = function() {
|
||||
globalErrors.pushListener.calls
|
||||
.mostRecent()
|
||||
.args[0](new Error('foo'));
|
||||
jasmine.clock().tick(2);
|
||||
};
|
||||
|
||||
nextQueueableFn.fn.and.callFake(function() {
|
||||
// should remove the same function that was added
|
||||
expect(globalErrors.popListener).toHaveBeenCalledWith(
|
||||
globalErrors.pushListener.calls.argsFor(1)[0]
|
||||
);
|
||||
});
|
||||
|
||||
queueRunner.execute();
|
||||
|
||||
function errorWithMessage(message) {
|
||||
return {
|
||||
asymmetricMatch: function(other) {
|
||||
return new RegExp(message).test(other.message);
|
||||
},
|
||||
toString: function() {
|
||||
return '<Error with message like "' + message + '">';
|
||||
}
|
||||
};
|
||||
}
|
||||
expect(onException).not.toHaveBeenCalledWith(
|
||||
errorWithMessage(/DEFAULT_TIMEOUT_INTERVAL/)
|
||||
);
|
||||
expect(onException).toHaveBeenCalledWith(errorWithMessage(/^foo$/));
|
||||
expect(nextQueueableFn.fn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('handles exceptions thrown while waiting for the stack to clear', function() {
|
||||
var queueableFn = {
|
||||
fn: function(done) {
|
||||
done();
|
||||
}
|
||||
},
|
||||
errorListeners = [],
|
||||
globalErrors = {
|
||||
pushListener: function(f) {
|
||||
errorListeners.push(f);
|
||||
},
|
||||
popListener: function() {
|
||||
errorListeners.pop();
|
||||
}
|
||||
},
|
||||
clearStack = jasmine.createSpy('clearStack'),
|
||||
onException = jasmine.createSpy('onException'),
|
||||
queueRunner = new jasmineUnderTest.QueueRunner({
|
||||
queueableFns: [queueableFn],
|
||||
globalErrors: globalErrors,
|
||||
clearStack: clearStack,
|
||||
onException: onException
|
||||
}),
|
||||
error = new Error('nope');
|
||||
|
||||
queueRunner.execute();
|
||||
jasmine.clock().tick();
|
||||
expect(clearStack).toHaveBeenCalled();
|
||||
expect(errorListeners.length).toEqual(1);
|
||||
errorListeners[0](error);
|
||||
clearStack.calls.argsFor(0)[0]();
|
||||
expect(onException).toHaveBeenCalledWith(error);
|
||||
});
|
||||
});
|
||||
|
||||
it("calls exception handlers when an exception is thrown in a fn", function() {
|
||||
var queueableFn = { type: 'queueable',
|
||||
fn: function() {
|
||||
throw new Error('fake error');
|
||||
} },
|
||||
describe('with a function that returns a promise', function() {
|
||||
function StubPromise() {}
|
||||
|
||||
StubPromise.prototype.then = function(resolve, reject) {
|
||||
this.resolveHandler = resolve;
|
||||
this.rejectHandler = reject;
|
||||
};
|
||||
|
||||
beforeEach(function() {
|
||||
jasmine.clock().install();
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
jasmine.clock().uninstall();
|
||||
});
|
||||
|
||||
it('runs the function asynchronously, advancing once the promise is settled', function() {
|
||||
var onComplete = jasmine.createSpy('onComplete'),
|
||||
fnCallback = jasmine.createSpy('fnCallback'),
|
||||
p1 = new StubPromise(),
|
||||
p2 = new StubPromise(),
|
||||
queueableFn1 = {
|
||||
fn: function() {
|
||||
setTimeout(function() {
|
||||
p1.resolveHandler();
|
||||
}, 100);
|
||||
return p1;
|
||||
}
|
||||
};
|
||||
(queueableFn2 = {
|
||||
fn: function() {
|
||||
fnCallback();
|
||||
setTimeout(function() {
|
||||
p2.resolveHandler();
|
||||
}, 100);
|
||||
return p2;
|
||||
}
|
||||
}),
|
||||
(queueRunner = new jasmineUnderTest.QueueRunner({
|
||||
queueableFns: [queueableFn1, queueableFn2],
|
||||
onComplete: onComplete
|
||||
}));
|
||||
|
||||
queueRunner.execute();
|
||||
expect(fnCallback).not.toHaveBeenCalled();
|
||||
expect(onComplete).not.toHaveBeenCalled();
|
||||
|
||||
jasmine.clock().tick(100);
|
||||
|
||||
expect(fnCallback).toHaveBeenCalled();
|
||||
expect(onComplete).not.toHaveBeenCalled();
|
||||
|
||||
jasmine.clock().tick(100);
|
||||
|
||||
expect(onComplete).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('handles a rejected promise like an unhandled exception', function() {
|
||||
var promise = new StubPromise(),
|
||||
queueableFn1 = {
|
||||
fn: function() {
|
||||
setTimeout(function() {
|
||||
promise.rejectHandler('foo');
|
||||
}, 100);
|
||||
return promise;
|
||||
}
|
||||
},
|
||||
queueableFn2 = { fn: jasmine.createSpy('fn2') },
|
||||
onExceptionCallback = jasmine.createSpy('on exception callback'),
|
||||
queueRunner = new jasmineUnderTest.QueueRunner({
|
||||
queueableFns: [queueableFn1, queueableFn2],
|
||||
onException: onExceptionCallback
|
||||
});
|
||||
|
||||
queueRunner.execute();
|
||||
|
||||
expect(onExceptionCallback).not.toHaveBeenCalled();
|
||||
expect(queueableFn2.fn).not.toHaveBeenCalled();
|
||||
|
||||
jasmine.clock().tick(100);
|
||||
|
||||
expect(onExceptionCallback).toHaveBeenCalledWith('foo');
|
||||
expect(queueableFn2.fn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('issues a deprecation if the function also takes a parameter', function() {
|
||||
var queueableFn = {
|
||||
fn: function(done) {
|
||||
return new StubPromise();
|
||||
}
|
||||
},
|
||||
deprecated = jasmine.createSpy('deprecated'),
|
||||
queueRunner = new jasmineUnderTest.QueueRunner({
|
||||
queueableFns: [queueableFn],
|
||||
deprecated: deprecated
|
||||
}),
|
||||
env = jasmineUnderTest.getEnv();
|
||||
|
||||
queueRunner.execute();
|
||||
|
||||
expect(deprecated).toHaveBeenCalledWith(
|
||||
'An asynchronous ' +
|
||||
'before/it/after function took a done callback but also returned a ' +
|
||||
'promise. This is not supported and will stop working in the future. ' +
|
||||
'Either remove the done callback (recommended) or change the function ' +
|
||||
'to not return a promise.'
|
||||
);
|
||||
});
|
||||
|
||||
it('issues a more specific deprecation if the function is `async`', function() {
|
||||
jasmine.getEnv().requireAsyncAwait();
|
||||
eval('var fn = async function(done){};');
|
||||
var deprecated = jasmine.createSpy('deprecated'),
|
||||
queueRunner = new jasmineUnderTest.QueueRunner({
|
||||
queueableFns: [{ fn: fn }],
|
||||
deprecated: deprecated
|
||||
});
|
||||
|
||||
queueRunner.execute();
|
||||
|
||||
expect(deprecated).toHaveBeenCalledWith(
|
||||
'An asynchronous ' +
|
||||
'before/it/after function was defined with the async keyword but ' +
|
||||
'also took a done callback. This is not supported and will stop ' +
|
||||
'working in the future. Either remove the done callback ' +
|
||||
'(recommended) or remove the async keyword.'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('passes the error instance to exception handlers in HTML browsers', function() {
|
||||
var error = new Error('fake error'),
|
||||
onExceptionCallback = jasmine.createSpy('on exception callback'),
|
||||
queueRunner = new jasmineUnderTest.QueueRunner({
|
||||
onException: onExceptionCallback
|
||||
});
|
||||
|
||||
queueRunner.execute();
|
||||
queueRunner.handleFinalError(error.message, 'fake.js', 1, 1, error);
|
||||
|
||||
expect(onExceptionCallback).toHaveBeenCalledWith(error);
|
||||
});
|
||||
|
||||
it('passes the first argument to exception handlers for compatibility', function() {
|
||||
var error = new Error('fake error'),
|
||||
onExceptionCallback = jasmine.createSpy('on exception callback'),
|
||||
queueRunner = new jasmineUnderTest.QueueRunner({
|
||||
onException: onExceptionCallback
|
||||
});
|
||||
|
||||
queueRunner.execute();
|
||||
queueRunner.handleFinalError(error.message);
|
||||
|
||||
expect(onExceptionCallback).toHaveBeenCalledWith(error.message);
|
||||
});
|
||||
|
||||
it('calls exception handlers when an exception is thrown in a fn', function() {
|
||||
var queueableFn = {
|
||||
type: 'queueable',
|
||||
fn: function() {
|
||||
throw new Error('fake error');
|
||||
}
|
||||
},
|
||||
onExceptionCallback = jasmine.createSpy('on exception callback'),
|
||||
queueRunner = new jasmineUnderTest.QueueRunner({
|
||||
queueableFns: [queueableFn],
|
||||
@@ -252,23 +602,13 @@ describe("QueueRunner", function() {
|
||||
expect(onExceptionCallback).toHaveBeenCalledWith(jasmine.any(Error));
|
||||
});
|
||||
|
||||
it("rethrows an exception if told to", function() {
|
||||
var queueableFn = { fn: function() {
|
||||
throw new Error('fake error');
|
||||
} },
|
||||
queueRunner = new jasmineUnderTest.QueueRunner({
|
||||
queueableFns: [queueableFn],
|
||||
catchException: function(e) { return false; }
|
||||
});
|
||||
|
||||
expect(function() {
|
||||
queueRunner.execute();
|
||||
}).toThrowError('fake error');
|
||||
});
|
||||
|
||||
it("continues running the functions even after an exception is thrown in an async spec", function() {
|
||||
var queueableFn = { fn: function(done) { throw new Error("error"); } },
|
||||
nextQueueableFn = { fn: jasmine.createSpy("nextFunction") },
|
||||
it('continues running the functions even after an exception is thrown in an async spec', function() {
|
||||
var queueableFn = {
|
||||
fn: function(done) {
|
||||
throw new Error('error');
|
||||
}
|
||||
},
|
||||
nextQueueableFn = { fn: jasmine.createSpy('nextFunction') },
|
||||
queueRunner = new jasmineUnderTest.QueueRunner({
|
||||
queueableFns: [queueableFn, nextQueueableFn]
|
||||
});
|
||||
@@ -277,7 +617,133 @@ describe("QueueRunner", function() {
|
||||
expect(nextQueueableFn.fn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("calls a provided complete callback when done", function() {
|
||||
describe('When configured to complete on first error', function() {
|
||||
it('skips to cleanup functions on the first exception', function() {
|
||||
var queueableFn = {
|
||||
fn: function() {
|
||||
throw new Error('error');
|
||||
}
|
||||
},
|
||||
nextQueueableFn = { fn: jasmine.createSpy('nextFunction') },
|
||||
cleanupFn = { fn: jasmine.createSpy('cleanup') },
|
||||
onComplete = jasmine.createSpy('onComplete'),
|
||||
queueRunner = new jasmineUnderTest.QueueRunner({
|
||||
queueableFns: [queueableFn, nextQueueableFn],
|
||||
cleanupFns: [cleanupFn],
|
||||
onComplete: onComplete,
|
||||
completeOnFirstError: true
|
||||
});
|
||||
|
||||
queueRunner.execute();
|
||||
expect(nextQueueableFn.fn).not.toHaveBeenCalled();
|
||||
expect(cleanupFn.fn).toHaveBeenCalled();
|
||||
expect(onComplete).toHaveBeenCalledWith(
|
||||
jasmine.any(jasmineUnderTest.StopExecutionError)
|
||||
);
|
||||
});
|
||||
|
||||
it('does not skip when a cleanup function throws', function() {
|
||||
var queueableFn = { fn: function() {} },
|
||||
cleanupFn1 = {
|
||||
fn: function() {
|
||||
throw new Error('error');
|
||||
}
|
||||
},
|
||||
cleanupFn2 = { fn: jasmine.createSpy('cleanupFn2') },
|
||||
queueRunner = new jasmineUnderTest.QueueRunner({
|
||||
queueableFns: [queueableFn],
|
||||
cleanupFns: [cleanupFn1, cleanupFn2],
|
||||
completeOnFirstError: true
|
||||
});
|
||||
|
||||
queueRunner.execute();
|
||||
expect(cleanupFn2.fn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
describe('with an asynchronous function', function() {
|
||||
beforeEach(function() {
|
||||
jasmine.clock().install();
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
jasmine.clock().uninstall();
|
||||
});
|
||||
|
||||
it('skips to cleanup functions once the fn completes after an unhandled exception', function() {
|
||||
var errorListeners = [],
|
||||
queueableFn = {
|
||||
fn: function(done) {
|
||||
queueableFnDone = done;
|
||||
}
|
||||
},
|
||||
nextQueueableFn = { fn: jasmine.createSpy('nextFunction') },
|
||||
cleanupFn = { fn: jasmine.createSpy('cleanup') },
|
||||
queueRunner = new jasmineUnderTest.QueueRunner({
|
||||
globalErrors: {
|
||||
pushListener: function(f) {
|
||||
errorListeners.push(f);
|
||||
},
|
||||
popListener: function() {
|
||||
errorListeners.pop();
|
||||
}
|
||||
},
|
||||
queueableFns: [queueableFn, nextQueueableFn],
|
||||
cleanupFns: [cleanupFn],
|
||||
completeOnFirstError: true
|
||||
}),
|
||||
queueableFnDone;
|
||||
|
||||
queueRunner.execute();
|
||||
errorListeners[errorListeners.length - 1](new Error('error'));
|
||||
expect(cleanupFn.fn).not.toHaveBeenCalled();
|
||||
queueableFnDone();
|
||||
expect(nextQueueableFn.fn).not.toHaveBeenCalled();
|
||||
expect(cleanupFn.fn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('skips to cleanup functions when next.fail is called', function() {
|
||||
var queueableFn = {
|
||||
fn: function(done) {
|
||||
done.fail('nope');
|
||||
}
|
||||
},
|
||||
nextQueueableFn = { fn: jasmine.createSpy('nextFunction') },
|
||||
cleanupFn = { fn: jasmine.createSpy('cleanup') },
|
||||
queueRunner = new jasmineUnderTest.QueueRunner({
|
||||
queueableFns: [queueableFn, nextQueueableFn],
|
||||
cleanupFns: [cleanupFn],
|
||||
completeOnFirstError: true
|
||||
});
|
||||
|
||||
queueRunner.execute();
|
||||
jasmine.clock().tick();
|
||||
expect(nextQueueableFn.fn).not.toHaveBeenCalled();
|
||||
expect(cleanupFn.fn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('skips to cleanup functions when next is called with an Error', function() {
|
||||
var queueableFn = {
|
||||
fn: function(done) {
|
||||
done(new Error('nope'));
|
||||
}
|
||||
},
|
||||
nextQueueableFn = { fn: jasmine.createSpy('nextFunction') },
|
||||
cleanupFn = { fn: jasmine.createSpy('cleanup') },
|
||||
queueRunner = new jasmineUnderTest.QueueRunner({
|
||||
queueableFns: [queueableFn, nextQueueableFn],
|
||||
cleanupFns: [cleanupFn],
|
||||
completeOnFirstError: true
|
||||
});
|
||||
|
||||
queueRunner.execute();
|
||||
jasmine.clock().tick();
|
||||
expect(nextQueueableFn.fn).not.toHaveBeenCalled();
|
||||
expect(cleanupFn.fn).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('calls a provided complete callback when done', function() {
|
||||
var queueableFn = { fn: jasmine.createSpy('fn') },
|
||||
completeCallback = jasmine.createSpy('completeCallback'),
|
||||
queueRunner = new jasmineUnderTest.QueueRunner({
|
||||
@@ -290,8 +756,21 @@ describe("QueueRunner", function() {
|
||||
expect(completeCallback).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("calls a provided stack clearing function when done", function() {
|
||||
var asyncFn = { fn: function(done) { done() } },
|
||||
describe('clearing the stack', function() {
|
||||
beforeEach(function() {
|
||||
jasmine.clock().install();
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
jasmine.clock().uninstall();
|
||||
});
|
||||
|
||||
it('calls a provided stack clearing function when done', function() {
|
||||
var asyncFn = {
|
||||
fn: function(done) {
|
||||
done();
|
||||
}
|
||||
},
|
||||
afterFn = { fn: jasmine.createSpy('afterFn') },
|
||||
completeCallback = jasmine.createSpy('completeCallback'),
|
||||
clearStack = jasmine.createSpy('clearStack'),
|
||||
@@ -301,10 +780,62 @@ describe("QueueRunner", function() {
|
||||
onComplete: completeCallback
|
||||
});
|
||||
|
||||
clearStack.and.callFake(function(fn) { fn(); });
|
||||
clearStack.and.callFake(function(fn) {
|
||||
fn();
|
||||
});
|
||||
|
||||
queueRunner.execute();
|
||||
expect(afterFn.fn).toHaveBeenCalled();
|
||||
expect(clearStack).toHaveBeenCalledWith(completeCallback);
|
||||
queueRunner.execute();
|
||||
jasmine.clock().tick();
|
||||
expect(afterFn.fn).toHaveBeenCalled();
|
||||
expect(clearStack).toHaveBeenCalled();
|
||||
clearStack.calls.argsFor(0)[0]();
|
||||
expect(completeCallback).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when user context has not been defined', function() {
|
||||
beforeEach(function() {
|
||||
var fn;
|
||||
|
||||
this.fn = fn = jasmine.createSpy('fn1');
|
||||
this.queueRunner = new jasmineUnderTest.QueueRunner({
|
||||
queueableFns: [{ fn: fn }]
|
||||
});
|
||||
});
|
||||
|
||||
it('runs the functions on the scope of a UserContext', function() {
|
||||
var context;
|
||||
this.fn.and.callFake(function() {
|
||||
context = this;
|
||||
});
|
||||
|
||||
this.queueRunner.execute();
|
||||
|
||||
expect(context.constructor).toBe(jasmineUnderTest.UserContext);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when user context has been defined', function() {
|
||||
beforeEach(function() {
|
||||
var fn, context;
|
||||
|
||||
this.fn = fn = jasmine.createSpy('fn1');
|
||||
this.context = context = new jasmineUnderTest.UserContext();
|
||||
this.queueRunner = new jasmineUnderTest.QueueRunner({
|
||||
queueableFns: [{ fn: fn }],
|
||||
userContext: context
|
||||
});
|
||||
});
|
||||
|
||||
it('runs the functions on the scope of a UserContext', function() {
|
||||
var context;
|
||||
this.fn.and.callFake(function() {
|
||||
context = this;
|
||||
});
|
||||
|
||||
this.queueRunner.execute();
|
||||
|
||||
expect(context).toBe(this.context);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,64 +1,178 @@
|
||||
describe("ReportDispatcher", function() {
|
||||
|
||||
it("builds an interface of requested methods", function() {
|
||||
var dispatcher = new jasmineUnderTest.ReportDispatcher(['foo', 'bar', 'baz']);
|
||||
describe('ReportDispatcher', function() {
|
||||
it('builds an interface of requested methods', function() {
|
||||
var dispatcher = new jasmineUnderTest.ReportDispatcher([
|
||||
'foo',
|
||||
'bar',
|
||||
'baz'
|
||||
]);
|
||||
|
||||
expect(dispatcher.foo).toBeDefined();
|
||||
expect(dispatcher.bar).toBeDefined();
|
||||
expect(dispatcher.baz).toBeDefined();
|
||||
});
|
||||
|
||||
it("dispatches requested methods to added reporters", function() {
|
||||
var dispatcher = new jasmineUnderTest.ReportDispatcher(['foo', 'bar']),
|
||||
it('dispatches requested methods to added reporters', function() {
|
||||
var queueRunnerFactory = jasmine.createSpy('queueRunner'),
|
||||
dispatcher = new jasmineUnderTest.ReportDispatcher(
|
||||
['foo', 'bar'],
|
||||
queueRunnerFactory
|
||||
),
|
||||
reporter = jasmine.createSpyObj('reporter', ['foo', 'bar']),
|
||||
anotherReporter = jasmine.createSpyObj('reporter', ['foo', 'bar']);
|
||||
anotherReporter = jasmine.createSpyObj('reporter', ['foo', 'bar']),
|
||||
completeCallback = jasmine.createSpy('complete');
|
||||
|
||||
dispatcher.addReporter(reporter);
|
||||
dispatcher.addReporter(anotherReporter);
|
||||
|
||||
dispatcher.foo(123, 456);
|
||||
dispatcher.foo(123, 456, completeCallback);
|
||||
|
||||
expect(queueRunnerFactory).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
queueableFns: [
|
||||
{ fn: jasmine.any(Function) },
|
||||
{ fn: jasmine.any(Function) }
|
||||
],
|
||||
isReporter: true
|
||||
})
|
||||
);
|
||||
|
||||
var fns = queueRunnerFactory.calls.mostRecent().args[0].queueableFns;
|
||||
fns[0].fn();
|
||||
expect(reporter.foo).toHaveBeenCalledWith(123, 456);
|
||||
expect(reporter.foo.calls.mostRecent().object).toBe(reporter);
|
||||
|
||||
fns[1].fn();
|
||||
expect(anotherReporter.foo).toHaveBeenCalledWith(123, 456);
|
||||
expect(anotherReporter.foo.calls.mostRecent().object).toBe(anotherReporter);
|
||||
|
||||
dispatcher.bar('a', 'b');
|
||||
queueRunnerFactory.calls.reset();
|
||||
|
||||
dispatcher.bar('a', 'b', completeCallback);
|
||||
|
||||
expect(queueRunnerFactory).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
queueableFns: [
|
||||
{ fn: jasmine.any(Function) },
|
||||
{ fn: jasmine.any(Function) }
|
||||
],
|
||||
isReporter: true
|
||||
})
|
||||
);
|
||||
|
||||
fns = queueRunnerFactory.calls.mostRecent().args[0].queueableFns;
|
||||
fns[0].fn();
|
||||
expect(reporter.bar).toHaveBeenCalledWith('a', 'b');
|
||||
|
||||
fns[1].fn();
|
||||
expect(anotherReporter.bar).toHaveBeenCalledWith('a', 'b');
|
||||
});
|
||||
|
||||
it("does not dispatch to a reporter if the reporter doesn't accept the method", function() {
|
||||
var dispatcher = new jasmineUnderTest.ReportDispatcher(['foo']),
|
||||
var queueRunnerFactory = jasmine.createSpy('queueRunner'),
|
||||
dispatcher = new jasmineUnderTest.ReportDispatcher(
|
||||
['foo'],
|
||||
queueRunnerFactory
|
||||
),
|
||||
reporter = jasmine.createSpyObj('reporter', ['baz']);
|
||||
|
||||
dispatcher.addReporter(reporter);
|
||||
|
||||
expect(function() {
|
||||
dispatcher.foo(123, 456);
|
||||
}).not.toThrow();
|
||||
dispatcher.foo(123, 456);
|
||||
expect(queueRunnerFactory).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
queueableFns: []
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it("allows providing a fallback reporter in case there's no other report", function() {
|
||||
var dispatcher = new jasmineUnderTest.ReportDispatcher(['foo', 'bar']),
|
||||
reporter = jasmine.createSpyObj('reporter', ['foo', 'bar']);
|
||||
it("allows providing a fallback reporter in case there's no other reporter", function() {
|
||||
var queueRunnerFactory = jasmine.createSpy('queueRunner'),
|
||||
dispatcher = new jasmineUnderTest.ReportDispatcher(
|
||||
['foo', 'bar'],
|
||||
queueRunnerFactory
|
||||
),
|
||||
reporter = jasmine.createSpyObj('reporter', ['foo', 'bar']),
|
||||
completeCallback = jasmine.createSpy('complete');
|
||||
|
||||
dispatcher.provideFallbackReporter(reporter);
|
||||
dispatcher.foo(123, 456);
|
||||
expect(reporter.foo).toHaveBeenCalledWith(123, 456);
|
||||
dispatcher.foo(123, 456, completeCallback);
|
||||
|
||||
expect(queueRunnerFactory).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
queueableFns: [{ fn: jasmine.any(Function) }],
|
||||
isReporter: true
|
||||
})
|
||||
);
|
||||
|
||||
var fns = queueRunnerFactory.calls.mostRecent().args[0].queueableFns;
|
||||
fns[0].fn();
|
||||
expect(reporter.foo).toHaveBeenCalledWith(123, 456);
|
||||
});
|
||||
|
||||
it("does not call fallback reporting methods when another report is provided", function() {
|
||||
var dispatcher = new jasmineUnderTest.ReportDispatcher(['foo', 'bar']),
|
||||
it('does not call fallback reporting methods when another reporter is provided', function() {
|
||||
var queueRunnerFactory = jasmine.createSpy('queueRunner'),
|
||||
dispatcher = new jasmineUnderTest.ReportDispatcher(
|
||||
['foo', 'bar'],
|
||||
queueRunnerFactory
|
||||
),
|
||||
reporter = jasmine.createSpyObj('reporter', ['foo', 'bar']),
|
||||
fallbackReporter = jasmine.createSpyObj('otherReporter', ['foo', 'bar']);
|
||||
fallbackReporter = jasmine.createSpyObj('otherReporter', ['foo', 'bar']),
|
||||
completeCallback = jasmine.createSpy('complete');
|
||||
|
||||
dispatcher.provideFallbackReporter(fallbackReporter);
|
||||
dispatcher.addReporter(reporter);
|
||||
dispatcher.foo(123, 456);
|
||||
dispatcher.foo(123, 456, completeCallback);
|
||||
|
||||
expect(queueRunnerFactory).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
queueableFns: [{ fn: jasmine.any(Function) }],
|
||||
isReporter: true
|
||||
})
|
||||
);
|
||||
|
||||
var fns = queueRunnerFactory.calls.mostRecent().args[0].queueableFns;
|
||||
fns[0].fn();
|
||||
expect(reporter.foo).toHaveBeenCalledWith(123, 456);
|
||||
expect(fallbackReporter.foo).not.toHaveBeenCalledWith(123, 456);
|
||||
});
|
||||
|
||||
it('allows registered reporters to be cleared', function() {
|
||||
var queueRunnerFactory = jasmine.createSpy('queueRunner'),
|
||||
dispatcher = new jasmineUnderTest.ReportDispatcher(
|
||||
['foo', 'bar'],
|
||||
queueRunnerFactory
|
||||
),
|
||||
reporter1 = jasmine.createSpyObj('reporter1', ['foo', 'bar']),
|
||||
reporter2 = jasmine.createSpyObj('reporter2', ['foo', 'bar']),
|
||||
completeCallback = jasmine.createSpy('complete');
|
||||
|
||||
dispatcher.addReporter(reporter1);
|
||||
dispatcher.foo(123, completeCallback);
|
||||
expect(queueRunnerFactory).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
queueableFns: [{ fn: jasmine.any(Function) }],
|
||||
isReporter: true
|
||||
})
|
||||
);
|
||||
|
||||
var fns = queueRunnerFactory.calls.mostRecent().args[0].queueableFns;
|
||||
fns[0].fn();
|
||||
expect(reporter1.foo).toHaveBeenCalledWith(123);
|
||||
|
||||
dispatcher.clearReporters();
|
||||
dispatcher.addReporter(reporter2);
|
||||
dispatcher.bar(456, completeCallback);
|
||||
|
||||
expect(queueRunnerFactory).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
queueableFns: [{ fn: jasmine.any(Function) }],
|
||||
isReporter: true
|
||||
})
|
||||
);
|
||||
|
||||
fns = queueRunnerFactory.calls.mostRecent().args[0].queueableFns;
|
||||
fns[0].fn();
|
||||
expect(reporter1.bar).not.toHaveBeenCalled();
|
||||
expect(reporter2.bar).toHaveBeenCalledWith(456);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,25 +1,30 @@
|
||||
describe("Spec", function() {
|
||||
|
||||
it("#isPendingSpecException returns true for a pending spec exception", function() {
|
||||
describe('Spec', function() {
|
||||
it('#isPendingSpecException returns true for a pending spec exception', function() {
|
||||
var e = new Error(jasmineUnderTest.Spec.pendingSpecExceptionMessage);
|
||||
|
||||
expect(jasmineUnderTest.Spec.isPendingSpecException(e)).toBe(true);
|
||||
});
|
||||
|
||||
it("#isPendingSpecException returns true for a pending spec exception (even when FF bug is present)", function() {
|
||||
it('#isPendingSpecException returns true for a pending spec exception (even when FF bug is present)', function() {
|
||||
var fakeError = {
|
||||
toString: function() { return "Error: " + jasmineUnderTest.Spec.pendingSpecExceptionMessage; }
|
||||
toString: function() {
|
||||
return 'Error: ' + jasmineUnderTest.Spec.pendingSpecExceptionMessage;
|
||||
}
|
||||
};
|
||||
|
||||
expect(jasmineUnderTest.Spec.isPendingSpecException(fakeError)).toBe(true);
|
||||
});
|
||||
|
||||
it("#isPendingSpecException returns true for a pending spec exception with a custom message", function() {
|
||||
expect(jasmineUnderTest.Spec.isPendingSpecException(jasmineUnderTest.Spec.pendingSpecExceptionMessage + 'foo')).toBe(true);
|
||||
it('#isPendingSpecException returns true for a pending spec exception with a custom message', function() {
|
||||
expect(
|
||||
jasmineUnderTest.Spec.isPendingSpecException(
|
||||
jasmineUnderTest.Spec.pendingSpecExceptionMessage + 'foo'
|
||||
)
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it("#isPendingSpecException returns false for not a pending spec exception", function() {
|
||||
var e = new Error("foo");
|
||||
it('#isPendingSpecException returns false for not a pending spec exception', function() {
|
||||
var e = new Error('foo');
|
||||
|
||||
expect(jasmineUnderTest.Spec.isPendingSpecException(e)).toBe(false);
|
||||
});
|
||||
@@ -28,7 +33,7 @@ describe("Spec", function() {
|
||||
expect(jasmineUnderTest.Spec.isPendingSpecException(void 0)).toBe(false);
|
||||
});
|
||||
|
||||
it("delegates execution to a QueueRunner", function() {
|
||||
it('delegates execution to a QueueRunner', function() {
|
||||
var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
|
||||
spec = new jasmineUnderTest.Spec({
|
||||
description: 'my test',
|
||||
@@ -42,7 +47,7 @@ describe("Spec", function() {
|
||||
expect(fakeQueueRunner).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should call the start callback on execution", function() {
|
||||
it('should call the start callback on execution', function() {
|
||||
var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
|
||||
startCallback = jasmine.createSpy('startCallback'),
|
||||
spec = new jasmineUnderTest.Spec({
|
||||
@@ -55,6 +60,7 @@ describe("Spec", function() {
|
||||
|
||||
spec.execute();
|
||||
|
||||
fakeQueueRunner.calls.mostRecent().args[0].queueableFns[0].fn();
|
||||
// TODO: due to some issue with the Pretty Printer, this line fails, but the other two pass.
|
||||
// This means toHaveBeenCalledWith on IE8 will always be broken.
|
||||
|
||||
@@ -63,18 +69,22 @@ describe("Spec", function() {
|
||||
expect(startCallback.calls.first().object).toEqual(spec);
|
||||
});
|
||||
|
||||
it("should call the start callback on execution but before any befores are called", function() {
|
||||
it('should call the start callback on execution but before any befores are called', function() {
|
||||
var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
|
||||
beforesWereCalled = false,
|
||||
startCallback = jasmine.createSpy('start-callback').and.callFake(function() {
|
||||
expect(beforesWereCalled).toBe(false);
|
||||
}),
|
||||
startCallback = jasmine
|
||||
.createSpy('start-callback')
|
||||
.and.callFake(function() {
|
||||
expect(beforesWereCalled).toBe(false);
|
||||
}),
|
||||
spec = new jasmineUnderTest.Spec({
|
||||
queueableFn: { fn: function() {} },
|
||||
beforeFns: function() {
|
||||
return [function() {
|
||||
beforesWereCalled = true
|
||||
}]
|
||||
return [
|
||||
function() {
|
||||
beforesWereCalled = true;
|
||||
}
|
||||
];
|
||||
},
|
||||
onStart: startCallback,
|
||||
queueRunnerFactory: fakeQueueRunner
|
||||
@@ -82,34 +92,60 @@ describe("Spec", function() {
|
||||
|
||||
spec.execute();
|
||||
|
||||
fakeQueueRunner.calls.mostRecent().args[0].queueableFns[0].fn();
|
||||
expect(startCallback).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("provides all before fns and after fns to be run", function() {
|
||||
it('provides all before fns and after fns to be run', function() {
|
||||
var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
|
||||
before = jasmine.createSpy('before'),
|
||||
after = jasmine.createSpy('after'),
|
||||
queueableFn = { fn: jasmine.createSpy('test body').and.callFake(function() {
|
||||
expect(before).toHaveBeenCalled();
|
||||
expect(after).not.toHaveBeenCalled();
|
||||
}) },
|
||||
queueableFn = {
|
||||
fn: jasmine.createSpy('test body').and.callFake(function() {
|
||||
expect(before).toHaveBeenCalled();
|
||||
expect(after).not.toHaveBeenCalled();
|
||||
})
|
||||
},
|
||||
spec = new jasmineUnderTest.Spec({
|
||||
queueableFn: queueableFn,
|
||||
beforeAndAfterFns: function() {
|
||||
return {befores: [before], afters: [after]}
|
||||
return { befores: [before], afters: [after] };
|
||||
},
|
||||
queueRunnerFactory: fakeQueueRunner
|
||||
});
|
||||
|
||||
spec.execute();
|
||||
|
||||
var allSpecFns = fakeQueueRunner.calls.mostRecent().args[0].queueableFns;
|
||||
expect(allSpecFns).toEqual([before, queueableFn, after]);
|
||||
var options = fakeQueueRunner.calls.mostRecent().args[0];
|
||||
expect(options.queueableFns).toEqual([
|
||||
{ fn: jasmine.any(Function) },
|
||||
before,
|
||||
queueableFn
|
||||
]);
|
||||
expect(options.cleanupFns).toEqual([after, { fn: jasmine.any(Function) }]);
|
||||
});
|
||||
|
||||
it("is marked pending if created without a function body", function() {
|
||||
it("tells the queue runner that it's a leaf node", function() {
|
||||
var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
|
||||
spec = new jasmineUnderTest.Spec({
|
||||
queueableFn: { fn: function() {} },
|
||||
beforeAndAfterFns: function() {
|
||||
return { befores: [], afters: [] };
|
||||
},
|
||||
queueRunnerFactory: fakeQueueRunner
|
||||
});
|
||||
|
||||
spec.execute();
|
||||
|
||||
expect(fakeQueueRunner).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
isLeaf: true
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('is marked pending if created without a function body', function() {
|
||||
var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
|
||||
startCallback = jasmine.createSpy('startCallback'),
|
||||
resultCallback = jasmine.createSpy('resultCallback'),
|
||||
spec = new jasmineUnderTest.Spec({
|
||||
@@ -122,64 +158,48 @@ describe("Spec", function() {
|
||||
expect(spec.status()).toBe('pending');
|
||||
});
|
||||
|
||||
it("can be disabled, but still calls callbacks", function() {
|
||||
it('can be excluded at execution time by a parent', function() {
|
||||
var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
|
||||
startCallback = jasmine.createSpy('startCallback'),
|
||||
specBody = jasmine.createSpy('specBody'),
|
||||
resultCallback = jasmine.createSpy('resultCallback'),
|
||||
spec = new jasmineUnderTest.Spec({
|
||||
onStart:startCallback,
|
||||
onStart: startCallback,
|
||||
queueableFn: { fn: specBody },
|
||||
resultCallback: resultCallback,
|
||||
queueRunnerFactory: fakeQueueRunner
|
||||
});
|
||||
|
||||
spec.disable();
|
||||
spec.execute('cally-back', true);
|
||||
|
||||
expect(spec.status()).toBe('disabled');
|
||||
|
||||
spec.execute();
|
||||
|
||||
expect(fakeQueueRunner).not.toHaveBeenCalled();
|
||||
expect(fakeQueueRunner).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
onComplete: jasmine.any(Function),
|
||||
queueableFns: [{ fn: jasmine.any(Function) }],
|
||||
cleanupFns: [{ fn: jasmine.any(Function) }]
|
||||
})
|
||||
);
|
||||
expect(specBody).not.toHaveBeenCalled();
|
||||
|
||||
var args = fakeQueueRunner.calls.mostRecent().args[0];
|
||||
args.queueableFns[0].fn();
|
||||
expect(startCallback).toHaveBeenCalled();
|
||||
args.cleanupFns[0].fn();
|
||||
expect(resultCallback).toHaveBeenCalled();
|
||||
|
||||
expect(spec.result.status).toBe('excluded');
|
||||
});
|
||||
|
||||
it("can be disabled at execution time by a parent", function() {
|
||||
var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
|
||||
startCallback = jasmine.createSpy('startCallback'),
|
||||
specBody = jasmine.createSpy('specBody'),
|
||||
resultCallback = jasmine.createSpy('resultCallback'),
|
||||
spec = new jasmineUnderTest.Spec({
|
||||
onStart:startCallback,
|
||||
queueableFn: { fn: specBody },
|
||||
resultCallback: resultCallback,
|
||||
queueRunnerFactory: fakeQueueRunner
|
||||
});
|
||||
|
||||
spec.execute(undefined, false);
|
||||
|
||||
expect(spec.result.status).toBe('disabled');
|
||||
|
||||
expect(fakeQueueRunner).not.toHaveBeenCalled();
|
||||
expect(specBody).not.toHaveBeenCalled();
|
||||
|
||||
expect(startCallback).toHaveBeenCalled();
|
||||
expect(resultCallback).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("can be marked pending, but still calls callbacks when executed", function() {
|
||||
it('can be marked pending, but still calls callbacks when executed', function() {
|
||||
var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
|
||||
startCallback = jasmine.createSpy('startCallback'),
|
||||
resultCallback = jasmine.createSpy('resultCallback'),
|
||||
spec = new jasmineUnderTest.Spec({
|
||||
onStart: startCallback,
|
||||
resultCallback: resultCallback,
|
||||
description: "with a spec",
|
||||
description: 'with a spec',
|
||||
getSpecName: function() {
|
||||
return "a suite with a spec"
|
||||
return 'a suite with a spec';
|
||||
},
|
||||
queueRunnerFactory: fakeQueueRunner,
|
||||
queueableFn: { fn: null }
|
||||
@@ -191,27 +211,40 @@ describe("Spec", function() {
|
||||
|
||||
spec.execute();
|
||||
|
||||
expect(fakeQueueRunner).not.toHaveBeenCalled();
|
||||
expect(fakeQueueRunner).toHaveBeenCalled();
|
||||
|
||||
var args = fakeQueueRunner.calls.mostRecent().args[0];
|
||||
args.queueableFns[0].fn();
|
||||
expect(startCallback).toHaveBeenCalled();
|
||||
expect(resultCallback).toHaveBeenCalledWith({
|
||||
id: spec.id,
|
||||
status: 'pending',
|
||||
description: 'with a spec',
|
||||
fullName: 'a suite with a spec',
|
||||
failedExpectations: [],
|
||||
passedExpectations: [],
|
||||
pendingReason: ''
|
||||
});
|
||||
args.cleanupFns[0].fn('things');
|
||||
expect(resultCallback).toHaveBeenCalledWith(
|
||||
{
|
||||
id: spec.id,
|
||||
status: 'pending',
|
||||
description: 'with a spec',
|
||||
fullName: 'a suite with a spec',
|
||||
failedExpectations: [],
|
||||
passedExpectations: [],
|
||||
deprecationWarnings: [],
|
||||
pendingReason: '',
|
||||
duration: jasmine.any(Number),
|
||||
properties: null
|
||||
},
|
||||
'things'
|
||||
);
|
||||
});
|
||||
|
||||
it("should call the done callback on execution complete", function() {
|
||||
it('should call the done callback on execution complete', function() {
|
||||
var done = jasmine.createSpy('done callback'),
|
||||
spec = new jasmineUnderTest.Spec({
|
||||
queueableFn: { fn: function() {} },
|
||||
catchExceptions: function() { return false; },
|
||||
catchExceptions: function() {
|
||||
return false;
|
||||
},
|
||||
resultCallback: function() {},
|
||||
queueRunnerFactory: function(attrs) { attrs.onComplete(); }
|
||||
queueRunnerFactory: function(attrs) {
|
||||
attrs.onComplete();
|
||||
}
|
||||
});
|
||||
|
||||
spec.execute(done);
|
||||
@@ -219,30 +252,104 @@ describe("Spec", function() {
|
||||
expect(done).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("#status returns passing by default", function() {
|
||||
var spec = new jasmineUnderTest.Spec({queueableFn: { fn: jasmine.createSpy("spec body")} });
|
||||
it('should call the done callback with an error if the spec is failed', function() {
|
||||
var done = jasmine.createSpy('done callback'),
|
||||
spec = new jasmineUnderTest.Spec({
|
||||
queueableFn: { fn: function() {} },
|
||||
catchExceptions: function() {
|
||||
return false;
|
||||
},
|
||||
resultCallback: function() {},
|
||||
queueRunnerFactory: function(attrs) {
|
||||
spec.result.status = 'failed';
|
||||
attrs.onComplete();
|
||||
}
|
||||
});
|
||||
|
||||
spec.execute(done);
|
||||
|
||||
expect(done).toHaveBeenCalledWith(
|
||||
jasmine.any(jasmineUnderTest.StopExecutionError)
|
||||
);
|
||||
});
|
||||
|
||||
it('should report the duration of the test', function() {
|
||||
var timer = jasmine.createSpyObj('timer', { start: null, elapsed: 77000 }),
|
||||
spec = new jasmineUnderTest.Spec({
|
||||
queueableFn: { fn: jasmine.createSpy('spec body') },
|
||||
catchExceptions: function() {
|
||||
return false;
|
||||
},
|
||||
resultCallback: function(result) {
|
||||
duration = result.duration;
|
||||
},
|
||||
queueRunnerFactory: function(config) {
|
||||
config.queueableFns.forEach(function(qf) {
|
||||
qf.fn();
|
||||
});
|
||||
config.cleanupFns.forEach(function(qf) {
|
||||
qf.fn();
|
||||
});
|
||||
config.onComplete();
|
||||
},
|
||||
timer: timer
|
||||
}),
|
||||
duration = undefined;
|
||||
|
||||
spec.execute(function() {});
|
||||
expect(duration).toBe(77000);
|
||||
});
|
||||
|
||||
it('should report properties set during the test', function() {
|
||||
var done = jasmine.createSpy('done callback'),
|
||||
spec = new jasmineUnderTest.Spec({
|
||||
queueableFn: { fn: jasmine.createSpy('spec body') },
|
||||
catchExceptions: function() {
|
||||
return false;
|
||||
},
|
||||
resultCallback: function() {},
|
||||
queueRunnerFactory: function(attrs) {
|
||||
attrs.onComplete();
|
||||
}
|
||||
});
|
||||
spec.setSpecProperty('a', 4);
|
||||
spec.execute(done);
|
||||
expect(spec.result.properties).toEqual({ a: 4 });
|
||||
});
|
||||
|
||||
it('#status returns passing by default', function() {
|
||||
var spec = new jasmineUnderTest.Spec({
|
||||
queueableFn: { fn: jasmine.createSpy('spec body') }
|
||||
});
|
||||
expect(spec.status()).toBe('passed');
|
||||
});
|
||||
|
||||
it("#status returns passed if all expectations in the spec have passed", function() {
|
||||
var spec = new jasmineUnderTest.Spec({queueableFn: { fn: jasmine.createSpy("spec body")} });
|
||||
it('#status returns passed if all expectations in the spec have passed', function() {
|
||||
var spec = new jasmineUnderTest.Spec({
|
||||
queueableFn: { fn: jasmine.createSpy('spec body') }
|
||||
});
|
||||
spec.addExpectationResult(true);
|
||||
expect(spec.status()).toBe('passed');
|
||||
});
|
||||
|
||||
it("#status returns failed if any expectations in the spec have failed", function() {
|
||||
var spec = new jasmineUnderTest.Spec({queueableFn: { fn: jasmine.createSpy("spec body") } });
|
||||
it('#status returns failed if any expectations in the spec have failed', function() {
|
||||
var spec = new jasmineUnderTest.Spec({
|
||||
queueableFn: { fn: jasmine.createSpy('spec body') }
|
||||
});
|
||||
spec.addExpectationResult(true);
|
||||
spec.addExpectationResult(false);
|
||||
expect(spec.status()).toBe('failed');
|
||||
});
|
||||
|
||||
it("keeps track of passed and failed expectations", function() {
|
||||
var resultCallback = jasmine.createSpy('resultCallback'),
|
||||
it('keeps track of passed and failed expectations', function() {
|
||||
var fakeQueueRunner = jasmine.createSpy('queueRunner'),
|
||||
resultCallback = jasmine.createSpy('resultCallback'),
|
||||
spec = new jasmineUnderTest.Spec({
|
||||
queueableFn: { fn: jasmine.createSpy("spec body") },
|
||||
expectationResultFactory: function (data) { return data; },
|
||||
queueRunnerFactory: function(attrs) { attrs.onComplete(); },
|
||||
queueableFn: { fn: jasmine.createSpy('spec body') },
|
||||
expectationResultFactory: function(data) {
|
||||
return data;
|
||||
},
|
||||
queueRunnerFactory: fakeQueueRunner,
|
||||
resultCallback: resultCallback
|
||||
});
|
||||
spec.addExpectationResult(true, 'expectation1');
|
||||
@@ -250,37 +357,54 @@ describe("Spec", function() {
|
||||
|
||||
spec.execute();
|
||||
|
||||
expect(resultCallback.calls.first().args[0].passedExpectations).toEqual(['expectation1']);
|
||||
expect(resultCallback.calls.first().args[0].failedExpectations).toEqual(['expectation2']);
|
||||
fakeQueueRunner.calls.mostRecent().args[0].cleanupFns[0].fn();
|
||||
expect(resultCallback.calls.first().args[0].passedExpectations).toEqual([
|
||||
'expectation1'
|
||||
]);
|
||||
expect(resultCallback.calls.first().args[0].failedExpectations).toEqual([
|
||||
'expectation2'
|
||||
]);
|
||||
});
|
||||
|
||||
it("throws an ExpectationFailed error upon receiving a failed expectation when 'throwOnExpectationFailure' is set", function() {
|
||||
var resultCallback = jasmine.createSpy('resultCallback'),
|
||||
var fakeQueueRunner = jasmine.createSpy('queueRunner'),
|
||||
resultCallback = jasmine.createSpy('resultCallback'),
|
||||
spec = new jasmineUnderTest.Spec({
|
||||
queueableFn: { fn: function() {} },
|
||||
expectationResultFactory: function(data) { return data; },
|
||||
queueRunnerFactory: function(attrs) { attrs.onComplete(); },
|
||||
resultCallback: resultCallback,
|
||||
throwOnExpectationFailure: true
|
||||
});
|
||||
queueableFn: { fn: function() {} },
|
||||
expectationResultFactory: function(data) {
|
||||
return data;
|
||||
},
|
||||
queueRunnerFactory: fakeQueueRunner,
|
||||
resultCallback: resultCallback,
|
||||
throwOnExpectationFailure: true
|
||||
});
|
||||
|
||||
spec.addExpectationResult(true, 'passed');
|
||||
expect(function() {
|
||||
spec.addExpectationResult(false, 'failed')
|
||||
spec.addExpectationResult(false, 'failed');
|
||||
}).toThrowError(jasmineUnderTest.errors.ExpectationFailed);
|
||||
|
||||
spec.execute();
|
||||
|
||||
expect(resultCallback.calls.first().args[0].passedExpectations).toEqual(['passed']);
|
||||
expect(resultCallback.calls.first().args[0].failedExpectations).toEqual(['failed']);
|
||||
fakeQueueRunner.calls.mostRecent().args[0].cleanupFns[0].fn();
|
||||
expect(resultCallback.calls.first().args[0].passedExpectations).toEqual([
|
||||
'passed'
|
||||
]);
|
||||
expect(resultCallback.calls.first().args[0].failedExpectations).toEqual([
|
||||
'failed'
|
||||
]);
|
||||
});
|
||||
|
||||
it("does not throw an ExpectationFailed error when handling an error", function() {
|
||||
it('does not throw an ExpectationFailed error when handling an error', function() {
|
||||
var resultCallback = jasmine.createSpy('resultCallback'),
|
||||
spec = new jasmineUnderTest.Spec({
|
||||
queueableFn: { fn: function() {} },
|
||||
expectationResultFactory: function(data) { return data; },
|
||||
queueRunnerFactory: function(attrs) { attrs.onComplete(); },
|
||||
expectationResultFactory: function(data) {
|
||||
return data;
|
||||
},
|
||||
queueRunnerFactory: function(attrs) {
|
||||
attrs.onComplete();
|
||||
},
|
||||
resultCallback: resultCallback,
|
||||
throwOnExpectationFailure: true
|
||||
});
|
||||
@@ -288,8 +412,10 @@ describe("Spec", function() {
|
||||
spec.onException('failing exception');
|
||||
});
|
||||
|
||||
it("can return its full name", function() {
|
||||
var specNameSpy = jasmine.createSpy('specNameSpy').and.returnValue('expected val');
|
||||
it('can return its full name', function() {
|
||||
var specNameSpy = jasmine
|
||||
.createSpy('specNameSpy')
|
||||
.and.returnValue('expected val');
|
||||
|
||||
var spec = new jasmineUnderTest.Spec({
|
||||
getSpecName: specNameSpy,
|
||||
@@ -300,121 +426,94 @@ describe("Spec", function() {
|
||||
expect(specNameSpy.calls.mostRecent().args[0].id).toEqual(spec.id);
|
||||
});
|
||||
|
||||
describe("when a spec is marked pending during execution", function() {
|
||||
it("should mark the spec as pending", function() {
|
||||
describe('when a spec is marked pending during execution', function() {
|
||||
it('should mark the spec as pending', function() {
|
||||
var fakeQueueRunner = function(opts) {
|
||||
opts.onException(new Error(jasmineUnderTest.Spec.pendingSpecExceptionMessage));
|
||||
opts.onException(
|
||||
new Error(jasmineUnderTest.Spec.pendingSpecExceptionMessage)
|
||||
);
|
||||
},
|
||||
spec = new jasmineUnderTest.Spec({
|
||||
description: 'my test',
|
||||
id: 'some-id',
|
||||
queueableFn: { fn: function() { } },
|
||||
queueableFn: { fn: function() {} },
|
||||
queueRunnerFactory: fakeQueueRunner
|
||||
});
|
||||
|
||||
spec.execute();
|
||||
|
||||
expect(spec.status()).toEqual("pending");
|
||||
expect(spec.status()).toEqual('pending');
|
||||
expect(spec.result.pendingReason).toEqual('');
|
||||
});
|
||||
|
||||
it("should set the pendingReason", function() {
|
||||
it('should set the pendingReason', function() {
|
||||
var fakeQueueRunner = function(opts) {
|
||||
opts.onException(new Error(jasmineUnderTest.Spec.pendingSpecExceptionMessage + 'custom message'));
|
||||
opts.onException(
|
||||
new Error(
|
||||
jasmineUnderTest.Spec.pendingSpecExceptionMessage +
|
||||
'custom message'
|
||||
)
|
||||
);
|
||||
},
|
||||
spec = new jasmineUnderTest.Spec({
|
||||
description: 'my test',
|
||||
id: 'some-id',
|
||||
queueableFn: { fn: function() { } },
|
||||
queueableFn: { fn: function() {} },
|
||||
queueRunnerFactory: fakeQueueRunner
|
||||
});
|
||||
|
||||
spec.execute();
|
||||
|
||||
expect(spec.status()).toEqual("pending");
|
||||
expect(spec.status()).toEqual('pending');
|
||||
expect(spec.result.pendingReason).toEqual('custom message');
|
||||
});
|
||||
});
|
||||
|
||||
it("should log a failure when handling an exception", function() {
|
||||
var resultCallback = jasmine.createSpy('resultCallback'),
|
||||
it('should log a failure when handling an exception', function() {
|
||||
var fakeQueueRunner = jasmine.createSpy('queueRunner'),
|
||||
resultCallback = jasmine.createSpy('resultCallback'),
|
||||
spec = new jasmineUnderTest.Spec({
|
||||
queueableFn: { fn: function() {} },
|
||||
expectationResultFactory: function(data) { return data; },
|
||||
queueRunnerFactory: function(attrs) { attrs.onComplete(); },
|
||||
expectationResultFactory: function(data) {
|
||||
return data;
|
||||
},
|
||||
queueRunnerFactory: fakeQueueRunner,
|
||||
resultCallback: resultCallback
|
||||
});
|
||||
|
||||
spec.onException('foo');
|
||||
spec.execute();
|
||||
|
||||
expect(resultCallback.calls.first().args[0].failedExpectations).toEqual([{
|
||||
error: 'foo',
|
||||
matcherName: '',
|
||||
passed: false,
|
||||
expected: '',
|
||||
actual: ''
|
||||
}]);
|
||||
var args = fakeQueueRunner.calls.mostRecent().args[0];
|
||||
args.cleanupFns[0].fn();
|
||||
expect(resultCallback.calls.first().args[0].failedExpectations).toEqual([
|
||||
{
|
||||
error: 'foo',
|
||||
matcherName: '',
|
||||
passed: false,
|
||||
expected: '',
|
||||
actual: ''
|
||||
}
|
||||
]);
|
||||
});
|
||||
|
||||
it("should not log an additional failure when handling an ExpectationFailed error", function() {
|
||||
var resultCallback = jasmine.createSpy('resultCallback'),
|
||||
it('should not log an additional failure when handling an ExpectationFailed error', function() {
|
||||
var fakeQueueRunner = jasmine.createSpy('queueRunner'),
|
||||
resultCallback = jasmine.createSpy('resultCallback'),
|
||||
spec = new jasmineUnderTest.Spec({
|
||||
queueableFn: { fn: function() {} },
|
||||
expectationResultFactory: function(data) { return data; },
|
||||
queueRunnerFactory: function(attrs) { attrs.onComplete(); },
|
||||
expectationResultFactory: function(data) {
|
||||
return data;
|
||||
},
|
||||
queueRunnerFactory: fakeQueueRunner,
|
||||
resultCallback: resultCallback
|
||||
});
|
||||
|
||||
spec.onException(new jasmineUnderTest.errors.ExpectationFailed());
|
||||
spec.execute();
|
||||
|
||||
var args = fakeQueueRunner.calls.mostRecent().args[0];
|
||||
args.cleanupFns[0].fn();
|
||||
expect(resultCallback.calls.first().args[0].failedExpectations).toEqual([]);
|
||||
});
|
||||
|
||||
it("retrieves a result with updated status", function() {
|
||||
var spec = new jasmineUnderTest.Spec({ queueableFn: { fn: function() {} } });
|
||||
|
||||
expect(spec.getResult().status).toBe('passed');
|
||||
});
|
||||
|
||||
it("retrives a result with disabled status", function() {
|
||||
var spec = new jasmineUnderTest.Spec({ queueableFn: { fn: function() {} } });
|
||||
spec.disable();
|
||||
|
||||
expect(spec.getResult().status).toBe('disabled');
|
||||
});
|
||||
|
||||
it("retrives a result with pending status", function() {
|
||||
var spec = new jasmineUnderTest.Spec({ queueableFn: { fn: function() {} } });
|
||||
spec.pend();
|
||||
|
||||
expect(spec.getResult().status).toBe('pending');
|
||||
});
|
||||
|
||||
it("should not be executable when disabled", function() {
|
||||
var spec = new jasmineUnderTest.Spec({
|
||||
queueableFn: { fn: function() {} }
|
||||
});
|
||||
spec.disable();
|
||||
|
||||
expect(spec.isExecutable()).toBe(false);
|
||||
});
|
||||
|
||||
it("should be executable when pending", function() {
|
||||
var spec = new jasmineUnderTest.Spec({
|
||||
queueableFn: { fn: function() {} }
|
||||
});
|
||||
spec.pend();
|
||||
|
||||
expect(spec.isExecutable()).toBe(true);
|
||||
});
|
||||
|
||||
it("should be executable when not disabled or pending", function() {
|
||||
var spec = new jasmineUnderTest.Spec({
|
||||
queueableFn: { fn: function() {} }
|
||||
});
|
||||
|
||||
expect(spec.isExecutable()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,22 +1,44 @@
|
||||
describe("SpyRegistry", function() {
|
||||
describe("#spyOn", function() {
|
||||
it("checks for the existence of the object", function() {
|
||||
var spyRegistry = new jasmineUnderTest.SpyRegistry();
|
||||
describe('SpyRegistry', function() {
|
||||
function createSpy(name, originalFn) {
|
||||
return jasmineUnderTest.Spy(name, originalFn);
|
||||
}
|
||||
|
||||
describe('#spyOn', function() {
|
||||
it('checks for the existence of the object', function() {
|
||||
var spyRegistry = new jasmineUnderTest.SpyRegistry({
|
||||
createSpy: createSpy
|
||||
});
|
||||
expect(function() {
|
||||
spyRegistry.spyOn(void 0, 'pants');
|
||||
}).toThrowError(/could not find an object/);
|
||||
});
|
||||
|
||||
it("checks that a method name was passed", function() {
|
||||
it('checks that a method name was passed', function() {
|
||||
var spyRegistry = new jasmineUnderTest.SpyRegistry(),
|
||||
subject = {};
|
||||
|
||||
expect(function() {
|
||||
spyRegistry.spyOn(subject);
|
||||
}).toThrowError(/No method name supplied/);
|
||||
expect(function() {
|
||||
spyRegistry.spyOn(subject);
|
||||
}).toThrowError(/No method name supplied/);
|
||||
});
|
||||
|
||||
it("checks for the existence of the method", function() {
|
||||
it('checks that the object is not `null`', function() {
|
||||
var spyRegistry = new jasmineUnderTest.SpyRegistry();
|
||||
expect(function() {
|
||||
spyRegistry.spyOn(null, 'pants');
|
||||
}).toThrowError(/could not find an object/);
|
||||
});
|
||||
|
||||
it('checks that the method name is not `null`', function() {
|
||||
var spyRegistry = new jasmineUnderTest.SpyRegistry(),
|
||||
subject = {};
|
||||
|
||||
expect(function() {
|
||||
spyRegistry.spyOn(subject, null);
|
||||
}).toThrowError(/No method name supplied/);
|
||||
});
|
||||
|
||||
it('checks for the existence of the method', function() {
|
||||
var spyRegistry = new jasmineUnderTest.SpyRegistry(),
|
||||
subject = {};
|
||||
|
||||
@@ -25,9 +47,14 @@ describe("SpyRegistry", function() {
|
||||
}).toThrowError(/method does not exist/);
|
||||
});
|
||||
|
||||
it("checks if it has already been spied upon", function() {
|
||||
it('checks if it has already been spied upon', function() {
|
||||
var spies = [],
|
||||
spyRegistry = new jasmineUnderTest.SpyRegistry({currentSpies: function() { return spies; }}),
|
||||
spyRegistry = new jasmineUnderTest.SpyRegistry({
|
||||
currentSpies: function() {
|
||||
return spies;
|
||||
},
|
||||
createSpy: createSpy
|
||||
}),
|
||||
subject = { spiedFunc: function() {} };
|
||||
|
||||
spyRegistry.spyOn(subject, 'spiedFunc');
|
||||
@@ -37,10 +64,7 @@ describe("SpyRegistry", function() {
|
||||
}).toThrowError(/has already been spied upon/);
|
||||
});
|
||||
|
||||
it("checks if it can be spied upon", function() {
|
||||
// IE 8 doesn't support `definePropery` on non-DOM nodes
|
||||
if (jasmine.getEnv().ieVersion < 9) { return; }
|
||||
|
||||
it('checks if it can be spied upon', function() {
|
||||
var scope = {};
|
||||
|
||||
function myFunc() {
|
||||
@@ -54,7 +78,11 @@ describe("SpyRegistry", function() {
|
||||
});
|
||||
|
||||
var spies = [],
|
||||
spyRegistry = new jasmineUnderTest.SpyRegistry({currentSpies: function() { return spies; }}),
|
||||
spyRegistry = new jasmineUnderTest.SpyRegistry({
|
||||
currentSpies: function() {
|
||||
return spies;
|
||||
}
|
||||
}),
|
||||
subject = { spiedFunc: scope.myFunc };
|
||||
|
||||
expect(function() {
|
||||
@@ -66,21 +94,447 @@ describe("SpyRegistry", function() {
|
||||
}).not.toThrowError(/is not declared writable or has no setter/);
|
||||
});
|
||||
|
||||
it("overrides the method on the object and returns the spy", function() {
|
||||
it('overrides the method on the object and returns the spy', function() {
|
||||
var originalFunctionWasCalled = false,
|
||||
spyRegistry = new jasmineUnderTest.SpyRegistry(),
|
||||
subject = { spiedFunc: function() { originalFunctionWasCalled = true; } };
|
||||
spyRegistry = new jasmineUnderTest.SpyRegistry({
|
||||
createSpy: createSpy
|
||||
}),
|
||||
subject = {
|
||||
spiedFunc: function() {
|
||||
originalFunctionWasCalled = true;
|
||||
}
|
||||
};
|
||||
|
||||
var spy = spyRegistry.spyOn(subject, 'spiedFunc');
|
||||
|
||||
expect(subject.spiedFunc).toEqual(spy);
|
||||
subject.spiedFunc();
|
||||
expect(originalFunctionWasCalled).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#clearSpies", function() {
|
||||
it("restores the original functions on the spied-upon objects", function() {
|
||||
describe('#spyOnProperty', function() {
|
||||
it('checks for the existence of the object', function() {
|
||||
var spyRegistry = new jasmineUnderTest.SpyRegistry();
|
||||
expect(function() {
|
||||
spyRegistry.spyOnProperty(void 0, 'pants');
|
||||
}).toThrowError(/could not find an object/);
|
||||
});
|
||||
|
||||
it('checks that a property name was passed', function() {
|
||||
var spyRegistry = new jasmineUnderTest.SpyRegistry(),
|
||||
subject = {};
|
||||
|
||||
expect(function() {
|
||||
spyRegistry.spyOnProperty(subject);
|
||||
}).toThrowError(/No property name supplied/);
|
||||
});
|
||||
|
||||
it('checks for the existence of the method', function() {
|
||||
var spyRegistry = new jasmineUnderTest.SpyRegistry(),
|
||||
subject = {};
|
||||
|
||||
expect(function() {
|
||||
spyRegistry.spyOnProperty(subject, 'pants');
|
||||
}).toThrowError(/property does not exist/);
|
||||
});
|
||||
|
||||
it('checks for the existence of access type', function() {
|
||||
var spyRegistry = new jasmineUnderTest.SpyRegistry(),
|
||||
subject = {};
|
||||
|
||||
Object.defineProperty(subject, 'pants', {
|
||||
get: function() {
|
||||
return 1;
|
||||
},
|
||||
configurable: true
|
||||
});
|
||||
|
||||
expect(function() {
|
||||
spyRegistry.spyOnProperty(subject, 'pants', 'set');
|
||||
}).toThrowError(/does not have access type/);
|
||||
});
|
||||
|
||||
it('checks if it can be spied upon', function() {
|
||||
var subject = {};
|
||||
|
||||
Object.defineProperty(subject, 'myProp', {
|
||||
get: function() {}
|
||||
});
|
||||
|
||||
Object.defineProperty(subject, 'spiedProp', {
|
||||
get: function() {},
|
||||
configurable: true
|
||||
});
|
||||
|
||||
var spyRegistry = new jasmineUnderTest.SpyRegistry();
|
||||
|
||||
expect(function() {
|
||||
spyRegistry.spyOnProperty(subject, 'myProp');
|
||||
}).toThrowError(/is not declared configurable/);
|
||||
|
||||
expect(function() {
|
||||
spyRegistry.spyOnProperty(subject, 'spiedProp');
|
||||
}).not.toThrowError(/is not declared configurable/);
|
||||
});
|
||||
|
||||
it('overrides the property getter on the object and returns the spy', function() {
|
||||
var spyRegistry = new jasmineUnderTest.SpyRegistry({
|
||||
createSpy: createSpy
|
||||
}),
|
||||
subject = {},
|
||||
returnValue = 1;
|
||||
|
||||
Object.defineProperty(subject, 'spiedProperty', {
|
||||
get: function() {
|
||||
return returnValue;
|
||||
},
|
||||
configurable: true
|
||||
});
|
||||
|
||||
expect(subject.spiedProperty).toEqual(returnValue);
|
||||
|
||||
var spy = spyRegistry.spyOnProperty(subject, 'spiedProperty');
|
||||
var getter = Object.getOwnPropertyDescriptor(subject, 'spiedProperty')
|
||||
.get;
|
||||
|
||||
expect(getter).toEqual(spy);
|
||||
expect(subject.spiedProperty).toBeUndefined();
|
||||
});
|
||||
|
||||
it('overrides the property setter on the object and returns the spy', function() {
|
||||
var spyRegistry = new jasmineUnderTest.SpyRegistry({
|
||||
createSpy: createSpy
|
||||
}),
|
||||
subject = {},
|
||||
returnValue = 1;
|
||||
|
||||
Object.defineProperty(subject, 'spiedProperty', {
|
||||
get: function() {
|
||||
return returnValue;
|
||||
},
|
||||
set: function() {},
|
||||
configurable: true
|
||||
});
|
||||
|
||||
var spy = spyRegistry.spyOnProperty(subject, 'spiedProperty', 'set');
|
||||
var setter = Object.getOwnPropertyDescriptor(subject, 'spiedProperty')
|
||||
.set;
|
||||
|
||||
expect(subject.spiedProperty).toEqual(returnValue);
|
||||
expect(setter).toEqual(spy);
|
||||
});
|
||||
|
||||
describe('when the property is already spied upon', function() {
|
||||
it('throws an error if respy is not allowed', function() {
|
||||
var spyRegistry = new jasmineUnderTest.SpyRegistry({
|
||||
createSpy: createSpy
|
||||
}),
|
||||
subject = {};
|
||||
|
||||
Object.defineProperty(subject, 'spiedProp', {
|
||||
get: function() {
|
||||
return 1;
|
||||
},
|
||||
configurable: true
|
||||
});
|
||||
|
||||
spyRegistry.spyOnProperty(subject, 'spiedProp');
|
||||
|
||||
expect(function() {
|
||||
spyRegistry.spyOnProperty(subject, 'spiedProp');
|
||||
}).toThrowError(/spiedProp#get has already been spied upon/);
|
||||
});
|
||||
|
||||
it('returns the original spy if respy is allowed', function() {
|
||||
var spyRegistry = new jasmineUnderTest.SpyRegistry({
|
||||
createSpy: createSpy
|
||||
}),
|
||||
subject = {};
|
||||
|
||||
spyRegistry.allowRespy(true);
|
||||
|
||||
Object.defineProperty(subject, 'spiedProp', {
|
||||
get: function() {
|
||||
return 1;
|
||||
},
|
||||
configurable: true
|
||||
});
|
||||
|
||||
var originalSpy = spyRegistry.spyOnProperty(subject, 'spiedProp');
|
||||
|
||||
expect(spyRegistry.spyOnProperty(subject, 'spiedProp')).toBe(
|
||||
originalSpy
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#spyOnAllFunctions', function() {
|
||||
it('checks for the existence of the object', function() {
|
||||
var spyRegistry = new jasmineUnderTest.SpyRegistry();
|
||||
expect(function() {
|
||||
spyRegistry.spyOnAllFunctions(void 0);
|
||||
}).toThrowError(/spyOnAllFunctions could not find an object to spy upon/);
|
||||
});
|
||||
|
||||
it('overrides all writable and configurable functions of the object and its parents', function() {
|
||||
var spyRegistry = new jasmineUnderTest.SpyRegistry({
|
||||
createSpy: function() {
|
||||
return 'I am a spy';
|
||||
}
|
||||
});
|
||||
var createNoop = function() {
|
||||
return function() {
|
||||
/**/
|
||||
};
|
||||
};
|
||||
var noop1 = createNoop();
|
||||
var noop2 = createNoop();
|
||||
var noop3 = createNoop();
|
||||
var noop4 = createNoop();
|
||||
var noop5 = createNoop();
|
||||
|
||||
var parent = {
|
||||
parentSpied1: noop1
|
||||
};
|
||||
var subject = Object.create(parent);
|
||||
Object.defineProperty(subject, 'spied1', {
|
||||
value: noop1,
|
||||
writable: true,
|
||||
configurable: true,
|
||||
enumerable: true
|
||||
});
|
||||
Object.defineProperty(subject, 'spied2', {
|
||||
value: noop2,
|
||||
writable: true,
|
||||
configurable: true,
|
||||
enumerable: true
|
||||
});
|
||||
var _spied3 = noop3;
|
||||
Object.defineProperty(subject, 'spied3', {
|
||||
configurable: true,
|
||||
set: function(val) {
|
||||
_spied3 = val;
|
||||
},
|
||||
get: function() {
|
||||
return _spied3;
|
||||
},
|
||||
enumerable: true
|
||||
});
|
||||
subject.spied4 = noop4;
|
||||
Object.defineProperty(subject, 'notSpied2', {
|
||||
value: noop2,
|
||||
writable: false,
|
||||
configurable: true,
|
||||
enumerable: true
|
||||
});
|
||||
Object.defineProperty(subject, 'notSpied3', {
|
||||
value: noop3,
|
||||
writable: true,
|
||||
configurable: false,
|
||||
enumerable: true
|
||||
});
|
||||
Object.defineProperty(subject, 'notSpied4', {
|
||||
configurable: false,
|
||||
set: function(val) {
|
||||
/**/
|
||||
},
|
||||
get: function() {
|
||||
return noop4;
|
||||
},
|
||||
enumerable: true
|
||||
});
|
||||
Object.defineProperty(subject, 'notSpied5', {
|
||||
value: noop5,
|
||||
writable: true,
|
||||
configurable: true,
|
||||
enumerable: false
|
||||
});
|
||||
subject.notSpied6 = 6;
|
||||
|
||||
var spiedObject = spyRegistry.spyOnAllFunctions(subject);
|
||||
|
||||
expect(subject.parentSpied1).toBe('I am a spy');
|
||||
expect(subject.notSpied2).toBe(noop2);
|
||||
expect(subject.notSpied3).toBe(noop3);
|
||||
expect(subject.notSpied4).toBe(noop4);
|
||||
expect(subject.notSpied5).toBe(noop5);
|
||||
expect(subject.notSpied6).toBe(6);
|
||||
expect(subject.spied1).toBe('I am a spy');
|
||||
expect(subject.spied2).toBe('I am a spy');
|
||||
expect(subject.spied3).toBe('I am a spy');
|
||||
expect(subject.spied4).toBe('I am a spy');
|
||||
expect(spiedObject).toBe(subject);
|
||||
});
|
||||
|
||||
it('overrides prototype methods on the object', function() {
|
||||
var spyRegistry = new jasmineUnderTest.SpyRegistry({
|
||||
createSpy: function() {
|
||||
return 'I am a spy';
|
||||
}
|
||||
});
|
||||
|
||||
var noop1 = function() {};
|
||||
var noop2 = function() {};
|
||||
|
||||
var MyClass = function() {
|
||||
this.spied1 = noop1;
|
||||
};
|
||||
MyClass.prototype.spied2 = noop2;
|
||||
|
||||
var subject = new MyClass();
|
||||
spyRegistry.spyOnAllFunctions(subject);
|
||||
|
||||
expect(subject.spied1).toBe('I am a spy');
|
||||
expect(subject.spied2).toBe('I am a spy');
|
||||
expect(MyClass.prototype.spied2).toBe(noop2);
|
||||
});
|
||||
|
||||
it('does not override non-enumerable properties (like Object.prototype methods)', function() {
|
||||
var spyRegistry = new jasmineUnderTest.SpyRegistry({
|
||||
createSpy: function() {
|
||||
return 'I am a spy';
|
||||
}
|
||||
});
|
||||
var subject = {
|
||||
spied1: function() {}
|
||||
};
|
||||
|
||||
spyRegistry.spyOnAllFunctions(subject);
|
||||
|
||||
expect(subject.spied1).toBe('I am a spy');
|
||||
expect(subject.toString).not.toBe('I am a spy');
|
||||
expect(subject.hasOwnProperty).not.toBe('I am a spy');
|
||||
});
|
||||
describe('when includeNonEnumerable is true', function() {
|
||||
it('does not override Object.prototype methods', function() {
|
||||
var spyRegistry = new jasmineUnderTest.SpyRegistry({
|
||||
createSpy: function() {
|
||||
return 'I am a spy';
|
||||
}
|
||||
});
|
||||
var subject = {
|
||||
spied1: function() {}
|
||||
};
|
||||
|
||||
spyRegistry.spyOnAllFunctions(subject, true);
|
||||
|
||||
expect(subject.spied1).toBe('I am a spy');
|
||||
expect(subject.toString).not.toBe('I am a spy');
|
||||
expect(subject.hasOwnProperty).not.toBe('I am a spy');
|
||||
});
|
||||
|
||||
it('overrides non-enumerable properties', function() {
|
||||
var spyRegistry = new jasmineUnderTest.SpyRegistry({
|
||||
createSpy: function() {
|
||||
return 'I am a spy';
|
||||
}
|
||||
});
|
||||
var subject = {
|
||||
spied1: function() {},
|
||||
spied2: function() {}
|
||||
};
|
||||
|
||||
Object.defineProperty(subject, 'spied2', {
|
||||
enumerable: false,
|
||||
writable: true,
|
||||
configurable: true
|
||||
});
|
||||
|
||||
spyRegistry.spyOnAllFunctions(subject, true);
|
||||
|
||||
expect(subject.spied1).toBe('I am a spy');
|
||||
expect(subject.spied2).toBe('I am a spy');
|
||||
});
|
||||
|
||||
it('should not spy on non-enumerable functions named constructor', function() {
|
||||
var spyRegistry = new jasmineUnderTest.SpyRegistry({
|
||||
createSpy: function() {
|
||||
return 'I am a spy';
|
||||
}
|
||||
});
|
||||
var subject = {
|
||||
constructor: function() {}
|
||||
};
|
||||
|
||||
Object.defineProperty(subject, 'constructor', {
|
||||
enumerable: false,
|
||||
writable: true,
|
||||
configurable: true
|
||||
});
|
||||
|
||||
spyRegistry.spyOnAllFunctions(subject, true);
|
||||
|
||||
expect(subject.constructor).not.toBe('I am a spy');
|
||||
});
|
||||
|
||||
it('should spy on enumerable functions named constructor', function() {
|
||||
var spyRegistry = new jasmineUnderTest.SpyRegistry({
|
||||
createSpy: function() {
|
||||
return 'I am a spy';
|
||||
}
|
||||
});
|
||||
var subject = {
|
||||
constructor: function() {}
|
||||
};
|
||||
|
||||
spyRegistry.spyOnAllFunctions(subject, true);
|
||||
|
||||
expect(subject.constructor).toBe('I am a spy');
|
||||
});
|
||||
|
||||
it('should not throw an exception if we try and access strict mode restricted properties', function() {
|
||||
var spyRegistry = new jasmineUnderTest.SpyRegistry({
|
||||
createSpy: function() {
|
||||
return 'I am a spy';
|
||||
}
|
||||
});
|
||||
var subject = function() {};
|
||||
var fn = function() {
|
||||
spyRegistry.spyOnAllFunctions(subject, true);
|
||||
};
|
||||
|
||||
expect(fn).not.toThrow();
|
||||
});
|
||||
|
||||
it('should not spy on properties which are more permissable further up the prototype chain', function() {
|
||||
var spyRegistry = new jasmineUnderTest.SpyRegistry({
|
||||
createSpy: function() {
|
||||
return 'I am a spy';
|
||||
}
|
||||
});
|
||||
var subjectParent = Object.defineProperty({}, 'sharedProp', {
|
||||
value: function() {},
|
||||
writable: true,
|
||||
configurable: true
|
||||
});
|
||||
|
||||
var subject = Object.create(subjectParent);
|
||||
|
||||
Object.defineProperty(subject, 'sharedProp', {
|
||||
value: function() {}
|
||||
});
|
||||
|
||||
var fn = function() {
|
||||
spyRegistry.spyOnAllFunctions(subject, true);
|
||||
};
|
||||
|
||||
expect(fn).not.toThrow();
|
||||
expect(subject).not.toBe('I am a spy');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#clearSpies', function() {
|
||||
it('restores the original functions on the spied-upon objects', function() {
|
||||
var spies = [],
|
||||
spyRegistry = new jasmineUnderTest.SpyRegistry({currentSpies: function() { return spies; }}),
|
||||
spyRegistry = new jasmineUnderTest.SpyRegistry({
|
||||
currentSpies: function() {
|
||||
return spies;
|
||||
},
|
||||
createSpy: createSpy
|
||||
}),
|
||||
originalFunction = function() {},
|
||||
subject = { spiedFunc: originalFunction };
|
||||
|
||||
@@ -90,9 +544,14 @@ describe("SpyRegistry", function() {
|
||||
expect(subject.spiedFunc).toBe(originalFunction);
|
||||
});
|
||||
|
||||
it("restores the original functions, even when that spy has been replace and re-spied upon", function() {
|
||||
it('restores the original functions, even when that spy has been replace and re-spied upon', function() {
|
||||
var spies = [],
|
||||
spyRegistry = new jasmineUnderTest.SpyRegistry({currentSpies: function() { return spies; }}),
|
||||
spyRegistry = new jasmineUnderTest.SpyRegistry({
|
||||
currentSpies: function() {
|
||||
return spies;
|
||||
},
|
||||
createSpy: createSpy
|
||||
}),
|
||||
originalFunction = function() {},
|
||||
subject = { spiedFunc: originalFunction };
|
||||
|
||||
@@ -110,13 +569,15 @@ describe("SpyRegistry", function() {
|
||||
});
|
||||
|
||||
it("does not add a property that the spied-upon object didn't originally have", function() {
|
||||
// IE 8 doesn't support `Object.create`
|
||||
if (jasmine.getEnv().ieVersion < 9) { return; }
|
||||
|
||||
var spies = [],
|
||||
spyRegistry = new jasmineUnderTest.SpyRegistry({currentSpies: function() { return spies; }}),
|
||||
spyRegistry = new jasmineUnderTest.SpyRegistry({
|
||||
currentSpies: function() {
|
||||
return spies;
|
||||
},
|
||||
createSpy: createSpy
|
||||
}),
|
||||
originalFunction = function() {},
|
||||
subjectParent = {spiedFunc: originalFunction};
|
||||
subjectParent = { spiedFunc: originalFunction };
|
||||
|
||||
var subject = Object.create(subjectParent);
|
||||
|
||||
@@ -129,14 +590,16 @@ describe("SpyRegistry", function() {
|
||||
expect(subject.spiedFunc).toBe(originalFunction);
|
||||
});
|
||||
|
||||
it("restores the original function when it\'s inherited and cannot be deleted", function() {
|
||||
// IE 8 doesn't support `Object.create` or `Object.defineProperty`
|
||||
if (jasmine.getEnv().ieVersion < 9) { return; }
|
||||
|
||||
it("restores the original function when it's inherited and cannot be deleted", function() {
|
||||
var spies = [],
|
||||
spyRegistry = new jasmineUnderTest.SpyRegistry({currentSpies: function() { return spies; }}),
|
||||
spyRegistry = new jasmineUnderTest.SpyRegistry({
|
||||
currentSpies: function() {
|
||||
return spies;
|
||||
},
|
||||
createSpy: createSpy
|
||||
}),
|
||||
originalFunction = function() {},
|
||||
subjectParent = {spiedFunc: originalFunction};
|
||||
subjectParent = { spiedFunc: originalFunction };
|
||||
|
||||
var subject = Object.create(subjectParent);
|
||||
|
||||
@@ -151,5 +614,80 @@ describe("SpyRegistry", function() {
|
||||
|
||||
expect(jasmineUnderTest.isSpy(subject.spiedFunc)).toBe(false);
|
||||
});
|
||||
|
||||
it('restores window.onerror by overwriting, not deleting', function() {
|
||||
function FakeWindow() {}
|
||||
FakeWindow.prototype.onerror = function() {};
|
||||
|
||||
var spies = [],
|
||||
global = new FakeWindow(),
|
||||
spyRegistry = new jasmineUnderTest.SpyRegistry({
|
||||
currentSpies: function() {
|
||||
return spies;
|
||||
},
|
||||
createSpy: createSpy,
|
||||
global: global
|
||||
});
|
||||
|
||||
spyRegistry.spyOn(global, 'onerror');
|
||||
spyRegistry.clearSpies();
|
||||
expect(global.onerror).toBe(FakeWindow.prototype.onerror);
|
||||
expect(global.hasOwnProperty('onerror')).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('spying on properties', function() {
|
||||
it('restores the original properties on the spied-upon objects', function() {
|
||||
var spies = [],
|
||||
spyRegistry = new jasmineUnderTest.SpyRegistry({
|
||||
currentSpies: function() {
|
||||
return spies;
|
||||
},
|
||||
createSpy: createSpy
|
||||
}),
|
||||
originalReturn = 1,
|
||||
subject = {};
|
||||
|
||||
Object.defineProperty(subject, 'spiedProp', {
|
||||
get: function() {
|
||||
return originalReturn;
|
||||
},
|
||||
configurable: true
|
||||
});
|
||||
|
||||
spyRegistry.spyOnProperty(subject, 'spiedProp');
|
||||
spyRegistry.clearSpies();
|
||||
|
||||
expect(subject.spiedProp).toBe(originalReturn);
|
||||
});
|
||||
|
||||
it("does not add a property that the spied-upon object didn't originally have", function() {
|
||||
var spies = [],
|
||||
spyRegistry = new jasmineUnderTest.SpyRegistry({
|
||||
currentSpies: function() {
|
||||
return spies;
|
||||
},
|
||||
createSpy: createSpy
|
||||
}),
|
||||
originalReturn = 1,
|
||||
subjectParent = {};
|
||||
|
||||
Object.defineProperty(subjectParent, 'spiedProp', {
|
||||
get: function() {
|
||||
return originalReturn;
|
||||
},
|
||||
configurable: true
|
||||
});
|
||||
|
||||
var subject = Object.create(subjectParent);
|
||||
|
||||
expect(subject.hasOwnProperty('spiedProp')).toBe(false);
|
||||
|
||||
spyRegistry.spyOnProperty(subject, 'spiedProp');
|
||||
spyRegistry.clearSpies();
|
||||
|
||||
expect(subject.hasOwnProperty('spiedProp')).toBe(false);
|
||||
expect(subject.spiedProp).toBe(originalReturn);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,46 +1,82 @@
|
||||
describe('Spies', function () {
|
||||
describe("createSpy", function() {
|
||||
describe('Spies', function() {
|
||||
var env;
|
||||
|
||||
beforeEach(function() {
|
||||
env = new jasmineUnderTest.Env();
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
env.cleanup_();
|
||||
});
|
||||
|
||||
describe('createSpy', function() {
|
||||
var TestClass;
|
||||
|
||||
beforeEach(function() {
|
||||
TestClass = function() {};
|
||||
TestClass.prototype.someFunction = function() {};
|
||||
TestClass.prototype.someFunction.bob = "test";
|
||||
TestClass.prototype.someFunction.bob = 'test';
|
||||
});
|
||||
|
||||
it("preserves the properties of the spied function", function() {
|
||||
var spy = jasmineUnderTest.createSpy(TestClass.prototype, TestClass.prototype.someFunction);
|
||||
it('preserves the properties of the spied function', function() {
|
||||
var spy = env.createSpy(
|
||||
TestClass.prototype,
|
||||
TestClass.prototype.someFunction
|
||||
);
|
||||
|
||||
expect(spy.bob).toEqual("test");
|
||||
expect(spy.bob).toEqual('test');
|
||||
});
|
||||
|
||||
it("warns the user that we intend to overwrite an existing property", function() {
|
||||
TestClass.prototype.someFunction.and = "turkey";
|
||||
it('should allow you to omit the name argument and only pass the originalFn argument', function() {
|
||||
var fn = function test() {};
|
||||
var spy = env.createSpy(fn);
|
||||
|
||||
// IE doesn't do `.name`
|
||||
if (fn.name === 'test') {
|
||||
expect(spy.and.identity).toEqual('test');
|
||||
} else {
|
||||
expect(spy.and.identity).toEqual('unknown');
|
||||
}
|
||||
});
|
||||
|
||||
it('warns the user that we intend to overwrite an existing property', function() {
|
||||
TestClass.prototype.someFunction.and = 'turkey';
|
||||
|
||||
expect(function() {
|
||||
jasmineUnderTest.createSpy(TestClass.prototype, TestClass.prototype.someFunction);
|
||||
}).toThrowError("Jasmine spies would overwrite the 'and' and 'calls' properties on the object being spied upon");
|
||||
env.createSpy(TestClass.prototype, TestClass.prototype.someFunction);
|
||||
}).toThrowError(
|
||||
"Jasmine spies would overwrite the 'and' and 'calls' properties on the object being spied upon"
|
||||
);
|
||||
});
|
||||
|
||||
it("adds a spyStrategy and callTracker to the spy", function() {
|
||||
var spy = jasmineUnderTest.createSpy(TestClass.prototype, TestClass.prototype.someFunction);
|
||||
it('adds a spyStrategy and callTracker to the spy', function() {
|
||||
var spy = env.createSpy(
|
||||
TestClass.prototype,
|
||||
TestClass.prototype.someFunction
|
||||
);
|
||||
|
||||
expect(spy.and).toEqual(jasmine.any(jasmineUnderTest.SpyStrategy));
|
||||
expect(spy.calls).toEqual(jasmine.any(jasmineUnderTest.CallTracker));
|
||||
});
|
||||
|
||||
it("tracks the argument of calls", function () {
|
||||
var spy = jasmineUnderTest.createSpy(TestClass.prototype, TestClass.prototype.someFunction);
|
||||
var trackSpy = spyOn(spy.calls, "track");
|
||||
it('tracks the argument of calls', function() {
|
||||
var spy = env.createSpy(
|
||||
TestClass.prototype,
|
||||
TestClass.prototype.someFunction
|
||||
);
|
||||
var trackSpy = spyOn(spy.calls, 'track');
|
||||
|
||||
spy("arg");
|
||||
spy('arg');
|
||||
|
||||
expect(trackSpy.calls.mostRecent().args[0].args).toEqual(["arg"]);
|
||||
expect(trackSpy.calls.mostRecent().args[0].args).toEqual(['arg']);
|
||||
});
|
||||
|
||||
it("tracks the context of calls", function () {
|
||||
var spy = jasmineUnderTest.createSpy(TestClass.prototype, TestClass.prototype.someFunction);
|
||||
var trackSpy = spyOn(spy.calls, "track");
|
||||
it('tracks the context of calls', function() {
|
||||
var spy = env.createSpy(
|
||||
TestClass.prototype,
|
||||
TestClass.prototype.someFunction
|
||||
);
|
||||
var trackSpy = spyOn(spy.calls, 'track');
|
||||
|
||||
var contextObject = { spyMethod: spy };
|
||||
contextObject.spyMethod();
|
||||
@@ -48,38 +84,218 @@ describe('Spies', function () {
|
||||
expect(trackSpy.calls.mostRecent().args[0].object).toEqual(contextObject);
|
||||
});
|
||||
|
||||
it("tracks the return value of calls", function () {
|
||||
var spy = jasmineUnderTest.createSpy(TestClass.prototype, TestClass.prototype.someFunction);
|
||||
var trackSpy = spyOn(spy.calls, "track");
|
||||
it('tracks the return value of calls', function() {
|
||||
var spy = env.createSpy(
|
||||
TestClass.prototype,
|
||||
TestClass.prototype.someFunction
|
||||
);
|
||||
var trackSpy = spyOn(spy.calls, 'track');
|
||||
|
||||
spy.and.returnValue("return value");
|
||||
spy.and.returnValue('return value');
|
||||
spy();
|
||||
|
||||
expect(trackSpy.calls.mostRecent().args[0].returnValue).toEqual("return value");
|
||||
expect(trackSpy.calls.mostRecent().args[0].returnValue).toEqual(
|
||||
'return value'
|
||||
);
|
||||
});
|
||||
|
||||
it('preserves arity of original function', function() {
|
||||
var functions = [
|
||||
function nullary() {},
|
||||
function unary(arg) {},
|
||||
function binary(arg1, arg2) {},
|
||||
function ternary(arg1, arg2, arg3) {},
|
||||
function quaternary(arg1, arg2, arg3, arg4) {},
|
||||
function quinary(arg1, arg2, arg3, arg4, arg5) {},
|
||||
function senary(arg1, arg2, arg3, arg4, arg5, arg6) {}
|
||||
];
|
||||
|
||||
for (var arity = 0; arity < functions.length; arity++) {
|
||||
var someFunction = functions[arity],
|
||||
spy = env.createSpy(someFunction.name, someFunction);
|
||||
|
||||
expect(spy.length).toEqual(arity);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("createSpyObj", function() {
|
||||
it("should create an object with a bunch of spy methods when you call jasmine.createSpyObj()", function() {
|
||||
var spyObj = jasmineUnderTest.createSpyObj('BaseName', ['method1', 'method2']);
|
||||
describe('createSpyObj', function() {
|
||||
it('should create an object with spy methods and corresponding return values when you call jasmine.createSpyObj() with an object', function() {
|
||||
var spyObj = env.createSpyObj('BaseName', {
|
||||
method1: 42,
|
||||
method2: 'special sauce'
|
||||
});
|
||||
|
||||
expect(spyObj).toEqual({ method1: jasmine.any(Function), method2: jasmine.any(Function)});
|
||||
expect(spyObj.method1.and.identity()).toEqual('BaseName.method1');
|
||||
expect(spyObj.method2.and.identity()).toEqual('BaseName.method2');
|
||||
expect(spyObj.method1()).toEqual(42);
|
||||
expect(spyObj.method1.and.identity).toEqual('BaseName.method1');
|
||||
|
||||
expect(spyObj.method2()).toEqual('special sauce');
|
||||
expect(spyObj.method2.and.identity).toEqual('BaseName.method2');
|
||||
});
|
||||
|
||||
it("should allow you to omit the baseName", function() {
|
||||
var spyObj = jasmineUnderTest.createSpyObj(['method1', 'method2']);
|
||||
it('should create an object with a bunch of spy methods when you call jasmine.createSpyObj()', function() {
|
||||
var spyObj = env.createSpyObj('BaseName', ['method1', 'method2']);
|
||||
|
||||
expect(spyObj).toEqual({ method1: jasmine.any(Function), method2: jasmine.any(Function)});
|
||||
expect(spyObj.method1.and.identity()).toEqual('unknown.method1');
|
||||
expect(spyObj.method2.and.identity()).toEqual('unknown.method2');
|
||||
expect(spyObj).toEqual({
|
||||
method1: jasmine.any(Function),
|
||||
method2: jasmine.any(Function)
|
||||
});
|
||||
expect(spyObj.method1.and.identity).toEqual('BaseName.method1');
|
||||
expect(spyObj.method2.and.identity).toEqual('BaseName.method2');
|
||||
});
|
||||
|
||||
it("should throw if you do not pass an array argument", function() {
|
||||
it('should allow you to omit the baseName', function() {
|
||||
var spyObj = env.createSpyObj(['method1', 'method2']);
|
||||
|
||||
expect(spyObj).toEqual({
|
||||
method1: jasmine.any(Function),
|
||||
method2: jasmine.any(Function)
|
||||
});
|
||||
expect(spyObj.method1.and.identity).toEqual('unknown.method1');
|
||||
expect(spyObj.method2.and.identity).toEqual('unknown.method2');
|
||||
});
|
||||
|
||||
it('should throw if you do not pass an array or object argument', function() {
|
||||
expect(function() {
|
||||
jasmineUnderTest.createSpyObj('BaseName');
|
||||
}).toThrow("createSpyObj requires a non-empty array of method names to create spies for");
|
||||
env.createSpyObj('BaseName');
|
||||
}).toThrow(
|
||||
'createSpyObj requires a non-empty array or object of method names to create spies for'
|
||||
);
|
||||
});
|
||||
|
||||
it('should throw if you pass an empty array argument', function() {
|
||||
expect(function() {
|
||||
env.createSpyObj('BaseName', []);
|
||||
}).toThrow(
|
||||
'createSpyObj requires a non-empty array or object of method names to create spies for'
|
||||
);
|
||||
});
|
||||
|
||||
it('should throw if you pass an empty object argument', function() {
|
||||
expect(function() {
|
||||
env.createSpyObj('BaseName', {});
|
||||
}).toThrow(
|
||||
'createSpyObj requires a non-empty array or object of method names to create spies for'
|
||||
);
|
||||
});
|
||||
|
||||
it('creates an object with spy properties if a second list is passed', function() {
|
||||
var spyObj = env.createSpyObj('base', ['method1'], ['prop1']);
|
||||
|
||||
expect(spyObj).toEqual({
|
||||
method1: jasmine.any(Function),
|
||||
prop1: undefined
|
||||
});
|
||||
|
||||
var descriptor = Object.getOwnPropertyDescriptor(spyObj, 'prop1');
|
||||
expect(descriptor.get.and.identity).toEqual('base.prop1.get');
|
||||
expect(descriptor.set.and.identity).toEqual('base.prop1.set');
|
||||
});
|
||||
|
||||
it('creates an object with property names and return values if second object is passed', function() {
|
||||
var spyObj = env.createSpyObj('base', ['method1'], {
|
||||
prop1: 'foo',
|
||||
prop2: 37
|
||||
});
|
||||
|
||||
expect(spyObj).toEqual({
|
||||
method1: jasmine.any(Function),
|
||||
prop1: 'foo',
|
||||
prop2: 37
|
||||
});
|
||||
|
||||
expect(spyObj.prop1).toEqual('foo');
|
||||
expect(spyObj.prop2).toEqual(37);
|
||||
spyObj.prop2 = 4;
|
||||
expect(spyObj.prop2).toEqual(37);
|
||||
expect(
|
||||
Object.getOwnPropertyDescriptor(spyObj, 'prop2').set.calls.count()
|
||||
).toBe(1);
|
||||
});
|
||||
|
||||
it('allows base name to be omitted when assigning methods and properties', function() {
|
||||
var spyObj = env.createSpyObj({ m: 3 }, { p: 4 });
|
||||
|
||||
expect(spyObj.m()).toEqual(3);
|
||||
expect(spyObj.p).toEqual(4);
|
||||
expect(
|
||||
Object.getOwnPropertyDescriptor(spyObj, 'p').get.and.identity
|
||||
).toEqual('unknown.p.get');
|
||||
});
|
||||
});
|
||||
|
||||
it('can use different strategies for different arguments', function() {
|
||||
var spy = env.createSpy('foo');
|
||||
spy.and.returnValue(42);
|
||||
spy.withArgs('baz', 'grault').and.returnValue(-1);
|
||||
spy.withArgs('thud').and.returnValue('bob');
|
||||
|
||||
expect(spy('foo')).toEqual(42);
|
||||
expect(spy('baz', 'grault')).toEqual(-1);
|
||||
expect(spy('thud')).toEqual('bob');
|
||||
expect(spy('baz', 'grault', 'waldo')).toEqual(42);
|
||||
});
|
||||
|
||||
it('uses custom equality testers when selecting a strategy', function() {
|
||||
var spy = env.createSpy('foo');
|
||||
spy.and.returnValue(42);
|
||||
spy.withArgs(jasmineUnderTest.any(String)).and.returnValue(-1);
|
||||
|
||||
expect(spy('foo')).toEqual(-1);
|
||||
expect(spy({})).toEqual(42);
|
||||
});
|
||||
|
||||
it('can reconfigure an argument-specific strategy', function() {
|
||||
var spy = env.createSpy('foo');
|
||||
spy.withArgs('foo').and.returnValue(42);
|
||||
spy.withArgs('foo').and.returnValue(17);
|
||||
expect(spy('foo')).toEqual(17);
|
||||
});
|
||||
|
||||
describe('any promise-based strategy', function() {
|
||||
it('works with global Promise library when available', function(done) {
|
||||
jasmine.getEnv().requirePromises();
|
||||
|
||||
var spy = env.createSpy('foo').and.resolveTo(42);
|
||||
spy()
|
||||
.then(function(result) {
|
||||
expect(result).toEqual(42);
|
||||
done();
|
||||
})
|
||||
.catch(done.fail);
|
||||
});
|
||||
|
||||
it('works with a custom Promise library', function() {
|
||||
var customPromise = {
|
||||
resolve: jasmine.createSpy(),
|
||||
reject: jasmine.createSpy()
|
||||
};
|
||||
customPromise.resolve.and.returnValue('resolved');
|
||||
env.configure({ Promise: customPromise });
|
||||
|
||||
var spy = env.createSpy('foo').and.resolveTo(42);
|
||||
expect(spy()).toEqual('resolved');
|
||||
expect(customPromise.resolve).toHaveBeenCalledWith(42);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when withArgs is used without a base strategy', function() {
|
||||
it('uses the matching strategy', function() {
|
||||
var spy = env.createSpy('foo');
|
||||
spy.withArgs('baz').and.returnValue(-1);
|
||||
|
||||
expect(spy('baz')).toEqual(-1);
|
||||
});
|
||||
|
||||
it("throws if the args don't match", function() {
|
||||
var spy = env.createSpy('foo');
|
||||
spy.withArgs('bar').and.returnValue(-1);
|
||||
|
||||
expect(function() {
|
||||
spy('baz', { qux: 42 });
|
||||
}).toThrowError(
|
||||
"Spy 'foo' received a call with arguments [ 'baz', Object({ qux: 42 }) ] but all configured strategies specify other arguments."
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user