mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-20 00:51:42 +00:00
Compare commits
656 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
02336fc478 | ||
|
|
c00848c060 | ||
|
|
738a1c015c | ||
|
|
48ae6c954a | ||
|
|
07f70cf784 | ||
|
|
e4e1eab413 | ||
|
|
0e8ff4663d | ||
|
|
54a0a7654a | ||
|
|
59f938b584 | ||
|
|
5513888457 | ||
|
|
02b6615042 | ||
|
|
1f4822f332 | ||
|
|
bb38ef5642 | ||
|
|
ca36d1dce6 | ||
|
|
ee33296e1f | ||
|
|
0ef9803363 | ||
|
|
eedb8910c3 | ||
|
|
8346caed9c | ||
|
|
55b6764d50 | ||
|
|
2c4faee667 | ||
|
|
8d1dee16be | ||
|
|
76b182600a | ||
|
|
c647a801ad | ||
|
|
02131639bc | ||
|
|
566e283694 | ||
|
|
40eb6dfc9b | ||
|
|
a3e5378d14 | ||
|
|
691741cfcb | ||
|
|
166d9e01bf | ||
|
|
7eab4371f4 | ||
|
|
de134a5c60 | ||
|
|
7f074563d0 | ||
|
|
d3dd586362 | ||
|
|
9c85105591 | ||
|
|
86ac70a125 | ||
|
|
3c3a448d47 | ||
|
|
8744511f1d | ||
|
|
7729dd972f | ||
|
|
8b7aa61091 | ||
|
|
88a6b4ac38 | ||
|
|
217b1a2259 | ||
|
|
d2e7a90f41 | ||
|
|
8bd48d6c34 | ||
|
|
1fa0adb091 | ||
|
|
f615e68a43 | ||
|
|
aa4f0ef4f8 | ||
|
|
b42285fddd | ||
|
|
8106fbdbea | ||
|
|
942ba51765 | ||
|
|
33a08d5b34 | ||
|
|
4e3af0756d | ||
|
|
5078f6c92a | ||
|
|
899892c119 | ||
|
|
54326311ad | ||
|
|
fe53dd2f28 | ||
|
|
ab137abab5 | ||
|
|
001dedf3b2 | ||
|
|
f9bece2ffb | ||
|
|
3befc7015b | ||
|
|
de63e1c8a1 | ||
|
|
a76b1aa800 | ||
|
|
350b741adc | ||
|
|
64bfdc1a69 | ||
|
|
65cc85f68d | ||
|
|
6a00dc7976 | ||
|
|
e9e407a87d | ||
|
|
59c4984ed6 | ||
|
|
b428d1e4b3 | ||
|
|
0994364591 | ||
|
|
0b8d3f0260 | ||
|
|
52eba45c51 | ||
|
|
9090a82ef5 | ||
|
|
2a69a4c7dc | ||
|
|
9d2393f97e | ||
|
|
dae619b006 | ||
|
|
9c06d2878b | ||
|
|
e3a2abdf97 | ||
|
|
7867e906e9 | ||
|
|
65a044f633 | ||
|
|
cbd08a1e11 | ||
|
|
e308dd28f3 | ||
|
|
fa0b4428e9 | ||
|
|
26a36779a6 | ||
|
|
dfc0656e5c | ||
|
|
0f3f5218ad | ||
|
|
34c44b7ae9 | ||
|
|
7a250a1b93 | ||
|
|
a338ee8be0 | ||
|
|
c9d440f338 | ||
|
|
a00b2449db | ||
|
|
5c659fdcdf | ||
|
|
d36d72bd4f | ||
|
|
614093c0c4 | ||
|
|
12c4418bda | ||
|
|
0431cf97ff | ||
|
|
ba879f4663 | ||
|
|
96de0b5b11 | ||
|
|
85157a56c3 | ||
|
|
029246ed28 | ||
|
|
6377ab774d | ||
|
|
05e581f409 | ||
|
|
c73dd807e1 | ||
|
|
7a0dd9baa9 | ||
|
|
11f37683c3 | ||
|
|
5af0c9c101 | ||
|
|
259461aee9 | ||
|
|
d214b36786 | ||
|
|
4a07f0380f | ||
|
|
7f46b50b21 | ||
|
|
303c259b89 | ||
|
|
cd1dbb1e3a | ||
|
|
a20474bfc7 | ||
|
|
479d0beb5a | ||
|
|
b93aa176d6 | ||
|
|
9021b37fd2 | ||
|
|
6307d41002 | ||
|
|
df7c1389de | ||
|
|
6accc31ee7 | ||
|
|
f56ec10bcf | ||
|
|
e5e6d6a193 | ||
|
|
c663d7cd16 | ||
|
|
1e8d18b328 | ||
|
|
c2d95db3ab | ||
|
|
dd7563376b | ||
|
|
14fcf3f2f0 | ||
|
|
020ee227d2 | ||
|
|
4d559f3856 | ||
|
|
35d68d2a34 | ||
|
|
7007725d9f | ||
|
|
0c83cad70c | ||
|
|
0001047b8b | ||
|
|
c885251367 | ||
|
|
42096fac3f | ||
|
|
6be9e69d13 | ||
|
|
7bbd13d914 | ||
|
|
2225c4fee2 | ||
|
|
7efab4c43a | ||
|
|
c8e44256ef | ||
|
|
f3cd883c5c | ||
|
|
f34c736fb2 | ||
|
|
1276489961 | ||
|
|
8b2e656bde | ||
|
|
6e9d1f55c6 | ||
|
|
f4dce9e608 | ||
|
|
b9aabc71b0 | ||
|
|
0d54772362 | ||
|
|
faf134a674 | ||
|
|
c24e755409 | ||
|
|
bee9f1cb17 | ||
|
|
45d48d6b5a | ||
|
|
6401aa1fde | ||
|
|
6af4940c22 | ||
|
|
237b2df82f | ||
|
|
a70687aaec | ||
|
|
fbfe85568b | ||
|
|
595b1df380 | ||
|
|
efc7770e9b | ||
|
|
21585f70a8 | ||
|
|
c33fca34e9 | ||
|
|
de95f08a10 | ||
|
|
90f99dc571 | ||
|
|
f34332643a | ||
|
|
4ab095e9c9 | ||
|
|
541753c814 | ||
|
|
f02bb058bd | ||
|
|
12e96c6f13 | ||
|
|
b65447b6f5 | ||
|
|
9945a5b3c6 | ||
|
|
ce4c9edd1f | ||
|
|
a6e6ae41b9 | ||
|
|
f4e2e41aaf | ||
|
|
1e528669ff | ||
|
|
a1ea448406 | ||
|
|
9dc1de1d09 | ||
|
|
0521d85048 | ||
|
|
3c842d8234 | ||
|
|
be77f9cb26 | ||
|
|
2fc60680f4 | ||
|
|
0291a95f68 | ||
|
|
66002d6cac | ||
|
|
a7e9ac1062 | ||
|
|
434d60592c | ||
|
|
ee20747255 | ||
|
|
f4779379c3 | ||
|
|
877a9eae1f | ||
|
|
24752a9751 | ||
|
|
e1dc099517 | ||
|
|
f0cc623241 | ||
|
|
ba3a85d0cc | ||
|
|
79919a5f1c | ||
|
|
94ea5bfb06 | ||
|
|
24680bbd53 | ||
|
|
7fab0e0ef2 | ||
|
|
dd66b23845 | ||
|
|
19addb04cf | ||
|
|
abb66d3e4b | ||
|
|
db4981f166 | ||
|
|
6e1be897de | ||
|
|
423d8f6860 | ||
|
|
eb38204d1a | ||
|
|
1711291cd8 | ||
|
|
57ba58917d | ||
|
|
2249a8bac0 | ||
|
|
c572e6a307 | ||
|
|
e444b6015c | ||
|
|
38dbed8e09 | ||
|
|
34c18ef000 | ||
|
|
0d4fde17e0 | ||
|
|
040a8c6bcc | ||
|
|
4e80570c4c | ||
|
|
91529cc435 | ||
|
|
ef3267833f | ||
|
|
a5ef50c9e7 | ||
|
|
6eee457898 | ||
|
|
fb6d7b3470 | ||
|
|
2d78fdabb8 | ||
|
|
94c31ceeb1 | ||
|
|
67d4da51ee | ||
|
|
6e4f66cc8b | ||
|
|
a4e781a231 | ||
|
|
f151892db5 | ||
|
|
c45fb73f36 | ||
|
|
848280d1f1 | ||
|
|
f7016b359f | ||
|
|
be58a279a5 | ||
|
|
909e6c4857 | ||
|
|
5c0b08f4f5 | ||
|
|
05d1cfa276 | ||
|
|
ae675ae4e1 | ||
|
|
d3b636d073 | ||
|
|
8b460f5944 | ||
|
|
bdfa32876b | ||
|
|
4a3472ebb2 | ||
|
|
9c804c1351 | ||
|
|
2a9c454baa | ||
|
|
1a9a6c3678 | ||
|
|
e1195e8b9d | ||
|
|
50ed55e8e2 | ||
|
|
d682295ccd | ||
|
|
5e19c1881f | ||
|
|
617ff52f18 | ||
|
|
5d3af62c0e | ||
|
|
ddd5aeba19 | ||
|
|
3cfcbe9a95 | ||
|
|
6bc793505d | ||
|
|
3b44160cff | ||
|
|
d9586c8d38 | ||
|
|
74df3fac4e | ||
|
|
06321b8e87 | ||
|
|
f3efb948fe | ||
|
|
432c03bf63 | ||
|
|
bfd224278b | ||
|
|
822ea6abc8 | ||
|
|
97437ee58b | ||
|
|
aa7fe0db29 | ||
|
|
237685d4a5 | ||
|
|
abbe630274 | ||
|
|
89d3b08e77 | ||
|
|
f826216a28 | ||
|
|
aa0a874ad0 | ||
|
|
2da26c0579 | ||
|
|
d34c844900 | ||
|
|
68b63632c4 | ||
|
|
d2de94778e | ||
|
|
4fd4a50d41 | ||
|
|
9d93820717 | ||
|
|
c57a7f0a41 | ||
|
|
1d15fcd072 | ||
|
|
e824b1129e | ||
|
|
0cd03c66e3 | ||
|
|
462b231dac | ||
|
|
e4a918850f | ||
|
|
d472af3517 | ||
|
|
98a587a347 | ||
|
|
5fd996876b | ||
|
|
b433d98c02 | ||
|
|
7006672b06 | ||
|
|
efec0c5cc3 | ||
|
|
16e71eac43 | ||
|
|
68b62abb52 | ||
|
|
b2f3479692 | ||
|
|
67d62ba164 | ||
|
|
e1fc60b8dd | ||
|
|
f32e696fef | ||
|
|
fc81298fac | ||
|
|
5987cfeaaf | ||
|
|
cd0ece4511 | ||
|
|
dc9f85ebb9 | ||
|
|
35a2055cda | ||
|
|
a1066776a5 | ||
|
|
4dae747343 | ||
|
|
d348a5b947 | ||
|
|
f0c413f40d | ||
|
|
846eee2f6c | ||
|
|
0b9ff68da1 | ||
|
|
7187e005d4 | ||
|
|
a5cd24e7ea | ||
|
|
dbe821baee | ||
|
|
04486c6472 | ||
|
|
2ee8ba9361 | ||
|
|
b07782cd89 | ||
|
|
305450b6e4 | ||
|
|
fdd0b853ed | ||
|
|
1d025204e7 | ||
|
|
12f759860e | ||
|
|
1bdbb5ddcc | ||
|
|
b573fb6555 | ||
|
|
b50a7bdbee | ||
|
|
5a5f10dfc8 | ||
|
|
e375b4a9ff | ||
|
|
ff141ab1ff | ||
|
|
b8537be219 | ||
|
|
8f1b034b2f | ||
|
|
71d0a07e0a | ||
|
|
d322342494 | ||
|
|
bc7ab17692 | ||
|
|
7a049c29bd | ||
|
|
1fc375b31a | ||
|
|
eee7f3991c | ||
|
|
2e3503517d | ||
|
|
15e58acc76 | ||
|
|
5aa5e3e09e | ||
|
|
25ae7b2c2b | ||
|
|
4b6dc9583a | ||
|
|
64eab1f7b3 | ||
|
|
182f57216f | ||
|
|
65b091a39a | ||
|
|
ed1a94531a | ||
|
|
4e12ffb0ae | ||
|
|
4800c201e4 | ||
|
|
dc9a9e5d96 | ||
|
|
6844f05c3d | ||
|
|
8f67f2c24c | ||
|
|
cc246bb9ac | ||
|
|
bf9f0a9e6d | ||
|
|
c3160bad44 | ||
|
|
94b8ac42ca | ||
|
|
a03e3d7eb9 | ||
|
|
a42ec08d16 | ||
|
|
fddb6cd9d8 | ||
|
|
841f016017 | ||
|
|
8e4afc95c7 | ||
|
|
8cec948699 | ||
|
|
31ae7c942c | ||
|
|
d0900626da | ||
|
|
0ee4cadca0 | ||
|
|
24b5a9c389 | ||
|
|
626220e9f3 | ||
|
|
323d68d460 | ||
|
|
db2091dd94 | ||
|
|
8216d85e52 | ||
|
|
a705eb1c61 | ||
|
|
77f664a6b1 | ||
|
|
c30057e923 | ||
|
|
06108b9479 | ||
|
|
16181523c9 | ||
|
|
7e0706cf83 | ||
|
|
bff67887fd | ||
|
|
351ff5eb48 | ||
|
|
051df14046 | ||
|
|
ee0318f697 | ||
|
|
a6fb1efcbe | ||
|
|
31fecc28a4 | ||
|
|
30b1efc354 | ||
|
|
7d721eb569 | ||
|
|
d48aac5beb | ||
|
|
14b56db99e | ||
|
|
bfe429de51 | ||
|
|
57ef5cfd07 | ||
|
|
4bbb7c0bcc | ||
|
|
4de70bff5e | ||
|
|
687f0c7dc0 | ||
|
|
f3d66e92ec | ||
|
|
9a91ae54d6 | ||
|
|
69422dc063 | ||
|
|
7bcd243ec3 | ||
|
|
8f70bea899 | ||
|
|
948c4275ad | ||
|
|
03a1159915 | ||
|
|
1c8fb298b4 | ||
|
|
b25a7cb370 | ||
|
|
140c365e4b | ||
|
|
8c93ceb728 | ||
|
|
ac50d7cf8a | ||
|
|
ecb873ff45 | ||
|
|
78baa04ecc | ||
|
|
b78f580d47 | ||
|
|
b115c75226 | ||
|
|
6bc092f3ae | ||
|
|
f99a266ce4 | ||
|
|
1f724d58e0 | ||
|
|
de4a246bb4 | ||
|
|
412b80da30 | ||
|
|
47319960a5 | ||
|
|
b22d218236 | ||
|
|
6eb82bc314 | ||
|
|
a06dd25d56 | ||
|
|
e1bb05bc52 | ||
|
|
8694a020ac | ||
|
|
1efb2e4d3d | ||
|
|
861726cefa | ||
|
|
81212d80c6 | ||
|
|
2235a809c4 | ||
|
|
3fe0f49ac0 | ||
|
|
03d8f9193b | ||
|
|
5e54969f6b | ||
|
|
18ef5eb1bf | ||
|
|
b5e3d92e9d | ||
|
|
ba8761e39e | ||
|
|
78f0b1562c | ||
|
|
5c28b30028 | ||
|
|
59267da72b | ||
|
|
36ad45c07d | ||
|
|
ecb2add791 | ||
|
|
9bbdaf300b | ||
|
|
bc492bb40e | ||
|
|
81221c4874 | ||
|
|
137b3d81fb | ||
|
|
6741f47ef1 | ||
|
|
e75e9092a8 | ||
|
|
247cef5ec2 | ||
|
|
29f999e2b2 | ||
|
|
5e3755493d | ||
|
|
70343c0b3f | ||
|
|
60e199b0bd | ||
|
|
1071686d81 | ||
|
|
fdebdd520a | ||
|
|
5ca5583fc3 | ||
|
|
75463a249f | ||
|
|
7280d241f0 | ||
|
|
963391cf39 | ||
|
|
4f4c52d6d5 | ||
|
|
499da6d08d | ||
|
|
39e4d11f8e | ||
|
|
df4a2c07f0 | ||
|
|
c46c490376 | ||
|
|
f2751db5c2 | ||
|
|
2bff276adb | ||
|
|
e5e1a1a4d1 | ||
|
|
0613f1d182 | ||
|
|
8b94e0933a | ||
|
|
23ef57561d | ||
|
|
33b95816ee | ||
|
|
4c1e4fd80c | ||
|
|
3784b665de | ||
|
|
567ea1d58d | ||
|
|
55346e28d0 | ||
|
|
49b8c4ba78 | ||
|
|
f1c2b66569 | ||
|
|
27bf94fd06 | ||
|
|
4896a77c86 | ||
|
|
d1d3f049f2 | ||
|
|
c313dde03a | ||
|
|
8d1c51b7e9 | ||
|
|
a59e00e901 | ||
|
|
7070162b98 | ||
|
|
9859c14ca1 | ||
|
|
64ebe7f5e5 | ||
|
|
8b2345a706 | ||
|
|
e65f9908d7 | ||
|
|
fd52912d74 | ||
|
|
9e7993905f | ||
|
|
a656207220 | ||
|
|
81e63ea3a5 | ||
|
|
5dfae8d6bd | ||
|
|
107a4cc1e2 | ||
|
|
35d51d68f7 | ||
|
|
049fec470b | ||
|
|
659dbef751 | ||
|
|
ac9b6f7b18 | ||
|
|
425ed464ed | ||
|
|
2c15bb247e | ||
|
|
28e178b1a8 | ||
|
|
5d2a08443b | ||
|
|
087eeec760 | ||
|
|
dbe03afb9a | ||
|
|
2ecb939b35 | ||
|
|
1416fb8f67 | ||
|
|
aeb6c4889b | ||
|
|
c2fc6711d8 | ||
|
|
f271185cbc | ||
|
|
4fc7daedc9 | ||
|
|
6bfc008673 | ||
|
|
2c94d0ba2f | ||
|
|
0cd05d1a42 | ||
|
|
ff93050b31 | ||
|
|
05626cfafe | ||
|
|
59ec54887d | ||
|
|
028efff50d | ||
|
|
2499771cf4 | ||
|
|
c989ae808b | ||
|
|
93b486b6ba | ||
|
|
2ec6132fcb | ||
|
|
8aba2b2850 | ||
|
|
32c95fa0da | ||
|
|
40365faeda | ||
|
|
776cb915bc | ||
|
|
5e9fe2f5cb | ||
|
|
7501ae65a1 | ||
|
|
63469c00c4 | ||
|
|
3df257cdbb | ||
|
|
45b8e9ab4f | ||
|
|
227fdc1a60 | ||
|
|
d347cebf67 | ||
|
|
3819cd0768 | ||
|
|
e8f1fdda44 | ||
|
|
fd4719cb87 | ||
|
|
6ef4745d86 | ||
|
|
62a980d3c8 | ||
|
|
866046edd1 | ||
|
|
8ac7e44f19 | ||
|
|
a831978cce | ||
|
|
8da577b56f | ||
|
|
512ecf6490 | ||
|
|
0901ae0808 | ||
|
|
1ca291f20b | ||
|
|
75eabfee1c | ||
|
|
f7c3f13a7f | ||
|
|
57efd13f7f | ||
|
|
7ddc153623 | ||
|
|
f9ebd3bde6 | ||
|
|
2c911b0f7a | ||
|
|
1bf2d58db1 | ||
|
|
c93b5bedf9 | ||
|
|
dffaa0abb9 | ||
|
|
20c6525b1d | ||
|
|
fe7165a8f7 | ||
|
|
d2aa168f66 | ||
|
|
05c00430b3 | ||
|
|
5305087162 | ||
|
|
6251697f60 | ||
|
|
ea1a1e6bc3 | ||
|
|
edf5ecd4a0 | ||
|
|
1b1ee7f9f3 | ||
|
|
3fade171f9 | ||
|
|
c99e89dfca | ||
|
|
b51e85ae26 | ||
|
|
4a98e68815 | ||
|
|
0cb288ffba | ||
|
|
e44a6e227a | ||
|
|
aafca4ed7f | ||
|
|
ea6876e81f | ||
|
|
aa9c2b2c92 | ||
|
|
43a2eccdc9 | ||
|
|
b637b9ee4c | ||
|
|
5ad28d58ec | ||
|
|
be2647d44e | ||
|
|
4a3e3a6324 | ||
|
|
7597e3c274 | ||
|
|
0a983eeeb8 | ||
|
|
b036bf2e34 | ||
|
|
73602e6cb4 | ||
|
|
72455280a9 | ||
|
|
ea95bb85aa | ||
|
|
fb865d3ee7 | ||
|
|
36ac37db8c | ||
|
|
b45e0917ae | ||
|
|
0e127679c1 | ||
|
|
2f36d508c4 | ||
|
|
cf29d4560b | ||
|
|
8c4ad62422 | ||
|
|
62c217cd01 | ||
|
|
0f105a26f7 | ||
|
|
47694ef810 | ||
|
|
f77a976fbb | ||
|
|
3593ecb17e | ||
|
|
9b2af0d090 | ||
|
|
e8e052712e | ||
|
|
77a1af44c4 | ||
|
|
5e2a76147c | ||
|
|
e1d4845ccd | ||
|
|
95d40ed01f | ||
|
|
aa22d4c33b | ||
|
|
046e043c4e | ||
|
|
74fc10999b | ||
|
|
cee9b2609d | ||
|
|
daa0260a4e | ||
|
|
d66c61a36e | ||
|
|
ecc210f99a | ||
|
|
3cacc2aba6 | ||
|
|
085c47b671 | ||
|
|
039515082a | ||
|
|
c3908660b1 | ||
|
|
fc515f4572 | ||
|
|
5a82f73d9b | ||
|
|
776a991d61 | ||
|
|
8527f2c2a1 | ||
|
|
c85b72b952 | ||
|
|
f0d9e19b5c | ||
|
|
c7c011813f | ||
|
|
d76f0d4022 | ||
|
|
de7678f2fc | ||
|
|
2f7eff7091 | ||
|
|
7a402b4170 | ||
|
|
10b4814e60 | ||
|
|
613309c0a2 | ||
|
|
c622c03eff | ||
|
|
ed7d2d6aa6 | ||
|
|
51ff9e9f69 | ||
|
|
9f2f301fa4 | ||
|
|
fa8bb3fa91 | ||
|
|
4af0bbddee | ||
|
|
4aca3c2022 | ||
|
|
753ab85efb | ||
|
|
da6b8c7ae1 | ||
|
|
305ab08f1c | ||
|
|
e9718fc7bf | ||
|
|
8566878af4 | ||
|
|
62812faf62 | ||
|
|
d82635bbe1 | ||
|
|
a598e2d09b | ||
|
|
b5b2f0c7d8 | ||
|
|
e6f6d24780 | ||
|
|
21b2aabf18 | ||
|
|
74f9da9da1 | ||
|
|
e63830ed21 | ||
|
|
eb51de65e5 | ||
|
|
565a125dad | ||
|
|
3af8e7e9fd | ||
|
|
e3eae023da | ||
|
|
6d9b3b0aaa | ||
|
|
9e99df1cf7 | ||
|
|
e842ff7ad5 | ||
|
|
21b1e39b2a | ||
|
|
8fc55c80a9 | ||
|
|
248ca0c4a0 | ||
|
|
0d655d7cec | ||
|
|
e71f454b9d | ||
|
|
54092378e9 | ||
|
|
a4f0c4fbe0 | ||
|
|
0965d60a71 | ||
|
|
f2d601d834 | ||
|
|
e14e45da76 | ||
|
|
68690643d2 | ||
|
|
00b2902102 | ||
|
|
975568c774 | ||
|
|
a834fff7b2 | ||
|
|
64ab6e51fe | ||
|
|
05a2089816 | ||
|
|
b827f484be | ||
|
|
000a98f193 | ||
|
|
bb64dd3546 | ||
|
|
d0c40b5ce2 | ||
|
|
6794ff9ce8 | ||
|
|
083362bd86 | ||
|
|
0f228e7b7d | ||
|
|
686f5d9fef | ||
|
|
ad8763fc8d | ||
|
|
1011b56b4c | ||
|
|
5904314a75 | ||
|
|
e852547344 | ||
|
|
fa8b68419f | ||
|
|
ec13d00b18 | ||
|
|
36447d86d8 | ||
|
|
1e14403b3b | ||
|
|
bee507eda8 |
107
.clang-format
Normal file
107
.clang-format
Normal file
@@ -0,0 +1,107 @@
|
||||
---
|
||||
Language: Cpp
|
||||
BasedOnStyle: Google
|
||||
AccessModifierOffset: -1
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignEscapedNewlines: Left
|
||||
AlignOperands: true
|
||||
AlignTrailingComments: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowShortBlocksOnASingleLine: false
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: All
|
||||
AllowShortIfStatementsOnASingleLine: true
|
||||
AllowShortLoopsOnASingleLine: true
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: true
|
||||
AlwaysBreakTemplateDeclarations: true
|
||||
BinPackArguments: true
|
||||
BinPackParameters: true
|
||||
BraceWrapping:
|
||||
AfterClass: false
|
||||
AfterControlStatement: false
|
||||
AfterEnum: false
|
||||
AfterFunction: false
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: false
|
||||
AfterStruct: false
|
||||
AfterUnion: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: true
|
||||
SplitEmptyRecord: true
|
||||
SplitEmptyNamespace: true
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeBraces: Attach
|
||||
BreakBeforeInheritanceComma: false
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
BreakConstructorInitializers: BeforeColon
|
||||
BreakAfterJavaFieldAnnotations: false
|
||||
BreakStringLiterals: true
|
||||
ColumnLimit: 80
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
CompactNamespaces: false
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: true
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
FixNamespaceComments: true
|
||||
ForEachMacros:
|
||||
- foreach
|
||||
- Q_FOREACH
|
||||
- BOOST_FOREACH
|
||||
IncludeCategories:
|
||||
- Regex: '^<.*\.h>'
|
||||
Priority: 1
|
||||
- Regex: '^<.*'
|
||||
Priority: 2
|
||||
- Regex: '.*'
|
||||
Priority: 3
|
||||
IncludeIsMainRegex: '([-_](test|unittest))?$'
|
||||
IndentCaseLabels: true
|
||||
IndentWidth: 2
|
||||
IndentWrappedFunctionNames: false
|
||||
JavaScriptQuotes: Leave
|
||||
JavaScriptWrapImports: true
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None
|
||||
ObjCBlockIndentWidth: 2
|
||||
ObjCSpaceAfterProperty: false
|
||||
ObjCSpaceBeforeProtocolList: false
|
||||
PenaltyBreakAssignment: 2
|
||||
PenaltyBreakBeforeFirstCallParameter: 1
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 200
|
||||
PointerAlignment: Left
|
||||
ReflowComments: true
|
||||
SortIncludes: false
|
||||
SortUsingDeclarations: true
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterTemplateKeyword: true
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 2
|
||||
SpacesInAngles: false
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: Auto
|
||||
TabWidth: 8
|
||||
UseTab: Never
|
||||
...
|
||||
50
.gitignore
vendored
50
.gitignore
vendored
@@ -1,13 +1,10 @@
|
||||
# WPIlib Specific
|
||||
|
||||
dependency-reduced-pom.xml
|
||||
/wpilibj/src/athena/cpp/nivision/*.c
|
||||
/wpilibj/src/athena/cpp/nivision/*.cpp
|
||||
/wpilibj/src/athena/cpp/nivision/*.s
|
||||
/wpilibj/src/athena/cpp/nivision/*_arm.ini
|
||||
/wpilibj/src/athena/cpp/nivision/*.java
|
||||
/wpilibj/src/athena/cpp/nivision/nivision_funcs.txt
|
||||
/wpilibj/src/athena/cpp/nivision/imaqdx_funcs.txt
|
||||
/wpilibj/src/shared/java/edu/wpi/first/wpilibj/util/WPILibVersion.java
|
||||
/wpilibc/shared/src/WPILibVersion.cpp
|
||||
/wpilibj/src/main/java/edu/wpi/first/wpilibj/util/WPILibVersion.java
|
||||
/wpilibc/src/main/native/cpp/WPILibVersion.cpp
|
||||
doxygen.log
|
||||
|
||||
# Created by the jenkins test script
|
||||
@@ -15,6 +12,8 @@ test-reports
|
||||
|
||||
# IntelliJ
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
.idea/
|
||||
|
||||
# Created by http://www.gitignore.io
|
||||
@@ -155,6 +154,9 @@ local.properties
|
||||
*.pyc
|
||||
__pycache__
|
||||
|
||||
# Gradle wrapper
|
||||
!gradle-wrapper.jar
|
||||
|
||||
# External tool builders
|
||||
.externalToolBuilders/
|
||||
|
||||
@@ -181,3 +183,37 @@ NO
|
||||
|
||||
# Simulation folder stuff
|
||||
!simulation/install_resources/*
|
||||
|
||||
# VSCode
|
||||
.vscode/
|
||||
|
||||
#classpaths and projects
|
||||
.project
|
||||
.classpath
|
||||
|
||||
#Visual Studio
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
*.VC.db-shm
|
||||
*.VC.db-wal
|
||||
|
||||
*.sln
|
||||
*.vcxproj
|
||||
*.vcxproj.filters
|
||||
|
||||
# Visual Studio 2015 cache/options directory
|
||||
.vs/
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
[gerrit]
|
||||
host=usfirst.collab.net
|
||||
port=29418
|
||||
project=allwpilib
|
||||
defaultbranch=master
|
||||
41
.styleguide
Normal file
41
.styleguide
Normal file
@@ -0,0 +1,41 @@
|
||||
cppHeaderFileInclude {
|
||||
\.h$
|
||||
\.hpp$
|
||||
\.inc$
|
||||
}
|
||||
|
||||
cppSrcFileInclude {
|
||||
\.cpp$
|
||||
}
|
||||
|
||||
generatedFileExclude {
|
||||
gmock/
|
||||
ni-libraries/include/
|
||||
ni-libraries/lib/
|
||||
hal/src/main/native/athena/ctre/
|
||||
hal/src/main/native/athena/frccansae/
|
||||
hal/src/main/native/athena/visa/
|
||||
hal/src/main/native/include/ctre/
|
||||
UsageReporting\.h$
|
||||
}
|
||||
|
||||
modifiableFileExclude {
|
||||
wpilibj/src/arm-linux-jni/
|
||||
wpilibj/src/main/native/cpp/
|
||||
\.patch$
|
||||
\.png$
|
||||
\.py$
|
||||
\.so$
|
||||
}
|
||||
|
||||
includeOtherLibs {
|
||||
^HAL/
|
||||
^llvm/
|
||||
^networktables/
|
||||
^opencv2/
|
||||
^support/
|
||||
}
|
||||
|
||||
includeProject {
|
||||
^ctre/
|
||||
}
|
||||
6
.styleguide-license
Normal file
6
.styleguide-license
Normal file
@@ -0,0 +1,6 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) {year} FIRST. All Rights Reserved.{padding}*/
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
40
.travis.yml
Normal file
40
.travis.yml
Normal file
@@ -0,0 +1,40 @@
|
||||
sudo: true
|
||||
dist: trusty
|
||||
language: java
|
||||
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- deadsnakes
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- g++-6
|
||||
- python3.5
|
||||
|
||||
before_install:
|
||||
- sudo sh -c 'echo "deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-5.0 main" > /etc/apt/sources.list.d/llvm.list'
|
||||
- wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key|sudo apt-key add -
|
||||
- sudo apt-get update -q || true
|
||||
- sudo apt-get install clang-format-5.0 -y
|
||||
|
||||
install:
|
||||
- wget https://bootstrap.pypa.io/get-pip.py
|
||||
- sudo python3.5 get-pip.py
|
||||
- python3.5 -m pip install --user wpiformat
|
||||
- mkdir -p $HOME/latest-gcc-symlinks # see travis-ci/travis-ci#3668
|
||||
- ln -s /usr/bin/g++-6 $HOME/latest-gcc-symlinks/g++
|
||||
- ln -s /usr/bin/gcc-6 $HOME/latest-gcc-symlinks/gcc
|
||||
- export PATH=$HOME/latest-gcc-symlinks:$PATH
|
||||
|
||||
before_cache:
|
||||
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.gradle/caches/
|
||||
- $HOME/.gradle/wrapper/
|
||||
|
||||
script:
|
||||
- python3.5 -m wpiformat -y 2018 -clang 5.0
|
||||
- git --no-pager diff --exit-code HEAD # Ensure formatter made no changes
|
||||
- ./gradlew --no-daemon --console=plain -PskipAthena :hal:halSimSharedLibrary :wpilibc:wpilibcSharedLibrary :wpilibj:wpilibJNISharedSharedLibrary :wpilibj:jar
|
||||
@@ -1,24 +0,0 @@
|
||||
* Copyright (c) 2009-2016 FIRST
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the FIRST nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY FIRST AND CONTRIBUTORS``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY NONINFRINGEMENT AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL FIRST OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
@@ -1,39 +0,0 @@
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
project(AllC++Sim)
|
||||
|
||||
include(CheckCXXCompilerFlag)
|
||||
include (FindPkgConfig)
|
||||
include(GNUInstallDirs)
|
||||
|
||||
#check for depenedencies
|
||||
find_package(gazebo REQUIRED)
|
||||
find_package(Boost COMPONENTS system filesystem REQUIRED)
|
||||
|
||||
#on windows we produce .dlls with no prefix
|
||||
if(WIN32)
|
||||
#allows us to define constexpr and noexcept in macros
|
||||
#since msvc 2013 doesn't support them
|
||||
add_definitions(-D_ALLOW_KEYWORD_MACROS)
|
||||
|
||||
# defines things like M_PI
|
||||
add_definitions(-D_USE_MATH_DEFINES)
|
||||
|
||||
# get rid of min max macros on windows
|
||||
add_definitions(-DNOMINMAX)
|
||||
|
||||
add_definitions(-DWIN32_LEAN_AND_MEAN)
|
||||
|
||||
SET(CMAKE_FIND_LIBRARY_PREFIXES "")
|
||||
SET(CMAKE_FIND_LIBRARY_SUFFIXES ".lib" ".dll")
|
||||
endif()
|
||||
|
||||
if (MSVC)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DFRC_SIMULATOR /MDd /Zi")
|
||||
else ()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -std=c++1y -DFRC_SIMULATOR -Wno-unused-parameter -pthread -fPIC -fpermissive")
|
||||
endif()
|
||||
|
||||
include_directories("build")
|
||||
add_subdirectory(simulation/gz_msgs)
|
||||
add_subdirectory(wpilibc/simulation)
|
||||
add_subdirectory(simulation/frc_gazebo_plugins)
|
||||
56
CONTRIBUTING.md
Normal file
56
CONTRIBUTING.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# Contributing to WPILib
|
||||
|
||||
So you want to contribute your changes back to WPILib. Great! We have a few contributing rules that will help you make sure your changes will be accepted into the project. Please remember to follow the rules written here, and behave with Gracious Professionalism.
|
||||
|
||||
- [General Contribution Rules](#general-contribution-rules)
|
||||
- [What to Contribute](#what-to-contribute)
|
||||
- [Coding Guidelines](#coding-guidelines)
|
||||
- [Submitting Changes](#submitting-changes)
|
||||
- [Pull Request Format](#pull-request-format)
|
||||
- [Merge Process](#merge-process)
|
||||
- [Licensing](#licensing)
|
||||
|
||||
## General Contribution Rules
|
||||
|
||||
- Everything in the library must work for the 3000+ teams that will be using it.
|
||||
- We need to be able to maintain submitted changes, even if you are no longer working on the project.
|
||||
- Tool suite changes must be generally useful to a broad range of teams
|
||||
- Excluding bug fixes, changes in one language generally need to have corresponding changes in other languages.
|
||||
- Some features, such the addition of C++11 for WPILibC or Functional Interfaces for WPILibJ, are specific to that version of WPILib only.
|
||||
- Substantial changes often need to have corresponding LabVIEW changes. To do this, we will work with NI on these large changes.
|
||||
- Changes should have tests.
|
||||
- Code should be well documented.
|
||||
- This often involves ScreenSteps. To add content to ScreenSteps, we will work with you to get the appropriate articles written.
|
||||
|
||||
## What to Contribute
|
||||
|
||||
- Bug reports and fixes
|
||||
- We will generally accept bug fixes without too much question. If they are only implemented for one language, we will implement them for any other necessary languages. Bug reports are also welcome, please submit them to our GitHub issue tracker.
|
||||
- While we do welcome improvements to the API, there are a few important rules to consider:
|
||||
- Features must be added to both WPILibC and WPILibJ, with rare exceptions.
|
||||
- During competition season, we will not merge any new feature additions. We want to ensure that the API is stable during the season to help minimize issues for teams.
|
||||
- Ask about large changes before spending a bunch of time on them! You can create a new issue on our GitHub tracker for feature request/discussion and talk about it with us there.
|
||||
- Features that make it easier for teams with less experience to be more successful are more likely to be accepted.
|
||||
- Features in WPILib should be broadly applicable to all teams. Anything that is team specific should not be submitted.
|
||||
- As a rule, we are happy with the general structure of WPILib. We are not interested in major rewrites of all of WPILib. We are open to talking about ideas, but backwards compatibility is very important for WPILib, so be sure to keep this in mind when proposing major changes.
|
||||
- Generally speaking, we do not accept code for specific sensors. We have to be able to test the sensor in hardware on the WPILib test bed. Additionally, hardware availability for teams is important. Therefore, as a general rule, the library only directly supports hardware that is in the Kit of Parts. If you are a company interested in getting a sensor into the Kit of Parts, please contact FIRST directly at frcparts@firstinspires.org.
|
||||
|
||||
## Coding Guidelines
|
||||
|
||||
WPILib uses modified Google style guides for both C++ and Java, which can be found in the [styleguide repository](https://github.com/wpilibsuite/styleguide). Autoformatters are available for many popular editors at https://github.com/google/styleguide. Running wpiformat is required for all contributions and is enforced by our continuous integration system.
|
||||
|
||||
While the library should be fully formatted according to the styles, additional elements of the style guide were not followed when the library was initially created. All new code should follow the guidelines. If you are looking for some easy ramp-up tasks, finding areas that don't follow the style guide and fixing them is very welcome.
|
||||
|
||||
## Submitting Changes
|
||||
|
||||
### Pull Request Format
|
||||
|
||||
Changes should be submitted as a Pull Request against the master branch of WPILib. For most changes, we ask that you squash your changes down to a single commit. For particularly large changes, multiple commits are ok, but assume one commit unless asked otherwise. No change will be merged unless it is up to date with the current master. We will also not merge any changes with merge commits in them; please rebase off of master before submitting a pull request. We do this to make sure that the git history isn't too cluttered.
|
||||
|
||||
### Merge Process
|
||||
|
||||
When you first submit changes, Travis-CI will attempt to run `./gradlew check` on your change. If this fails, you will need to fix any issues that it sees. Once Travis passes, we will begin the review process in more earnest. One or more WPILib team members will review your change. This will be a back-and-forth process with the WPILib team and the greater community. Once we are satisfied that your change is ready, we will allow our Jenkins instance to test it. This will run the full gamut of checks, including integration tests on actual hardware. Once all tests have passed and the team is satisfied, we will merge your change into the WPILib repository.
|
||||
|
||||
## Licensing
|
||||
|
||||
By contributing to WPILib, you agree that your code will be distributed with WPILib, and licensed under the license for the WPILib project. You should not contribute code that you do not have permission to relicense in this manner. This includes code that is licensed under the GPL that you do not have permission to relicense, as WPILib is not released under a copyleft license. Our license is the 3-clause BSD license, which you can find [here](license.txt).
|
||||
24
LICENSE.txt
Normal file
24
LICENSE.txt
Normal file
@@ -0,0 +1,24 @@
|
||||
Copyright (c) 2009-2017 FIRST
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the FIRST nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY FIRST AND CONTRIBUTORS``AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY NONINFRINGEMENT AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL FIRST OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
71
README.md
71
README.md
@@ -1,36 +1,70 @@
|
||||
# WPILib Project
|
||||
|
||||
[](https://travis-ci.org/wpilibsuite/allwpilib)
|
||||
|
||||
Welcome to the WPILib project. This repository contains the HAL, WPILibJ, and WPILibC projects. These are the core libraries for creating robot programs for the roboRIO.
|
||||
|
||||
- [WPILib Mission](#wpilib-mission)
|
||||
- [Building WPILib](#building-wpilib)
|
||||
- [Requirements](#requirements)
|
||||
- [Setup](#setup)
|
||||
- [Building](#building)
|
||||
- [Publishing](#publishing)
|
||||
- [Structure and Organization](#structure-and-organization)
|
||||
- [Contributing to WPILib](#contributing-to-wpilib)
|
||||
|
||||
## WPILib Mission
|
||||
|
||||
The WPILib Mission is to enable FIRST Robotics teams to focus on writing game-specific software rather than focussing on hardware details - "raise the floor, don't lower the ceiling". We work to enable teams with limited programming knowledge and/or mentor experience to be as successful as possible, while not hampering the abilities of teams with more advanced programming capabilities. We support Kit of Parts control system components directly in the library. We also strive to keep parity between major features of each language (Java, C++, and NI's LabVIEW), so that teams aren't at a disadvantage for choosing a specific programming language. WPILib is an open source project, licensed under the BSD 3-clause license. You can find a copy of the license [here](license.txt).
|
||||
|
||||
# Building WPILib
|
||||
|
||||
Building WPILib is very straightforward. WPILib uses Gradle to compile. It only has a few dependencies on outside tools, including the ARM cross compiler.
|
||||
Using Gradle makes building WPILib very straightforward. It only has a few dependencies on outside tools, such as the ARM cross compiler for creating roboRIO binaries.
|
||||
|
||||
## Requirements
|
||||
|
||||
- A C++ compiler
|
||||
- On Linux, gcc works fine
|
||||
- On Windows, you need Visual Studio 2015 (the free community edition works fine).
|
||||
Make sure to select the C++ Programming Language for installation
|
||||
- [ARM Compiler Toolchain](http://first.wpi.edu/FRC/roborio/toolchains/)
|
||||
* Note that for 2017-2018 and beyond, you will need version 5 or greater of gcc
|
||||
- Doxygen (Only required if you want to build the C++ documentation)
|
||||
|
||||
## Setup
|
||||
Clone the WPILib Repo. If the toolchains are not installed, install them, and make sure they are available on the system PATH.
|
||||
|
||||
Clone the WPILib repository. If the toolchains are not installed, install them, and make sure they are available on the system PATH.
|
||||
|
||||
See the [styleguide README](https://github.com/wpilibsuite/styleguide/blob/master/README.md) for wpiformat setup instructions.
|
||||
|
||||
## Building
|
||||
All build steps are executed using the Gradle wrapper, `gradlew`. Each target that Gradle can build is referred to as a task. The most common Gradle task to use is `build`. This will build all of the outputs created by WPILib. To run, open a console and cd into the cloned WPILib directory. Then:
|
||||
|
||||
All build steps are executed using the Gradle wrapper, `gradlew`. Each target that Gradle can build is referred to as a task. The most common Gradle task to use is `build`. This will build all the outputs created by WPILib. To run, open a console and cd into the cloned WPILib directory. Then:
|
||||
|
||||
```bash
|
||||
./gradlew build
|
||||
```
|
||||
|
||||
To build a specific subproject, such as wpilibc, you must access the subproject and run the build task only on that project. Accessing a subproject in Gradle is quite easy. Simply use `:subproject_name:task_name` with the Gradle wrapper. For example, building just wpilibc:
|
||||
To build a specific subproject, such as WPILibC, you must access the subproject and run the build task only on that project. Accessing a subproject in Gradle is quite easy. Simply use `:subproject_name:task_name` with the Gradle wrapper. For example, building just WPILibC:
|
||||
|
||||
```bash
|
||||
./gradlew :wpilibc:build
|
||||
```
|
||||
|
||||
If you also want simulation to be build, add -PmakeSim. This requires gazebo_transport. We have tested on 14.04 and 15.05, but any correct install of gazebo should work, even on windows if you build from source. Correct means cmake needs to be able to find gazebo-config.cmake, which you get for free with ubuntu installs.
|
||||
If you have installed the FRC Toolchain to a directory other than the default, or if the Toolchain location is not on your System PATH, you can pass the `toolChainPath` property to specify where it is located. Example:
|
||||
|
||||
```bash
|
||||
./gradlew build -PtoolChainPath=some/path/to/frc/toolchain/bin
|
||||
```
|
||||
|
||||
If you also want simulation to be built, add -PmakeSim. This requires gazebo_transport. We have tested on 14.04 and 15.05, but any correct install of Gazebo should work, even on Windows if you build Gazebo from source. Correct means CMake needs to be able to find gazebo-config.cmake. See [The Gazebo website](https://gazebosim.org/) for installation instructions.
|
||||
|
||||
```bash
|
||||
./gradlew build -PmakeSim
|
||||
```
|
||||
|
||||
C++ simulation tasks (including plugins, gz_msgs, and wpilibcSim) all depend on gazebo_transport. In order for this to build you must have installed gazebo. See [The Gazebo website](https://gazebosim.org/) for installation instructions.
|
||||
If you prefer to use CMake directly, the you can still do so.
|
||||
The common cmake tasks are wpilibcSim, frc_gazebo_plugins, and gz_msgs
|
||||
The common CMake tasks are wpilibcSim, frc_gazebo_plugins, and gz_msgs
|
||||
|
||||
```bash
|
||||
mkdir build #run this in the root of allwpilib
|
||||
@@ -39,13 +73,15 @@ cmake ..
|
||||
make
|
||||
```
|
||||
|
||||
|
||||
The gradlew wrapper only exists in the root of the main project, so be sure to run all commands from there. All of the subprojects have build tasks that can be run. Gradle automatically determines and rebuilds dependencies, so if you make a change to the HAL and then run `:wpilibc:build`, the HAL will be rebuilt, then wpilibc.
|
||||
The gradlew wrapper only exists in the root of the main project, so be sure to run all commands from there. All of the subprojects have build tasks that can be run. Gradle automatically determines and rebuilds dependencies, so if you make a change in the HAL and then run `./gradlew :wpilibc:build`, the HAL will be rebuilt, then WPILibC.
|
||||
|
||||
There are a few tasks other than `build` available. To see them, run the meta-task `tasks`. This will print a list of all available tasks, with a description of each task.
|
||||
|
||||
wpiformat can be executed anywhere in the repository via `py -3 -m wpiformat` on Windows or `python3 -m wpiformat` on other platforms.
|
||||
|
||||
## Publishing
|
||||
If you are building to test with the eclipse plugins or just want to export the build as a Maven-style dependency, simply run the `publish` task. This task will publish all available packages to ~/releases/maven/development. If you need to publish the project to a different repo, you can specify it with `-Prepo=repo_name`. Valid options are:
|
||||
|
||||
If you are building to test with the Eclipse plugins or just want to export the build as a Maven-style dependency, simply run the `publish` task. This task will publish all available packages to ~/releases/maven/development. If you need to publish the project to a different repo, you can specify it with `-Prepo=repo_name`. Valid options are:
|
||||
|
||||
- development - The default repo.
|
||||
- beta - Publishes to ~/releases/maven/beta.
|
||||
@@ -54,20 +90,25 @@ If you are building to test with the eclipse plugins or just want to export the
|
||||
|
||||
The following maven targets a published by this task:
|
||||
|
||||
- edu.wpi.first.wpilib.cmake:cpp-root:1.0.0 - RoboRIO C++
|
||||
- edu.wpi.first.wpilib.cmake:cpp-root:1.0.0 - roboRIO C++
|
||||
- edu.wpi.first.wpilibc.simulation:WPILibCSim:0.1.0 - Simulation C++
|
||||
- edu.wpi.first.wpilibj:wpilibJavaFinal:0.1.0-SNAPSHOT - RoboRIO Java
|
||||
- edu.wpi.first.wpilibj:wpilibJavaFinal:0.1.0-SNAPSHOT - roboRIO Java
|
||||
- edu.wpi.first.wpilibj:wpilibJavaSim:0.1.0-SNAPSHOT - Simulation Java
|
||||
- edu.wpi.first.wpilibj.simulation:SimDS:0.1.0-SNAPSHOT - The driverstation for controlling simulation.
|
||||
- org.gazebosim:JavaGazebo:0.1.0-SNAPSHOT - Gazebo protocol for Java.
|
||||
|
||||
## Structure and Organization
|
||||
The main wpilib code you're probably looking for is in wpilibj and wpilibc. Those directories are split into shared, sim, and athena. Athena contains the wpilib code meant to run on your RoboRIO. Sim is wpilib code meant to run on your computer with gazebo, and shared is code shared between the two. Shared code must be platform-independent, since it will be compiled with both the ARM cross-compiler and whatever desktop compiler you are using (g++, msvc, etc...).
|
||||
|
||||
The main WPILib code you're probably looking for is in WPILibJ and WPILibC. Those directories are split into shared, sim, and athena. Athena contains the WPILib code meant to run on your roboRIO. Sim is WPILib code meant to run on your computer with Gazebo, and shared is code shared between the two. Shared code must be platform-independent, since it will be compiled with both the ARM cross-compiler and whatever desktop compiler you are using (g++, msvc, etc...).
|
||||
|
||||
The Simulation directory contains extra simulation tools and libraries, such as gz_msgs and JavaGazebo. See sub-directories for more information.
|
||||
|
||||
The integration test directories for C++ and Java contain test code that runs on our test-system. When you submit code for review, it is tested by those programs. If you add new functionality you should make sure to write tests for it so we don't break it in the future.
|
||||
|
||||
The hal directory contains more C++ code meant to run on the RoboRIO. HAL is an acronym for "Hardware Abstraction Layer", and it interfaces with the NI Libraries. The NI Libraries contain the low-level code for controlling devices on your robot. The NI Libraries are found in the ni-libraries folder.
|
||||
The hal directory contains more C++ code meant to run on the roboRIO. HAL is an acronym for "Hardware Abstraction Layer", and it interfaces with the NI Libraries. The NI Libraries contain the low-level code for controlling devices on your robot. The NI Libraries are found in the ni-libraries folder.
|
||||
|
||||
The styleguide directory contains the styleguide for C++ and Java code. Anything submitted to the wpilib project needs to follow the code style guides outlined in there.
|
||||
The [styleguide repository](https://github.com/wpilibsuite/styleguide) contains our style guides for C++ and Java code. Anything submitted to the WPILib project needs to follow the code style guides outlined in there. For details about the style, please see the contributors document [here](CONTRIBUTING.md#coding-guidelines).
|
||||
|
||||
# Contributing to WPILib
|
||||
|
||||
See [CONTRIBUTING.md](CONTRIBUTING.md).
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
INCLUDE(CMakeForceCompiler)
|
||||
set(ARM_PREFIX arm-frc-linux-gnueabi)
|
||||
set(CMAKE_SYSTEM_NAME Linux)
|
||||
CMAKE_FORCE_CXX_COMPILER(${ARM_PREFIX}-g++ GNU)
|
||||
CMAKE_FORCE_C_COMPILER(${ARM_PREFIX}-gcc GNU)
|
||||
set(CMAKE_CXX_FLAGS "-std=c++1y -Wformat=2 -Wall -Wextra -Werror -pedantic -Wno-psabi" CACHE STRING "" FORCE)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g3" CACHE STRING "" FORCE)
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -g" CACHE STRING "" FORCE) # still want debugging for release?
|
||||
201
build.gradle
201
build.gradle
@@ -1,34 +1,188 @@
|
||||
def enableSimulation = hasProperty('enableSimulation')
|
||||
|
||||
if (!hasProperty('repo')) {
|
||||
ext.repo = 'development'
|
||||
}
|
||||
|
||||
def repoBaseUrl = "http://first.wpi.edu/FRC/roborio/maven/${repo}"
|
||||
def publishUrl = "${System.getProperty('user.home')}/releases/maven/${repo}"
|
||||
|
||||
ext.simulationInstallDir = "$rootDir/build/install/simulation"
|
||||
|
||||
allprojects {
|
||||
ext.enableSimulation = enableSimulation
|
||||
ext.repo = repo
|
||||
import edu.wpi.first.nativeutils.NativeUtils
|
||||
import edu.wpi.first.nativeutils.tasks.JNIHeaders
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
mavenLocal()
|
||||
maven {
|
||||
url publishUrl
|
||||
}
|
||||
maven {
|
||||
url repoBaseUrl
|
||||
url "https://plugins.gradle.org/m2/"
|
||||
}
|
||||
}
|
||||
dependencies {
|
||||
classpath 'gradle.plugin.edu.wpi.first:native-utils:1.5.1'
|
||||
}
|
||||
}
|
||||
|
||||
plugins {
|
||||
id 'net.ltgt.errorprone' version '0.0.10'
|
||||
id 'edu.wpi.first.wpilib.versioning.WPILibVersioningPlugin' version '2.0'
|
||||
id 'idea'
|
||||
}
|
||||
|
||||
ext.licenseFile = file("$rootDir/LICENSE.txt")
|
||||
|
||||
ext.getJNIHeadersClass = {
|
||||
return JNIHeaders
|
||||
}
|
||||
|
||||
ext.getClassifier = { binary->
|
||||
return NativeUtils.getClassifier(binary)
|
||||
}
|
||||
|
||||
ext.getPlatformPath = { binary->
|
||||
return NativeUtils.getPlatformPath(binary)
|
||||
}
|
||||
|
||||
ext.createComponentZipTasks = { components, name, base, type, project, func ->
|
||||
def configMap = [:]
|
||||
components.each {
|
||||
if (it in NativeLibrarySpec && it.name == name) {
|
||||
it.binaries.each {
|
||||
def target = getClassifier(it)
|
||||
if (configMap.containsKey(target)) {
|
||||
configMap.get(target).add(it)
|
||||
} else {
|
||||
configMap.put(target, [])
|
||||
configMap.get(target).add(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
def taskList = []
|
||||
def outputsFolder = file("$project.buildDir/outputs")
|
||||
def baseN = base + name
|
||||
configMap.each { key, value ->
|
||||
def task = project.tasks.create(baseN + "-${key}", type) {
|
||||
description = 'Creates component archive for platform ' + key
|
||||
destinationDir = outputsFolder
|
||||
classifier = key
|
||||
baseName = baseN + '-classifier'
|
||||
duplicatesStrategy = 'exclude'
|
||||
|
||||
from(licenseFile) {
|
||||
into '/'
|
||||
}
|
||||
|
||||
func(it, value)
|
||||
}
|
||||
taskList.add(task)
|
||||
|
||||
project.build.dependsOn task
|
||||
|
||||
project.artifacts {
|
||||
task
|
||||
}
|
||||
}
|
||||
return taskList
|
||||
}
|
||||
|
||||
ext.createAllCombined = { list, name, base, type, project ->
|
||||
def outputsFolder = file("$project.buildDir/outputs")
|
||||
def baseN = base + name
|
||||
def task = project.tasks.create(baseN + '-all', type) {
|
||||
description = 'Creates component archive for all classifiers'
|
||||
destinationDir = outputsFolder
|
||||
classifier = 'all'
|
||||
baseName = baseN + '-classifier'
|
||||
duplicatesStrategy = 'exclude'
|
||||
|
||||
list.each {
|
||||
it.outputs.files.each {
|
||||
from project.zipTree(it)
|
||||
}
|
||||
dependsOn it
|
||||
}
|
||||
}
|
||||
|
||||
project.build.dependsOn task
|
||||
|
||||
project.artifacts {
|
||||
task
|
||||
}
|
||||
|
||||
return task
|
||||
|
||||
}
|
||||
|
||||
ext.includeStandardZipFormat = { task, value ->
|
||||
value.each { binary->
|
||||
if (binary.buildable) {
|
||||
if (binary instanceof SharedLibraryBinarySpec) {
|
||||
task.dependsOn binary.buildTask
|
||||
task.from(new File(binary.sharedLibraryFile.absolutePath + ".debug")) {
|
||||
into getPlatformPath(binary) + '/shared'
|
||||
}
|
||||
task.from (binary.sharedLibraryFile) {
|
||||
into getPlatformPath(binary) + '/shared'
|
||||
}
|
||||
task.from (binary.sharedLibraryLinkFile) {
|
||||
into getPlatformPath(binary) + '/shared'
|
||||
}
|
||||
} else if (binary instanceof StaticLibraryBinarySpec) {
|
||||
task.dependsOn binary.buildTask
|
||||
task.from (binary.staticLibraryFile) {
|
||||
into getPlatformPath(binary) + '/static'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that the WPILibVersioningPlugin is setup by setting the release type, if releaseType wasn't
|
||||
// already specified on the command line
|
||||
if (!hasProperty('releaseType')) {
|
||||
WPILibVersion {
|
||||
releaseType = 'dev'
|
||||
}
|
||||
}
|
||||
|
||||
def pubVersion
|
||||
if (project.hasProperty("publishVersion")) {
|
||||
pubVersion = project.publishVersion
|
||||
} else {
|
||||
pubVersion = WPILibVersion.version
|
||||
}
|
||||
|
||||
def outputsFolder = file("$buildDir/outputs")
|
||||
|
||||
def versionFile = file("$outputsFolder/version.txt")
|
||||
|
||||
task outputVersions() {
|
||||
description = 'Prints the versions of wpilib to a file for use by the downstream packaging project'
|
||||
group = 'Build'
|
||||
outputs.files(versionFile)
|
||||
|
||||
doFirst {
|
||||
buildDir.mkdir()
|
||||
outputsFolder.mkdir()
|
||||
}
|
||||
|
||||
doLast {
|
||||
versionFile.write pubVersion
|
||||
}
|
||||
}
|
||||
|
||||
task build() {}
|
||||
|
||||
build.dependsOn outputVersions
|
||||
|
||||
task clean(type: Delete) {
|
||||
delete buildDir
|
||||
}
|
||||
|
||||
subprojects {
|
||||
apply plugin: 'eclipse'
|
||||
apply plugin: 'idea'
|
||||
apply plugin: 'checkstyle'
|
||||
|
||||
ext.armBuild = true
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
checkstyle {
|
||||
toolVersion = "8.1"
|
||||
configFile = new File(rootDir, "styleguide/checkstyle.xml")
|
||||
}
|
||||
|
||||
// Disables doclint in java 8.
|
||||
if (JavaVersion.current().isJava8Compatible()) {
|
||||
@@ -36,12 +190,13 @@ subprojects {
|
||||
options.addStringOption('Xdoclint:none', '-quiet')
|
||||
}
|
||||
}
|
||||
|
||||
ext.setupWpilibRepo = { publishing ->
|
||||
publishing.repositories.maven {
|
||||
url = "${System.getProperty('user.home')}/releases/maven/${repo}"
|
||||
url = WPILibVersion.mavenLocalUrl
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
apply from: 'cppSettings.gradle'
|
||||
task wrapper(type: Wrapper) {
|
||||
gradleVersion = '4.1'
|
||||
}
|
||||
|
||||
235
config.gradle
Normal file
235
config.gradle
Normal file
@@ -0,0 +1,235 @@
|
||||
import edu.wpi.first.nativeutils.*
|
||||
import org.gradle.internal.os.OperatingSystem
|
||||
|
||||
def windowsCompilerArgs = ['/EHsc', '/DNOMINMAX', '/Zi', '/FS', '/Zc:inline', '/MT']
|
||||
def windowsReleaseCompilerArgs = ['/O2']
|
||||
def windowsLinkerArgs = [ '/DEBUG:FULL' ]
|
||||
def windowsReleaseLinkerArgs = [ '/OPT:REF', '/OPT:ICF' ]
|
||||
|
||||
def linuxCompilerArgs = ['-std=c++11', '-Wformat=2', '-Wall', '-Wextra', '-Werror', '-pedantic', '-Wno-psabi', '-g',
|
||||
'-Wno-unused-parameter', '-fPIC', '-rdynamic', '-Wno-error=deprecated-declarations', '-pthread']
|
||||
def linuxLinkerArgs = ['-rdynamic', '-pthread']
|
||||
def linuxReleaseCompilerArgs = ['-Og']
|
||||
def linuxDebugCompilerArgs = ['-O0']
|
||||
def linux32BitArg = '-m32'
|
||||
|
||||
def macCompilerArgs = ['-std=c++11', '-Wall', '-Wextra', '-Werror', '-pedantic-errors', '-fPIC', '-g',
|
||||
'-Wno-unused-parameter', '-Wno-missing-field-initializers', '-Wno-unused-private-field',
|
||||
'-Wno-unused-const-variable', '-pthread']
|
||||
def macReleaseCompilerArgs = ['-O2']
|
||||
def macDebugCompilerArgs = ['-O0']
|
||||
def mac32BitArg = '-m32'
|
||||
|
||||
def buildAll = project.hasProperty('buildAll')
|
||||
|
||||
def windows64PlatformDetect = {
|
||||
def arch = System.getProperty("os.arch")
|
||||
def isWin = OperatingSystem.current().isWindows()
|
||||
if (buildAll) {
|
||||
return isWin
|
||||
} else {
|
||||
return isWin && arch == 'amd64'
|
||||
}
|
||||
}
|
||||
|
||||
def windows32PlatformDetect = {
|
||||
def arch = System.getProperty("os.arch")
|
||||
def isWin = OperatingSystem.current().isWindows()
|
||||
if (buildAll) {
|
||||
return isWin
|
||||
} else {
|
||||
return isWin && arch == 'x86'
|
||||
}
|
||||
}
|
||||
|
||||
def linux32IntelPlatformDetect = {
|
||||
def arch = System.getProperty("os.arch")
|
||||
def isLinux = OperatingSystem.current().isLinux()
|
||||
def isIntel = (arch == 'amd64' || arch == 'i386')
|
||||
if (buildAll) {
|
||||
return isLinux && isIntel
|
||||
} else {
|
||||
return isLinux && arch == 'i386'
|
||||
}
|
||||
}
|
||||
|
||||
def linux64IntelPlatformDetect = {
|
||||
def arch = System.getProperty("os.arch")
|
||||
def isLinux = OperatingSystem.current().isLinux()
|
||||
def isIntel = (arch == 'amd64' || arch == 'i386')
|
||||
if (buildAll) {
|
||||
return isLinux && isIntel
|
||||
} else {
|
||||
return isLinux && arch == 'amd64'
|
||||
}
|
||||
}
|
||||
|
||||
def linuxArmPlatformDetect = {
|
||||
def arch = System.getProperty("os.arch")
|
||||
def isIntel = (arch == 'amd64' || arch == 'i386')
|
||||
return OperatingSystem.current().isLinux() && !isIntel
|
||||
}
|
||||
|
||||
def mac64PlatformDetect = {
|
||||
def arch = System.getProperty("os.arch")
|
||||
def isMac = OperatingSystem.current().isMacOsX()
|
||||
if (buildAll) {
|
||||
return isMac
|
||||
} else {
|
||||
return isMac && arch == 'x86_64'
|
||||
}
|
||||
}
|
||||
|
||||
def mac32PlatformDetect = {
|
||||
def arch = System.getProperty("os.arch")
|
||||
def isMac = OperatingSystem.current().isMacOsX()
|
||||
if (buildAll) {
|
||||
return isMac
|
||||
} else {
|
||||
return isMac && arch == 'x86'
|
||||
}
|
||||
}
|
||||
|
||||
if (!project.hasProperty('skipAthena')) {
|
||||
model {
|
||||
buildConfigs {
|
||||
roboRio(CrossBuildConfig) {
|
||||
architecture = 'athena'
|
||||
operatingSystem = 'linux'
|
||||
toolChainPrefix = 'arm-frc-linux-gnueabi-'
|
||||
compilerArgs = linuxCompilerArgs
|
||||
linkerArgs = linuxLinkerArgs
|
||||
debugCompilerArgs = linuxDebugCompilerArgs
|
||||
releaseCompilerArgs = linuxReleaseCompilerArgs
|
||||
releaseStripBinaries = true
|
||||
compilerFamily = 'Gcc'
|
||||
exclude << 'halSim'
|
||||
exclude << 'halSimStaticDeps'
|
||||
exclude << 'halSimTestingBase'
|
||||
exclude << 'wpilibcTestingBase'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!project.hasProperty('onlyAthena')) {
|
||||
model {
|
||||
buildConfigs {
|
||||
winX86(BuildConfig) {
|
||||
architecture = 'x86'
|
||||
operatingSystem = 'windows'
|
||||
compilerArgs = windowsCompilerArgs
|
||||
linkerArgs = windowsLinkerArgs
|
||||
releaseCompilerArgs = windowsReleaseCompilerArgs
|
||||
releaseLinkerArgs = windowsReleaseLinkerArgs
|
||||
compilerFamily = 'VisualCpp'
|
||||
detectPlatform = windows32PlatformDetect
|
||||
exclude << 'halAthena'
|
||||
}
|
||||
winX64(BuildConfig) {
|
||||
architecture = 'x86-64'
|
||||
operatingSystem = 'windows'
|
||||
compilerArgs = windowsCompilerArgs
|
||||
linkerArgs = windowsLinkerArgs
|
||||
releaseCompilerArgs = windowsReleaseCompilerArgs
|
||||
releaseLinkerArgs = windowsReleaseLinkerArgs
|
||||
compilerFamily = 'VisualCpp'
|
||||
detectPlatform = windows64PlatformDetect
|
||||
exclude << 'halAthena'
|
||||
}
|
||||
/* Disable 32 bit linux until we can figure out jenkins
|
||||
linuxX86(BuildConfig) {
|
||||
architecture = 'x86'
|
||||
operatingSystem = 'linux'
|
||||
compilerArgs = linuxCompilerArgs
|
||||
compilerArgs << linux32BitArg
|
||||
linkerArgs = linuxLinkerArgs
|
||||
linkerArgs << linux32BitArg
|
||||
debugCompilerArgs = linuxDebugCompilerArgs
|
||||
releaseCompilerArgs = linuxReleaseCompilerArgs
|
||||
releaseStripBinaries = true
|
||||
compilerFamily = 'Gcc'
|
||||
detectPlatform = linux32IntelPlatformDetect
|
||||
exclude << 'halAthena'
|
||||
}
|
||||
*/
|
||||
linuxX64(BuildConfig) {
|
||||
architecture = 'x86-64'
|
||||
operatingSystem = 'linux'
|
||||
compilerArgs = linuxCompilerArgs
|
||||
linkerArgs = linuxLinkerArgs
|
||||
debugCompilerArgs = linuxDebugCompilerArgs
|
||||
releaseCompilerArgs = linuxReleaseCompilerArgs
|
||||
releaseStripBinaries = true
|
||||
compilerFamily = 'Gcc'
|
||||
detectPlatform = linux64IntelPlatformDetect
|
||||
exclude << 'halAthena'
|
||||
}
|
||||
/* 32 bit Mac OS X not supported by OpenCV.
|
||||
* If support is ever added, will add this back in
|
||||
macX86(BuildConfig) {
|
||||
architecture = 'x86'
|
||||
operatingSystem = 'osx'
|
||||
compilerArgs = macCompilerArgs
|
||||
compilerArgs << mac32BitArg
|
||||
linkerArgs << mac32BitArg
|
||||
debugCompilerArgs = macDebugCompilerArgs
|
||||
releaseCompilerArgs = macReleaseCompilerArgs
|
||||
releaseStripBinaries = true
|
||||
compilerFamily = 'Clang'
|
||||
detectPlatform = mac32PlatformDetect
|
||||
exclude << 'halAthena'
|
||||
}
|
||||
*/
|
||||
macX64(BuildConfig) {
|
||||
architecture = 'x86-64'
|
||||
operatingSystem = 'osx'
|
||||
compilerArgs = macCompilerArgs
|
||||
debugCompilerArgs = macDebugCompilerArgs
|
||||
releaseCompilerArgs = macReleaseCompilerArgs
|
||||
releaseStripBinaries = true
|
||||
compilerFamily = 'Clang'
|
||||
detectPlatform = mac64PlatformDetect
|
||||
exclude << 'halAthena'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (project.hasProperty('linuxCross')) {
|
||||
model {
|
||||
buildConfigs {
|
||||
linuxArm(CrossBuildConfig) {
|
||||
architecture = 'nativearm'
|
||||
operatingSystem = 'linux'
|
||||
toolChainPrefix = 'PLEASE_PROVIDE_A_COMPILER_NAME'
|
||||
compilerArgs = linuxCompilerArgs
|
||||
linkerArgs = linuxLinkerArgs
|
||||
debugCompilerArgs = linuxDebugCompilerArgs
|
||||
releaseCompilerArgs = linuxReleaseCompilerArgs
|
||||
releaseStripBinaries = true
|
||||
skipByDefault = true
|
||||
compilerFamily = 'Gcc'
|
||||
exclude << 'gmock'
|
||||
exclude << 'halAthena'
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
model {
|
||||
buildConfigs {
|
||||
linuxArm(BuildConfig) {
|
||||
architecture = 'nativearm'
|
||||
operatingSystem = 'linux'
|
||||
compilerArgs = linuxCompilerArgs
|
||||
linkerArgs = linuxLinkerArgs
|
||||
debugCompilerArgs = linuxDebugCompilerArgs
|
||||
releaseCompilerArgs = linuxReleaseCompilerArgs
|
||||
releaseStripBinaries = true
|
||||
compilerFamily = 'Gcc'
|
||||
detectPlatform = linuxArmPlatformDetect
|
||||
exclude << 'halAthena'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
:: This file is a helper for allC++Sim
|
||||
::
|
||||
:: Usage: cd /build && ../configure
|
||||
::
|
||||
:: WARNING -- this is only temporary, and only meant for debug, and only works on my computer
|
||||
@set WS=C:\Users\peter\gz-ws
|
||||
@set BOOST_PATH=%WS%\boost_1_56_0
|
||||
@set BOOST_LIBRARY_DIR=%BOOST_PATH%\lib64-msvc-12.0
|
||||
|
||||
@set PROTOBUF_PATH=%WS%\protobuf-2.6.0-win64-vc12
|
||||
|
||||
@set OGRE_PATH=%WS%\ogre_src_v1-8-1-vc12-x64-release-debug\build\install\Debug
|
||||
@set OGRE_INCLUDE_DIR=%OGRE_PATH%\include;%OGRE_PATH%\include\OGRE;%OGRE_PATH%\include\OGRE\RTShaderSystem;%OGRE_PATH%\include\OGRE\Terrain;%OGRE_PATH%\include\OGRE\Paging
|
||||
@set OGRE_LIBRARY_DIR=%OGRE_PATH%\lib\Debug
|
||||
set OGRE_LIB_SUFFIX=_d.lib
|
||||
@set OGRE_LIBS=%OGRE_LIBRARY_DIR%\OgreMain%OGRE_LIB_SUFFIX%;%OGRE_LIBRARY_DIR%\OgreOverlay%OGRE_LIB_SUFFIX%;%OGRE_LIBRARY_DIR%\OgreRTShaderSystem%OGRE_LIB_SUFFIX%;%OGRE_LIBRARY_DIR%\OgreTerrain%OGRE_LIB_SUFFIX%;%OGRE_LIBRARY_DIR%\OgrePaging%OGRE_LIB_SUFFIX%
|
||||
@set OGRE_LIBS=%OGRE_LIBRARY_DIR%\OgreMain%OGRE_LIB_SUFFIX%;%OGRE_LIBRARY_DIR%\OgreRTShaderSystem%OGRE_LIB_SUFFIX%;%OGRE_LIBRARY_DIR%\OgreTerrain%OGRE_LIB_SUFFIX%;%OGRE_LIBRARY_DIR%\OgrePaging%OGRE_LIB_SUFFIX%
|
||||
|
||||
@set FREEIMAGE_PATH=%WS%\FreeImage-vc12-x64-release-debug
|
||||
@set FREEIMAGE_INCLUDE_DIR=%FREEIMAGE_PATH%\Source
|
||||
|
||||
@set TBB_PATH=%WS%\tbb43_20141023oss
|
||||
@set TBB_INCLUDEDIR=%TBB_PATH%\include
|
||||
|
||||
@set DLFCN_WIN32_PATH=%WS%\dlfcn-win32-vc12-x64-release-debug\build\install\Debug
|
||||
@set DLFCN_WIN32_INCLUDE_DIR=%DLFCN_WIN32_PATH%\include
|
||||
|
||||
@set TINY_XML_INCLUDE_DIR=%WS%\sdformat\src\win\tinyxml
|
||||
|
||||
@set GAZEBO_PATH=%WS%\gazebo\build\install\Debug\lib\cmake\gazebo
|
||||
@set SDFORMAT_PATH=%WS%\sdformat\build\install\Debug\lib\cmake\sdformat
|
||||
@set IGNITION-MATH_PATH=%WS%\ign-math\build\install\Debug\lib\cmake\ignition-math2
|
||||
|
||||
@set INCLUDE=%TINY_XML_INCLUDE_DIR%;%FREEIMAGE_INCLUDE_DIR%;%TBB_INCLUDEDIR%;%DLFCN_WIN32_INCLUDE_DIR%;%INCLUDE%
|
||||
@set LIB=%LIB%
|
||||
|
||||
cmake -G "NMake Makefiles"^
|
||||
-DCMAKE_INSTALL_PREFIX=build^
|
||||
-DCMAKE_PREFIX_PATH="%GAZEBO_PATH%;%SDFORMAT_PATH%;%IGNITION-MATH_PATH%"^
|
||||
-DOGRE_FOUND=1^
|
||||
-DOGRE_INCLUDE_DIRS="%OGRE_INCLUDE_DIR%"^
|
||||
-DOGRE_LIBRARIES="%OGRE_LIBS%"^
|
||||
-DPROTOBUF_SRC_ROOT_FOLDER="%PROTOBUF_PATH%"^
|
||||
-DBOOST_ROOT="%BOOST_PATH%"^
|
||||
-DBOOST_LIBRARYDIR="%BOOST_LIBRARY_DIR%"^
|
||||
..
|
||||
@@ -1,194 +0,0 @@
|
||||
// This regex matches either a Windows or Unix style file separator, then the lib part of the library,
|
||||
// then the name of the library itself, and finally the .so extension at the end. The name of the library
|
||||
// is in the libName capture group, which is extracted and used for the linker flags
|
||||
def libPattern = /.*((\\/|\\).*)+lib(?<libName>.+).so$/
|
||||
def niLibraryArgs = []
|
||||
def niLibraryPath = file('ni-libraries').path
|
||||
|
||||
// The NI Library tree includes all non-wpi libraries, which is everything that doesn't have libwpi in the name
|
||||
def niLibraryTree = fileTree(niLibraryPath)
|
||||
niLibraryTree.include '*.so'
|
||||
niLibraryTree.exclude '*wpi*.so'
|
||||
|
||||
// This adds all linker flags to the list of ni library linker flags
|
||||
niLibraryTree.each { lib ->
|
||||
def nameMatcher = (lib.path =~ libPattern)
|
||||
if (nameMatcher[0].size() > 1) {
|
||||
def name = nameMatcher.group('libName')
|
||||
niLibraryArgs << '-l' + name
|
||||
}
|
||||
}
|
||||
|
||||
def armNtDependency =
|
||||
project.dependencies.create("edu.wpi.first.wpilib.networktables.cpp:NetworkTables:3.0.0-SNAPSHOT:arm@zip")
|
||||
def armConfig = project.configurations.detachedConfiguration(armNtDependency)
|
||||
armConfig.setTransitive(false)
|
||||
def armNetTables = armConfig.files[0].canonicalFile
|
||||
|
||||
def desktopNetTables
|
||||
if (project.hasProperty('makeSim')){
|
||||
def desktopNtDependency =
|
||||
project.dependencies.create("edu.wpi.first.wpilib.networktables.cpp:NetworkTables:3.0.0-SNAPSHOT:desktop@zip")
|
||||
def desktopConfig = project.configurations.detachedConfiguration(desktopNtDependency)
|
||||
desktopConfig.setTransitive(false)
|
||||
desktopNetTables = desktopConfig.files[0].canonicalFile
|
||||
}
|
||||
|
||||
def netTablesUnzipLocation = "$buildDir/networktables"
|
||||
|
||||
// Create a task that will unzip the networktables files into a temporary build directory
|
||||
task unzipNetworkTables(type: Copy) {
|
||||
description = 'Unzips the networktables maven dependency so that the include files and libraries can be used'
|
||||
group = 'WPILib'
|
||||
if (project.hasProperty('makeSim')){
|
||||
from zipTree(desktopNetTables)
|
||||
}
|
||||
from zipTree(armNetTables)
|
||||
into netTablesUnzipLocation
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
description = "Deletes the build directory"
|
||||
group = "Build"
|
||||
delete buildDir
|
||||
}
|
||||
|
||||
subprojects {
|
||||
plugins.withType(CppPlugin).whenPluginAdded {
|
||||
// This defines a project property that projects depending on network tables can use to setup that dependency.
|
||||
ext.defineNetworkTablesProperties = {
|
||||
ext.netTables = netTablesUnzipLocation
|
||||
ext.netTablesInclude = "$netTablesUnzipLocation/include"
|
||||
ext.netLibArmLocation = "$netTablesUnzipLocation/Linux/arm"
|
||||
if (project.hasProperty('makeSim')){
|
||||
ext.netLibDesktopLocation = "$netTablesUnzipLocation/Linux/amd64"
|
||||
}
|
||||
ext.netSharedLib = "$netLibArmLocation/libntcore.so"
|
||||
ext.netStaticLib = "$netLibArmLocation/libntcore.a"
|
||||
|
||||
task addNetworkTablesLibraryLinks() {
|
||||
description = 'Adds the linker flags for the networktables libraries retreived from maven'
|
||||
group = 'WPILib'
|
||||
dependsOn project(':').unzipNetworkTables
|
||||
doLast {
|
||||
binaries.all {
|
||||
tasks.withType(CppCompile) {
|
||||
// desktop version doesn't use all the NI libraries
|
||||
// so only do this for arm libraries
|
||||
String architecture = targetPlatform.architecture
|
||||
if (architecture.contains('arm')){
|
||||
linker.args netStaticLib
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
model {
|
||||
buildTypes {
|
||||
debug
|
||||
}
|
||||
// Adds a custom toolchain for our compiler prefix and options
|
||||
toolChains {
|
||||
gcc(Gcc) {
|
||||
target('arm') {
|
||||
// We use a custom-built cross compiler with the prefix arm-frc-linux-gnueabi-<util name>
|
||||
// If this ever changes, the prefix will need to be changed here
|
||||
def compilerPrefix = 'arm-frc-linux-gnueabi-'
|
||||
cppCompiler.executable = compilerPrefix + cppCompiler.executable
|
||||
linker.executable = compilerPrefix + linker.executable
|
||||
assembler.executable = compilerPrefix + assembler.executable
|
||||
// Gradle auto-adds the -m32 argument to the linker and compiler. Our compiler only supports
|
||||
// arm, and doesn't understand this flag, so it is removed from both
|
||||
cppCompiler.withArguments { args ->
|
||||
args << '-std=c++1y' << '-Wformat=2' << '-Wall' << '-Wextra' << '-Werror' << '-pedantic'
|
||||
args << '-Wno-psabi' << '-Wno-unused-parameter' << '-fPIC' << '-O0' << '-g3' << '-rdynamic'
|
||||
//TODO: When the compiler allows us to actually call deprecated functions from within
|
||||
// deprecated function, remove this line (this will cause calling deprecated functions
|
||||
// to be treated as a warning rather than an error).
|
||||
args << '-Wno-error=deprecated-declarations'
|
||||
args.remove('-m32')
|
||||
}
|
||||
linker.withArguments { args ->
|
||||
args << '-rdynamic'
|
||||
args.remove('-m32')
|
||||
}
|
||||
staticLibArchiver.executable = compilerPrefix + staticLibArchiver.executable
|
||||
}
|
||||
}
|
||||
// Workaround for OS X. Macs for some reason want to use Xcode's gcc
|
||||
// (which just wraps Clang), so we have to explicitly make it so
|
||||
// that trying to compile with Clang will call gcc instead
|
||||
macGcc(Clang) {
|
||||
target('arm') {
|
||||
// We use a custom-built cross compiler with the prefix arm-frc-linux-gnueabi-<util name>
|
||||
// If this ever changes, the prefix will need to be changed here
|
||||
def compilerPrefix = 'arm-frc-linux-gnueabi-'
|
||||
cppCompiler.executable = compilerPrefix + 'g++'
|
||||
linker.executable = compilerPrefix + 'g++'
|
||||
assembler.executable = compilerPrefix + 'gcc'
|
||||
// Gradle auto-adds the -m32 argument to the linker and compiler. Our compiler only supports
|
||||
// arm, and doesn't understand this flag, so it is removed from both
|
||||
cppCompiler.withArguments { args ->
|
||||
args << '-std=c++1y' << '-Wformat=2' << '-Wall' << '-Wextra' << '-Werror' << '-pedantic'
|
||||
args << '-Wno-psabi' << '-Wno-unused-parameter' << '-fPIC' << '-O0' << '-g3' << '-rdynamic'
|
||||
//TODO: When the compiler allows us to actually call deprecated functions from within
|
||||
// deprecated function, remove this line (this will cause calling deprecated functions
|
||||
// to be treated as a warning rather than an error).
|
||||
args << '-Wno-error=deprecated-declarations'
|
||||
args.remove('-m32')
|
||||
}
|
||||
linker.withArguments { args ->
|
||||
args << '-rdynamic'
|
||||
args.remove('-m32')
|
||||
}
|
||||
staticLibArchiver.executable = compilerPrefix + 'ar'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The only platform is arm linux
|
||||
platforms {
|
||||
arm {
|
||||
architecture 'arm'
|
||||
operatingSystem 'linux'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This task adds the appropriate linker flags for the NI libraries
|
||||
task addNiLibraryLinks() {
|
||||
description = 'Adds the linker flags for the NI libraries in the ni-library folders'
|
||||
group = 'WPILib'
|
||||
doLast {
|
||||
binaries.all {
|
||||
tasks.withType(CppCompile) {
|
||||
// desktop version doesn't use all the NI libraries
|
||||
// so only do this for arm libraries
|
||||
String architecture = targetPlatform.architecture
|
||||
if (architecture.contains('arm')){
|
||||
linker.args << '-L' + niLibraryPath
|
||||
linker.args.addAll(niLibraryArgs)
|
||||
}
|
||||
}
|
||||
}
|
||||
model {
|
||||
repositories {
|
||||
libs(PrebuiltLibraries) { libs ->
|
||||
// Loops through all .so files (except files matching *libwpi*.so) in ../ni-libraries
|
||||
// and includes them for linking
|
||||
niLibraryTree.each { niLib ->
|
||||
libs.create(niLib) {
|
||||
binaries.withType(SharedLibraryBinary) {
|
||||
sharedLibraryFile = file(niLib.path)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
178
gen/wpilibj_frcnetcomm.py
Executable file
178
gen/wpilibj_frcnetcomm.py
Executable file
@@ -0,0 +1,178 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# This script generates the network communication interface for wpilibj.
|
||||
#
|
||||
# This script takes no arguments and should be invoked from either the gen
|
||||
# directory or the root directory of the project.
|
||||
|
||||
from datetime import date
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
|
||||
# Check that the current directory is part of a Git repository
|
||||
def inGitRepo(directory):
|
||||
ret = subprocess.run(["git", "rev-parse"], stderr = subprocess.DEVNULL)
|
||||
return ret.returncode == 0
|
||||
|
||||
def main():
|
||||
if not inGitRepo("."):
|
||||
print("Error: not invoked within a Git repository", file = sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
# Handle running in either the root or gen directories
|
||||
configPath = "."
|
||||
if os.getcwd().rpartition(os.sep)[2] == "gen":
|
||||
configPath = ".."
|
||||
|
||||
outputName = configPath + \
|
||||
"/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/FRCNetComm.java"
|
||||
|
||||
# Set initial copyright year and get current year
|
||||
year = "2016"
|
||||
currentYear = str(date.today().year)
|
||||
|
||||
# Start writing output file
|
||||
with open(outputName + ".tmp", "w") as temp:
|
||||
# Write first line of comment
|
||||
temp.write("/*")
|
||||
for i in range(0, 76):
|
||||
temp.write("-")
|
||||
temp.write("*/\n")
|
||||
|
||||
# Write second line of comment
|
||||
temp.write("/* Copyright (c) FIRST ")
|
||||
if year != currentYear:
|
||||
temp.write(year)
|
||||
temp.write("-")
|
||||
temp.write(currentYear)
|
||||
temp.write(". All Rights Reserved.")
|
||||
for i in range(0, 24):
|
||||
temp.write(" ")
|
||||
if year == currentYear:
|
||||
for i in range(0, 5):
|
||||
temp.write(" ")
|
||||
temp.write("*/\n")
|
||||
|
||||
# Write rest of lines of comment
|
||||
temp.write("""\
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*""")
|
||||
for i in range(0, 76):
|
||||
temp.write("-")
|
||||
temp.write("*/\n")
|
||||
|
||||
# Write preamble
|
||||
temp.write("""
|
||||
package edu.wpi.first.wpilibj.hal;
|
||||
|
||||
import edu.wpi.first.wpilibj.hal.JNIWrapper;
|
||||
|
||||
/**
|
||||
* JNI wrapper for library <b>FRC_NetworkCommunication</b><br>.
|
||||
*/
|
||||
@SuppressWarnings(\"MethodName\")
|
||||
public class FRCNetComm extends JNIWrapper {
|
||||
""")
|
||||
|
||||
# Read enums from C++ source files
|
||||
firstEnum = True
|
||||
for fileName in ["LoadOut.h", "UsageReporting.h"]:
|
||||
with open(configPath + "/hal/include/FRC_NetworkCommunication/" + \
|
||||
fileName, "r") as cppSource:
|
||||
while True:
|
||||
# Read until an enum is encountered
|
||||
line = ""
|
||||
pos = -1
|
||||
while line.find("enum") == -1:
|
||||
line = cppSource.readline()
|
||||
if line == "":
|
||||
break
|
||||
|
||||
if line == "":
|
||||
break
|
||||
|
||||
# If "{" is on next line, read next line
|
||||
if line.find("{") == -1:
|
||||
line = cppSource.readline()
|
||||
|
||||
# Write enum to output file as interface
|
||||
values = []
|
||||
line = cppSource.readline()
|
||||
while line.find("}") == -1:
|
||||
if line == "\n":
|
||||
values.append("")
|
||||
else:
|
||||
if line[0] != "#":
|
||||
line = line.strip()
|
||||
if line[len(line) - 1] == ",":
|
||||
values.append(line[0:len(line) - 1])
|
||||
else:
|
||||
values.append(line)
|
||||
line = cppSource.readline()
|
||||
|
||||
# Extract enum name
|
||||
nameStart = 0
|
||||
for i, c in enumerate(line):
|
||||
if c != " " and c != "}":
|
||||
nameStart = i
|
||||
break
|
||||
enumName = line[nameStart:len(line) - 2]
|
||||
|
||||
# Write comment for interface name
|
||||
# Only add newline if not the first enum
|
||||
if firstEnum == True:
|
||||
firstEnum = False
|
||||
else:
|
||||
temp.write("\n")
|
||||
temp.write(" /**\n"
|
||||
" * ")
|
||||
|
||||
# Splits camelcase string into words
|
||||
enumCamel = re.findall(r'[A-Z](?:[a-z]+|[A-Z]*(?=[A-Z]|$))',
|
||||
enumName)
|
||||
temp.write(enumCamel[0] + " ")
|
||||
for i in range(1, len(enumCamel)):
|
||||
temp.write(enumCamel[i][0].lower() + \
|
||||
enumCamel[i][1:len(enumCamel[i])] + " ")
|
||||
temp.write("from " + fileName + "\n"
|
||||
" */\n"
|
||||
" @SuppressWarnings(\"TypeName\")\n"
|
||||
" public interface " + enumName + " {\n")
|
||||
|
||||
# Write enum values
|
||||
count = 0
|
||||
for value in values:
|
||||
# Pass through empty lines
|
||||
if value == "":
|
||||
temp.write("\n")
|
||||
continue
|
||||
|
||||
if value.find("=") == -1:
|
||||
value = value + " = " + str(count)
|
||||
count += 1
|
||||
|
||||
# Add scoping for values from a different enum
|
||||
if enumName != "tModuleType" and \
|
||||
value.find("kModuleType") != -1:
|
||||
value = value.replace("kModuleType",
|
||||
"tModuleType.kModuleType")
|
||||
temp.write(" int " + value[0:len(value)] + ";\n")
|
||||
|
||||
# Write end of enum
|
||||
temp.write(" }\n")
|
||||
|
||||
# Write closing brace for file
|
||||
temp.write("}\n")
|
||||
|
||||
# Replace old output file
|
||||
try:
|
||||
os.remove(outputName)
|
||||
except OSError:
|
||||
pass
|
||||
os.rename(outputName + ".tmp", outputName)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
86
gmock/CMakeLists.txt
Normal file
86
gmock/CMakeLists.txt
Normal file
@@ -0,0 +1,86 @@
|
||||
########################################################################
|
||||
# CMake build script for Google Mock.
|
||||
#
|
||||
# To run the tests for Google Mock itself on Linux, use 'make test' or
|
||||
# ctest. You can select which tests to run using 'ctest -R regex'.
|
||||
# For more options, run 'ctest --help'.
|
||||
|
||||
# BUILD_SHARED_LIBS is a standard CMake variable, but we declare it here to
|
||||
# make it prominent in the GUI.
|
||||
option(BUILD_SHARED_LIBS "Build shared libraries (DLLs)." OFF)
|
||||
|
||||
# A directory to find Google Test sources.
|
||||
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/gtest/CMakeLists.txt")
|
||||
set(gtest_dir gtest)
|
||||
else()
|
||||
set(gtest_dir ../gtest)
|
||||
endif()
|
||||
|
||||
# Defines pre_project_set_up_hermetic_build() and set_up_hermetic_build().
|
||||
include("${gtest_dir}/cmake/hermetic_build.cmake" OPTIONAL)
|
||||
|
||||
if (COMMAND pre_project_set_up_hermetic_build)
|
||||
# Google Test also calls hermetic setup functions from add_subdirectory,
|
||||
# although its changes will not affect things at the current scope.
|
||||
pre_project_set_up_hermetic_build()
|
||||
endif()
|
||||
|
||||
########################################################################
|
||||
#
|
||||
# Project-wide settings
|
||||
|
||||
# Name of the project.
|
||||
#
|
||||
# CMake files in this project can refer to the root source directory
|
||||
# as ${gmock_SOURCE_DIR} and to the root binary directory as
|
||||
# ${gmock_BINARY_DIR}.
|
||||
# Language "C" is required for find_package(Threads).
|
||||
project(gmock CXX C)
|
||||
cmake_minimum_required(VERSION 2.6.2)
|
||||
|
||||
if (COMMAND set_up_hermetic_build)
|
||||
set_up_hermetic_build()
|
||||
endif()
|
||||
|
||||
if (NOT MSVC)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-missing-field-initializers -Wno-format-nonliteral")
|
||||
endif()
|
||||
|
||||
# Instructs CMake to process Google Test's CMakeLists.txt and add its
|
||||
# targets to the current scope. We are placing Google Test's binary
|
||||
# directory in a subdirectory of our own as VC compilation may break
|
||||
# if they are the same (the default).
|
||||
add_subdirectory("${gtest_dir}" "${gmock_BINARY_DIR}/gtest")
|
||||
|
||||
# Although Google Test's CMakeLists.txt calls this function, the
|
||||
# changes there don't affect the current scope. Therefore we have to
|
||||
# call it again here.
|
||||
config_compiler_and_linker() # from ${gtest_dir}/cmake/internal_utils.cmake
|
||||
|
||||
# Adds Google Mock's and Google Test's header directories to the search path.
|
||||
include_directories("${gmock_SOURCE_DIR}/include"
|
||||
"${gmock_SOURCE_DIR}"
|
||||
"${gtest_SOURCE_DIR}/include"
|
||||
# This directory is needed to build directly from Google
|
||||
# Test sources.
|
||||
"${gtest_SOURCE_DIR}")
|
||||
|
||||
########################################################################
|
||||
#
|
||||
# Defines the gmock & gmock_main libraries. User tests should link
|
||||
# with one of them.
|
||||
|
||||
# Google Mock libraries. We build them using more strict warnings than what
|
||||
# are used for other targets, to ensure that Google Mock can be compiled by
|
||||
# a user aggressive about warnings.
|
||||
cxx_library(gmock
|
||||
"${cxx_strict}"
|
||||
"${gtest_dir}/src/gtest-all.cc"
|
||||
src/gmock-all.cc)
|
||||
|
||||
cxx_library(gmock_main
|
||||
"${cxx_strict}"
|
||||
"${gtest_dir}/src/gtest-all.cc"
|
||||
src/gmock-all.cc
|
||||
src/gmock_main.cc)
|
||||
|
||||
28
gmock/LICENSE
Normal file
28
gmock/LICENSE
Normal file
@@ -0,0 +1,28 @@
|
||||
Copyright 2008, Google Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
44
gmock/build.gradle
Normal file
44
gmock/build.gradle
Normal file
@@ -0,0 +1,44 @@
|
||||
import org.gradle.internal.os.OperatingSystem
|
||||
|
||||
if (!project.hasProperty('onlyAthena')) {
|
||||
apply plugin: 'cpp'
|
||||
apply plugin: 'visual-studio'
|
||||
apply plugin: 'edu.wpi.first.NativeUtils'
|
||||
|
||||
ext.gmockProject = true
|
||||
|
||||
apply from: '../config.gradle'
|
||||
|
||||
ext.addGmockToLinker = { binary->
|
||||
binary.lib project: ':gmock', library: 'gmock', linkage: 'static'
|
||||
}
|
||||
|
||||
model {
|
||||
components {
|
||||
gmock(NativeLibrarySpec) {
|
||||
sources {
|
||||
cpp {
|
||||
source {
|
||||
srcDirs = ['src', 'gtest/src']
|
||||
includes = ['*-all.cc']
|
||||
}
|
||||
exportedHeaders {
|
||||
srcDirs = ['include', 'gtest/include', '.', 'gtest']
|
||||
includes = ['**/*.h', '**/*.cc']
|
||||
}
|
||||
}
|
||||
}
|
||||
binaries.all {
|
||||
if (toolChain in VisualCpp) {
|
||||
cppCompiler.args '-D_UNICODE', '-DUNICODE', '-DWIN32', '-D_WIN32', '-DSTRICT', '-DWIN32_LEAN_AND_MEAN', '-D_HAS_EXCEPTIONS=1'
|
||||
} else {
|
||||
cppCompiler.args '-Wall', '-Wshadow', '-fexceptions', '-Wextra', '-Wno-unused-parameter', '-Wno-missing-field-initializers', '-pthread', '-fPIC'
|
||||
}
|
||||
}
|
||||
binaries.withType(SharedLibraryBinarySpec) {
|
||||
buildable = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
69
gmock/gtest/CMakeLists.txt
Normal file
69
gmock/gtest/CMakeLists.txt
Normal file
@@ -0,0 +1,69 @@
|
||||
########################################################################
|
||||
# CMake build script for Google Test.
|
||||
#
|
||||
# To run the tests for Google Test itself on Linux, use 'make test' or
|
||||
# ctest. You can select which tests to run using 'ctest -R regex'.
|
||||
# For more options, run 'ctest --help'.
|
||||
|
||||
# BUILD_SHARED_LIBS is a standard CMake variable, but we declare it here to
|
||||
# make it prominent in the GUI.
|
||||
option(BUILD_SHARED_LIBS "Build shared libraries (DLLs)." OFF)
|
||||
|
||||
# When other libraries are using a shared version of runtime libraries,
|
||||
# Google Test also has to use one.
|
||||
option(
|
||||
gtest_force_shared_crt
|
||||
"Use shared (DLL) run-time lib even when Google Test is built as static lib."
|
||||
OFF)
|
||||
|
||||
option(gtest_disable_pthreads "Disable uses of pthreads in gtest." OFF)
|
||||
|
||||
# Defines pre_project_set_up_hermetic_build() and set_up_hermetic_build().
|
||||
include(cmake/hermetic_build.cmake OPTIONAL)
|
||||
|
||||
if (COMMAND pre_project_set_up_hermetic_build)
|
||||
pre_project_set_up_hermetic_build()
|
||||
endif()
|
||||
|
||||
########################################################################
|
||||
#
|
||||
# Project-wide settings
|
||||
|
||||
# Name of the project.
|
||||
#
|
||||
# CMake files in this project can refer to the root source directory
|
||||
# as ${gtest_SOURCE_DIR} and to the root binary directory as
|
||||
# ${gtest_BINARY_DIR}.
|
||||
# Language "C" is required for find_package(Threads).
|
||||
project(gtest CXX C)
|
||||
cmake_minimum_required(VERSION 2.6.2)
|
||||
|
||||
if (COMMAND set_up_hermetic_build)
|
||||
set_up_hermetic_build()
|
||||
endif()
|
||||
|
||||
# Define helper functions and macros used by Google Test.
|
||||
include(cmake/internal_utils.cmake)
|
||||
|
||||
config_compiler_and_linker() # Defined in internal_utils.cmake.
|
||||
|
||||
# Where Google Test's .h files can be found.
|
||||
include_directories(
|
||||
${gtest_SOURCE_DIR}/include
|
||||
${gtest_SOURCE_DIR})
|
||||
|
||||
# Where Google Test's libraries can be found.
|
||||
link_directories(${gtest_BINARY_DIR}/src)
|
||||
|
||||
########################################################################
|
||||
#
|
||||
# Defines the gtest & gtest_main libraries. User tests should link
|
||||
# with one of them.
|
||||
|
||||
# Google Test libraries. We build them using more strict warnings than what
|
||||
# are used for other targets, to ensure that gtest can be compiled by a user
|
||||
# aggressive about warnings.
|
||||
cxx_library(gtest "${cxx_strict}" src/gtest-all.cc)
|
||||
cxx_library(gtest_main "${cxx_strict}" src/gtest_main.cc)
|
||||
target_link_libraries(gtest_main gtest)
|
||||
|
||||
28
gmock/gtest/LICENSE
Normal file
28
gmock/gtest/LICENSE
Normal file
@@ -0,0 +1,28 @@
|
||||
Copyright 2008, Google Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
206
gmock/gtest/cmake/internal_utils.cmake
Normal file
206
gmock/gtest/cmake/internal_utils.cmake
Normal file
@@ -0,0 +1,206 @@
|
||||
# Defines functions and macros useful for building Google Test and
|
||||
# Google Mock.
|
||||
#
|
||||
# Note:
|
||||
#
|
||||
# - This file will be run twice when building Google Mock (once via
|
||||
# Google Test's CMakeLists.txt, and once via Google Mock's).
|
||||
# Therefore it shouldn't have any side effects other than defining
|
||||
# the functions and macros.
|
||||
#
|
||||
# - The functions/macros defined in this file may depend on Google
|
||||
# Test and Google Mock's option() definitions, and thus must be
|
||||
# called *after* the options have been defined.
|
||||
|
||||
# Tweaks CMake's default compiler/linker settings to suit Google Test's needs.
|
||||
#
|
||||
# This must be a macro(), as inside a function string() can only
|
||||
# update variables in the function scope.
|
||||
macro(fix_default_compiler_settings_)
|
||||
if (MSVC)
|
||||
# For MSVC, CMake sets certain flags to defaults we want to override.
|
||||
# This replacement code is taken from sample in the CMake Wiki at
|
||||
# http://www.cmake.org/Wiki/CMake_FAQ#Dynamic_Replace.
|
||||
foreach (flag_var
|
||||
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
|
||||
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
|
||||
if (NOT BUILD_SHARED_LIBS AND NOT gtest_force_shared_crt)
|
||||
# When Google Test is built as a shared library, it should also use
|
||||
# shared runtime libraries. Otherwise, it may end up with multiple
|
||||
# copies of runtime library data in different modules, resulting in
|
||||
# hard-to-find crashes. When it is built as a static library, it is
|
||||
# preferable to use CRT as static libraries, as we don't have to rely
|
||||
# on CRT DLLs being available. CMake always defaults to using shared
|
||||
# CRT libraries, so we override that default here.
|
||||
string(REPLACE "/MD" "-MT" ${flag_var} "${${flag_var}}")
|
||||
endif()
|
||||
|
||||
# We prefer more strict warning checking for building Google Test.
|
||||
# Replaces /W3 with /W4 in defaults.
|
||||
string(REPLACE "/W3" "-W4" ${flag_var} "${${flag_var}}")
|
||||
endforeach()
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# Defines the compiler/linker flags used to build Google Test and
|
||||
# Google Mock. You can tweak these definitions to suit your need. A
|
||||
# variable's value is empty before it's explicitly assigned to.
|
||||
macro(config_compiler_and_linker)
|
||||
if (NOT gtest_disable_pthreads)
|
||||
# Defines CMAKE_USE_PTHREADS_INIT and CMAKE_THREAD_LIBS_INIT.
|
||||
find_package(Threads)
|
||||
endif()
|
||||
|
||||
fix_default_compiler_settings_()
|
||||
if (MSVC)
|
||||
# Newlines inside flags variables break CMake's NMake generator.
|
||||
# TODO(vladl@google.com): Add -RTCs and -RTCu to debug builds.
|
||||
set(cxx_base_flags "-GS -W4 -WX -wd4127 -wd4251 -wd4275 -nologo -J -Zi")
|
||||
if (MSVC_VERSION LESS 1400)
|
||||
# Suppress spurious warnings MSVC 7.1 sometimes issues.
|
||||
# Forcing value to bool.
|
||||
set(cxx_base_flags "${cxx_base_flags} -wd4800")
|
||||
# Copy constructor and assignment operator could not be generated.
|
||||
set(cxx_base_flags "${cxx_base_flags} -wd4511 -wd4512")
|
||||
# Compatibility warnings not applicable to Google Test.
|
||||
# Resolved overload was found by argument-dependent lookup.
|
||||
set(cxx_base_flags "${cxx_base_flags} -wd4675")
|
||||
endif()
|
||||
set(cxx_base_flags "${cxx_base_flags} -D_UNICODE -DUNICODE -DWIN32 -D_WIN32")
|
||||
set(cxx_base_flags "${cxx_base_flags} -DSTRICT -DWIN32_LEAN_AND_MEAN")
|
||||
set(cxx_exception_flags "-EHsc -D_HAS_EXCEPTIONS=1")
|
||||
set(cxx_no_exception_flags "-D_HAS_EXCEPTIONS=0")
|
||||
set(cxx_no_rtti_flags "-GR-")
|
||||
elseif (CMAKE_COMPILER_IS_GNUCXX)
|
||||
set(cxx_base_flags "-Wall -Wshadow")
|
||||
set(cxx_exception_flags "-fexceptions")
|
||||
set(cxx_no_exception_flags "-fno-exceptions")
|
||||
# Until version 4.3.2, GCC doesn't define a macro to indicate
|
||||
# whether RTTI is enabled. Therefore we define GTEST_HAS_RTTI
|
||||
# explicitly.
|
||||
set(cxx_no_rtti_flags "-fno-rtti -DGTEST_HAS_RTTI=0")
|
||||
set(cxx_strict_flags
|
||||
"-Wextra -Wno-unused-parameter -Wno-missing-field-initializers")
|
||||
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "SunPro")
|
||||
set(cxx_exception_flags "-features=except")
|
||||
# Sun Pro doesn't provide macros to indicate whether exceptions and
|
||||
# RTTI are enabled, so we define GTEST_HAS_* explicitly.
|
||||
set(cxx_no_exception_flags "-features=no%except -DGTEST_HAS_EXCEPTIONS=0")
|
||||
set(cxx_no_rtti_flags "-features=no%rtti -DGTEST_HAS_RTTI=0")
|
||||
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "VisualAge" OR
|
||||
CMAKE_CXX_COMPILER_ID STREQUAL "XL")
|
||||
# CMake 2.8 changes Visual Age's compiler ID to "XL".
|
||||
set(cxx_exception_flags "-qeh")
|
||||
set(cxx_no_exception_flags "-qnoeh")
|
||||
# Until version 9.0, Visual Age doesn't define a macro to indicate
|
||||
# whether RTTI is enabled. Therefore we define GTEST_HAS_RTTI
|
||||
# explicitly.
|
||||
set(cxx_no_rtti_flags "-qnortti -DGTEST_HAS_RTTI=0")
|
||||
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "HP")
|
||||
set(cxx_base_flags "-AA -mt")
|
||||
set(cxx_exception_flags "-DGTEST_HAS_EXCEPTIONS=1")
|
||||
set(cxx_no_exception_flags "+noeh -DGTEST_HAS_EXCEPTIONS=0")
|
||||
# RTTI can not be disabled in HP aCC compiler.
|
||||
set(cxx_no_rtti_flags "")
|
||||
endif()
|
||||
|
||||
if (CMAKE_USE_PTHREADS_INIT) # The pthreads library is available and allowed.
|
||||
set(cxx_base_flags "${cxx_base_flags} -DGTEST_HAS_PTHREAD=1")
|
||||
else()
|
||||
set(cxx_base_flags "${cxx_base_flags} -DGTEST_HAS_PTHREAD=0")
|
||||
endif()
|
||||
|
||||
# For building gtest's own tests and samples.
|
||||
set(cxx_exception "${CMAKE_CXX_FLAGS} ${cxx_base_flags} ${cxx_exception_flags}")
|
||||
set(cxx_no_exception
|
||||
"${CMAKE_CXX_FLAGS} ${cxx_base_flags} ${cxx_no_exception_flags}")
|
||||
set(cxx_default "${cxx_exception}")
|
||||
set(cxx_no_rtti "${cxx_default} ${cxx_no_rtti_flags}")
|
||||
set(cxx_use_own_tuple "${cxx_default} -DGTEST_USE_OWN_TR1_TUPLE=1")
|
||||
|
||||
# For building the gtest libraries.
|
||||
set(cxx_strict "${cxx_default} ${cxx_strict_flags}")
|
||||
endmacro()
|
||||
|
||||
# Defines the gtest & gtest_main libraries. User tests should link
|
||||
# with one of them.
|
||||
function(cxx_library_with_type name type cxx_flags)
|
||||
# type can be either STATIC or SHARED to denote a static or shared library.
|
||||
# ARGN refers to additional arguments after 'cxx_flags'.
|
||||
add_library(${name} ${type} ${ARGN})
|
||||
set_target_properties(${name}
|
||||
PROPERTIES
|
||||
COMPILE_FLAGS "${cxx_flags}")
|
||||
if (BUILD_SHARED_LIBS OR type STREQUAL "SHARED")
|
||||
set_target_properties(${name}
|
||||
PROPERTIES
|
||||
COMPILE_DEFINITIONS "GTEST_CREATE_SHARED_LIBRARY=1")
|
||||
endif()
|
||||
if (CMAKE_USE_PTHREADS_INIT)
|
||||
target_link_libraries(${name} ${CMAKE_THREAD_LIBS_INIT})
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
########################################################################
|
||||
#
|
||||
# Helper functions for creating build targets.
|
||||
|
||||
function(cxx_shared_library name cxx_flags)
|
||||
cxx_library_with_type(${name} SHARED "${cxx_flags}" ${ARGN})
|
||||
endfunction()
|
||||
|
||||
function(cxx_library name cxx_flags)
|
||||
cxx_library_with_type(${name} "" "${cxx_flags}" ${ARGN})
|
||||
endfunction()
|
||||
|
||||
# cxx_executable_with_flags(name cxx_flags libs srcs...)
|
||||
#
|
||||
# creates a named C++ executable that depends on the given libraries and
|
||||
# is built from the given source files with the given compiler flags.
|
||||
function(cxx_executable_with_flags name cxx_flags libs)
|
||||
add_executable(${name} ${ARGN})
|
||||
if (cxx_flags)
|
||||
set_target_properties(${name}
|
||||
PROPERTIES
|
||||
COMPILE_FLAGS "${cxx_flags}")
|
||||
endif()
|
||||
if (BUILD_SHARED_LIBS)
|
||||
set_target_properties(${name}
|
||||
PROPERTIES
|
||||
COMPILE_DEFINITIONS "GTEST_LINKED_AS_SHARED_LIBRARY=1")
|
||||
endif()
|
||||
# To support mixing linking in static and dynamic libraries, link each
|
||||
# library in with an extra call to target_link_libraries.
|
||||
foreach (lib "${libs}")
|
||||
target_link_libraries(${name} ${lib})
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
# cxx_executable(name dir lib srcs...)
|
||||
#
|
||||
# creates a named target that depends on the given libs and is built
|
||||
# from the given source files. dir/name.cc is implicitly included in
|
||||
# the source file list.
|
||||
function(cxx_executable name dir libs)
|
||||
cxx_executable_with_flags(
|
||||
${name} "${cxx_default}" "${libs}" "${dir}/${name}.cc" ${ARGN})
|
||||
endfunction()
|
||||
|
||||
# cxx_test_with_flags(name cxx_flags libs srcs...)
|
||||
#
|
||||
# creates a named C++ test that depends on the given libs and is built
|
||||
# from the given source files with the given compiler flags.
|
||||
function(cxx_test_with_flags name cxx_flags libs)
|
||||
cxx_executable_with_flags(${name} "${cxx_flags}" "${libs}" ${ARGN})
|
||||
add_test(${name} ${name})
|
||||
endfunction()
|
||||
|
||||
# cxx_test(name libs srcs...)
|
||||
#
|
||||
# creates a named test target that depends on the given libs and is
|
||||
# built from the given source files. Unlike cxx_test_with_flags,
|
||||
# test/name.cc is already implicitly included in the source file list.
|
||||
function(cxx_test name libs)
|
||||
cxx_test_with_flags("${name}" "${cxx_default}" "${libs}"
|
||||
"test/${name}.cc" ${ARGN})
|
||||
endfunction()
|
||||
@@ -1,294 +1,294 @@
|
||||
// Copyright 2005, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
//
|
||||
// The Google C++ Testing Framework (Google Test)
|
||||
//
|
||||
// This header file defines the public API for death tests. It is
|
||||
// #included by gtest.h so a user doesn't need to include this
|
||||
// directly.
|
||||
|
||||
#ifndef GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
|
||||
#define GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
|
||||
|
||||
#include "gtest/internal/gtest-death-test-internal.h"
|
||||
|
||||
namespace testing {
|
||||
|
||||
// This flag controls the style of death tests. Valid values are "threadsafe",
|
||||
// meaning that the death test child process will re-execute the test binary
|
||||
// from the start, running only a single death test, or "fast",
|
||||
// meaning that the child process will execute the test logic immediately
|
||||
// after forking.
|
||||
GTEST_DECLARE_string_(death_test_style);
|
||||
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
|
||||
namespace internal {
|
||||
|
||||
// Returns a Boolean value indicating whether the caller is currently
|
||||
// executing in the context of the death test child process. Tools such as
|
||||
// Valgrind heap checkers may need this to modify their behavior in death
|
||||
// tests. IMPORTANT: This is an internal utility. Using it may break the
|
||||
// implementation of death tests. User code MUST NOT use it.
|
||||
GTEST_API_ bool InDeathTestChild();
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// The following macros are useful for writing death tests.
|
||||
|
||||
// Here's what happens when an ASSERT_DEATH* or EXPECT_DEATH* is
|
||||
// executed:
|
||||
//
|
||||
// 1. It generates a warning if there is more than one active
|
||||
// thread. This is because it's safe to fork() or clone() only
|
||||
// when there is a single thread.
|
||||
//
|
||||
// 2. The parent process clone()s a sub-process and runs the death
|
||||
// test in it; the sub-process exits with code 0 at the end of the
|
||||
// death test, if it hasn't exited already.
|
||||
//
|
||||
// 3. The parent process waits for the sub-process to terminate.
|
||||
//
|
||||
// 4. The parent process checks the exit code and error message of
|
||||
// the sub-process.
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// ASSERT_DEATH(server.SendMessage(56, "Hello"), "Invalid port number");
|
||||
// for (int i = 0; i < 5; i++) {
|
||||
// EXPECT_DEATH(server.ProcessRequest(i),
|
||||
// "Invalid request .* in ProcessRequest()")
|
||||
// << "Failed to die on request " << i;
|
||||
// }
|
||||
//
|
||||
// ASSERT_EXIT(server.ExitNow(), ::testing::ExitedWithCode(0), "Exiting");
|
||||
//
|
||||
// bool KilledBySIGHUP(int exit_code) {
|
||||
// return WIFSIGNALED(exit_code) && WTERMSIG(exit_code) == SIGHUP;
|
||||
// }
|
||||
//
|
||||
// ASSERT_EXIT(client.HangUpServer(), KilledBySIGHUP, "Hanging up!");
|
||||
//
|
||||
// On the regular expressions used in death tests:
|
||||
//
|
||||
// On POSIX-compliant systems (*nix), we use the <regex.h> library,
|
||||
// which uses the POSIX extended regex syntax.
|
||||
//
|
||||
// On other platforms (e.g. Windows), we only support a simple regex
|
||||
// syntax implemented as part of Google Test. This limited
|
||||
// implementation should be enough most of the time when writing
|
||||
// death tests; though it lacks many features you can find in PCRE
|
||||
// or POSIX extended regex syntax. For example, we don't support
|
||||
// union ("x|y"), grouping ("(xy)"), brackets ("[xy]"), and
|
||||
// repetition count ("x{5,7}"), among others.
|
||||
//
|
||||
// Below is the syntax that we do support. We chose it to be a
|
||||
// subset of both PCRE and POSIX extended regex, so it's easy to
|
||||
// learn wherever you come from. In the following: 'A' denotes a
|
||||
// literal character, period (.), or a single \\ escape sequence;
|
||||
// 'x' and 'y' denote regular expressions; 'm' and 'n' are for
|
||||
// natural numbers.
|
||||
//
|
||||
// c matches any literal character c
|
||||
// \\d matches any decimal digit
|
||||
// \\D matches any character that's not a decimal digit
|
||||
// \\f matches \f
|
||||
// \\n matches \n
|
||||
// \\r matches \r
|
||||
// \\s matches any ASCII whitespace, including \n
|
||||
// \\S matches any character that's not a whitespace
|
||||
// \\t matches \t
|
||||
// \\v matches \v
|
||||
// \\w matches any letter, _, or decimal digit
|
||||
// \\W matches any character that \\w doesn't match
|
||||
// \\c matches any literal character c, which must be a punctuation
|
||||
// . matches any single character except \n
|
||||
// A? matches 0 or 1 occurrences of A
|
||||
// A* matches 0 or many occurrences of A
|
||||
// A+ matches 1 or many occurrences of A
|
||||
// ^ matches the beginning of a string (not that of each line)
|
||||
// $ matches the end of a string (not that of each line)
|
||||
// xy matches x followed by y
|
||||
//
|
||||
// If you accidentally use PCRE or POSIX extended regex features
|
||||
// not implemented by us, you will get a run-time failure. In that
|
||||
// case, please try to rewrite your regular expression within the
|
||||
// above syntax.
|
||||
//
|
||||
// This implementation is *not* meant to be as highly tuned or robust
|
||||
// as a compiled regex library, but should perform well enough for a
|
||||
// death test, which already incurs significant overhead by launching
|
||||
// a child process.
|
||||
//
|
||||
// Known caveats:
|
||||
//
|
||||
// A "threadsafe" style death test obtains the path to the test
|
||||
// program from argv[0] and re-executes it in the sub-process. For
|
||||
// simplicity, the current implementation doesn't search the PATH
|
||||
// when launching the sub-process. This means that the user must
|
||||
// invoke the test program via a path that contains at least one
|
||||
// path separator (e.g. path/to/foo_test and
|
||||
// /absolute/path/to/bar_test are fine, but foo_test is not). This
|
||||
// is rarely a problem as people usually don't put the test binary
|
||||
// directory in PATH.
|
||||
//
|
||||
// TODO(wan@google.com): make thread-safe death tests search the PATH.
|
||||
|
||||
// Asserts that a given statement causes the program to exit, with an
|
||||
// integer exit status that satisfies predicate, and emitting error output
|
||||
// that matches regex.
|
||||
# define ASSERT_EXIT(statement, predicate, regex) \
|
||||
GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_FATAL_FAILURE_)
|
||||
|
||||
// Like ASSERT_EXIT, but continues on to successive tests in the
|
||||
// test case, if any:
|
||||
# define EXPECT_EXIT(statement, predicate, regex) \
|
||||
GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_NONFATAL_FAILURE_)
|
||||
|
||||
// Asserts that a given statement causes the program to exit, either by
|
||||
// explicitly exiting with a nonzero exit code or being killed by a
|
||||
// signal, and emitting error output that matches regex.
|
||||
# define ASSERT_DEATH(statement, regex) \
|
||||
ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex)
|
||||
|
||||
// Like ASSERT_DEATH, but continues on to successive tests in the
|
||||
// test case, if any:
|
||||
# define EXPECT_DEATH(statement, regex) \
|
||||
EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex)
|
||||
|
||||
// Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*:
|
||||
|
||||
// Tests that an exit code describes a normal exit with a given exit code.
|
||||
class GTEST_API_ ExitedWithCode {
|
||||
public:
|
||||
explicit ExitedWithCode(int exit_code);
|
||||
bool operator()(int exit_status) const;
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ExitedWithCode& other);
|
||||
|
||||
const int exit_code_;
|
||||
};
|
||||
|
||||
# if !GTEST_OS_WINDOWS
|
||||
// Tests that an exit code describes an exit due to termination by a
|
||||
// given signal.
|
||||
class GTEST_API_ KilledBySignal {
|
||||
public:
|
||||
explicit KilledBySignal(int signum);
|
||||
bool operator()(int exit_status) const;
|
||||
private:
|
||||
const int signum_;
|
||||
};
|
||||
# endif // !GTEST_OS_WINDOWS
|
||||
|
||||
// EXPECT_DEBUG_DEATH asserts that the given statements die in debug mode.
|
||||
// The death testing framework causes this to have interesting semantics,
|
||||
// since the sideeffects of the call are only visible in opt mode, and not
|
||||
// in debug mode.
|
||||
//
|
||||
// In practice, this can be used to test functions that utilize the
|
||||
// LOG(DFATAL) macro using the following style:
|
||||
//
|
||||
// int DieInDebugOr12(int* sideeffect) {
|
||||
// if (sideeffect) {
|
||||
// *sideeffect = 12;
|
||||
// }
|
||||
// LOG(DFATAL) << "death";
|
||||
// return 12;
|
||||
// }
|
||||
//
|
||||
// TEST(TestCase, TestDieOr12WorksInDgbAndOpt) {
|
||||
// int sideeffect = 0;
|
||||
// // Only asserts in dbg.
|
||||
// EXPECT_DEBUG_DEATH(DieInDebugOr12(&sideeffect), "death");
|
||||
//
|
||||
// #ifdef NDEBUG
|
||||
// // opt-mode has sideeffect visible.
|
||||
// EXPECT_EQ(12, sideeffect);
|
||||
// #else
|
||||
// // dbg-mode no visible sideeffect.
|
||||
// EXPECT_EQ(0, sideeffect);
|
||||
// #endif
|
||||
// }
|
||||
//
|
||||
// This will assert that DieInDebugReturn12InOpt() crashes in debug
|
||||
// mode, usually due to a DCHECK or LOG(DFATAL), but returns the
|
||||
// appropriate fallback value (12 in this case) in opt mode. If you
|
||||
// need to test that a function has appropriate side-effects in opt
|
||||
// mode, include assertions against the side-effects. A general
|
||||
// pattern for this is:
|
||||
//
|
||||
// EXPECT_DEBUG_DEATH({
|
||||
// // Side-effects here will have an effect after this statement in
|
||||
// // opt mode, but none in debug mode.
|
||||
// EXPECT_EQ(12, DieInDebugOr12(&sideeffect));
|
||||
// }, "death");
|
||||
//
|
||||
# ifdef NDEBUG
|
||||
|
||||
# define EXPECT_DEBUG_DEATH(statement, regex) \
|
||||
GTEST_EXECUTE_STATEMENT_(statement, regex)
|
||||
|
||||
# define ASSERT_DEBUG_DEATH(statement, regex) \
|
||||
GTEST_EXECUTE_STATEMENT_(statement, regex)
|
||||
|
||||
# else
|
||||
|
||||
# define EXPECT_DEBUG_DEATH(statement, regex) \
|
||||
EXPECT_DEATH(statement, regex)
|
||||
|
||||
# define ASSERT_DEBUG_DEATH(statement, regex) \
|
||||
ASSERT_DEATH(statement, regex)
|
||||
|
||||
# endif // NDEBUG for EXPECT_DEBUG_DEATH
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
||||
|
||||
// EXPECT_DEATH_IF_SUPPORTED(statement, regex) and
|
||||
// ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if
|
||||
// death tests are supported; otherwise they just issue a warning. This is
|
||||
// useful when you are combining death test assertions with normal test
|
||||
// assertions in one test.
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
|
||||
EXPECT_DEATH(statement, regex)
|
||||
# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \
|
||||
ASSERT_DEATH(statement, regex)
|
||||
#else
|
||||
# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
|
||||
GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, )
|
||||
# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \
|
||||
GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, return)
|
||||
#endif
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
|
||||
// Copyright 2005, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
//
|
||||
// The Google C++ Testing Framework (Google Test)
|
||||
//
|
||||
// This header file defines the public API for death tests. It is
|
||||
// #included by gtest.h so a user doesn't need to include this
|
||||
// directly.
|
||||
|
||||
#ifndef GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
|
||||
#define GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
|
||||
|
||||
#include "gtest/internal/gtest-death-test-internal.h"
|
||||
|
||||
namespace testing {
|
||||
|
||||
// This flag controls the style of death tests. Valid values are "threadsafe",
|
||||
// meaning that the death test child process will re-execute the test binary
|
||||
// from the start, running only a single death test, or "fast",
|
||||
// meaning that the child process will execute the test logic immediately
|
||||
// after forking.
|
||||
GTEST_DECLARE_string_(death_test_style);
|
||||
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
|
||||
namespace internal {
|
||||
|
||||
// Returns a Boolean value indicating whether the caller is currently
|
||||
// executing in the context of the death test child process. Tools such as
|
||||
// Valgrind heap checkers may need this to modify their behavior in death
|
||||
// tests. IMPORTANT: This is an internal utility. Using it may break the
|
||||
// implementation of death tests. User code MUST NOT use it.
|
||||
GTEST_API_ bool InDeathTestChild();
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// The following macros are useful for writing death tests.
|
||||
|
||||
// Here's what happens when an ASSERT_DEATH* or EXPECT_DEATH* is
|
||||
// executed:
|
||||
//
|
||||
// 1. It generates a warning if there is more than one active
|
||||
// thread. This is because it's safe to fork() or clone() only
|
||||
// when there is a single thread.
|
||||
//
|
||||
// 2. The parent process clone()s a sub-process and runs the death
|
||||
// test in it; the sub-process exits with code 0 at the end of the
|
||||
// death test, if it hasn't exited already.
|
||||
//
|
||||
// 3. The parent process waits for the sub-process to terminate.
|
||||
//
|
||||
// 4. The parent process checks the exit code and error message of
|
||||
// the sub-process.
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// ASSERT_DEATH(server.SendMessage(56, "Hello"), "Invalid port number");
|
||||
// for (int i = 0; i < 5; i++) {
|
||||
// EXPECT_DEATH(server.ProcessRequest(i),
|
||||
// "Invalid request .* in ProcessRequest()")
|
||||
// << "Failed to die on request " << i;
|
||||
// }
|
||||
//
|
||||
// ASSERT_EXIT(server.ExitNow(), ::testing::ExitedWithCode(0), "Exiting");
|
||||
//
|
||||
// bool KilledBySIGHUP(int exit_code) {
|
||||
// return WIFSIGNALED(exit_code) && WTERMSIG(exit_code) == SIGHUP;
|
||||
// }
|
||||
//
|
||||
// ASSERT_EXIT(client.HangUpServer(), KilledBySIGHUP, "Hanging up!");
|
||||
//
|
||||
// On the regular expressions used in death tests:
|
||||
//
|
||||
// On POSIX-compliant systems (*nix), we use the <regex.h> library,
|
||||
// which uses the POSIX extended regex syntax.
|
||||
//
|
||||
// On other platforms (e.g. Windows), we only support a simple regex
|
||||
// syntax implemented as part of Google Test. This limited
|
||||
// implementation should be enough most of the time when writing
|
||||
// death tests; though it lacks many features you can find in PCRE
|
||||
// or POSIX extended regex syntax. For example, we don't support
|
||||
// union ("x|y"), grouping ("(xy)"), brackets ("[xy]"), and
|
||||
// repetition count ("x{5,7}"), among others.
|
||||
//
|
||||
// Below is the syntax that we do support. We chose it to be a
|
||||
// subset of both PCRE and POSIX extended regex, so it's easy to
|
||||
// learn wherever you come from. In the following: 'A' denotes a
|
||||
// literal character, period (.), or a single \\ escape sequence;
|
||||
// 'x' and 'y' denote regular expressions; 'm' and 'n' are for
|
||||
// natural numbers.
|
||||
//
|
||||
// c matches any literal character c
|
||||
// \\d matches any decimal digit
|
||||
// \\D matches any character that's not a decimal digit
|
||||
// \\f matches \f
|
||||
// \\n matches \n
|
||||
// \\r matches \r
|
||||
// \\s matches any ASCII whitespace, including \n
|
||||
// \\S matches any character that's not a whitespace
|
||||
// \\t matches \t
|
||||
// \\v matches \v
|
||||
// \\w matches any letter, _, or decimal digit
|
||||
// \\W matches any character that \\w doesn't match
|
||||
// \\c matches any literal character c, which must be a punctuation
|
||||
// . matches any single character except \n
|
||||
// A? matches 0 or 1 occurrences of A
|
||||
// A* matches 0 or many occurrences of A
|
||||
// A+ matches 1 or many occurrences of A
|
||||
// ^ matches the beginning of a string (not that of each line)
|
||||
// $ matches the end of a string (not that of each line)
|
||||
// xy matches x followed by y
|
||||
//
|
||||
// If you accidentally use PCRE or POSIX extended regex features
|
||||
// not implemented by us, you will get a run-time failure. In that
|
||||
// case, please try to rewrite your regular expression within the
|
||||
// above syntax.
|
||||
//
|
||||
// This implementation is *not* meant to be as highly tuned or robust
|
||||
// as a compiled regex library, but should perform well enough for a
|
||||
// death test, which already incurs significant overhead by launching
|
||||
// a child process.
|
||||
//
|
||||
// Known caveats:
|
||||
//
|
||||
// A "threadsafe" style death test obtains the path to the test
|
||||
// program from argv[0] and re-executes it in the sub-process. For
|
||||
// simplicity, the current implementation doesn't search the PATH
|
||||
// when launching the sub-process. This means that the user must
|
||||
// invoke the test program via a path that contains at least one
|
||||
// path separator (e.g. path/to/foo_test and
|
||||
// /absolute/path/to/bar_test are fine, but foo_test is not). This
|
||||
// is rarely a problem as people usually don't put the test binary
|
||||
// directory in PATH.
|
||||
//
|
||||
// TODO(wan@google.com): make thread-safe death tests search the PATH.
|
||||
|
||||
// Asserts that a given statement causes the program to exit, with an
|
||||
// integer exit status that satisfies predicate, and emitting error output
|
||||
// that matches regex.
|
||||
# define ASSERT_EXIT(statement, predicate, regex) \
|
||||
GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_FATAL_FAILURE_)
|
||||
|
||||
// Like ASSERT_EXIT, but continues on to successive tests in the
|
||||
// test case, if any:
|
||||
# define EXPECT_EXIT(statement, predicate, regex) \
|
||||
GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_NONFATAL_FAILURE_)
|
||||
|
||||
// Asserts that a given statement causes the program to exit, either by
|
||||
// explicitly exiting with a nonzero exit code or being killed by a
|
||||
// signal, and emitting error output that matches regex.
|
||||
# define ASSERT_DEATH(statement, regex) \
|
||||
ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex)
|
||||
|
||||
// Like ASSERT_DEATH, but continues on to successive tests in the
|
||||
// test case, if any:
|
||||
# define EXPECT_DEATH(statement, regex) \
|
||||
EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex)
|
||||
|
||||
// Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*:
|
||||
|
||||
// Tests that an exit code describes a normal exit with a given exit code.
|
||||
class GTEST_API_ ExitedWithCode {
|
||||
public:
|
||||
explicit ExitedWithCode(int exit_code);
|
||||
bool operator()(int exit_status) const;
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ExitedWithCode& other);
|
||||
|
||||
const int exit_code_;
|
||||
};
|
||||
|
||||
# if !GTEST_OS_WINDOWS
|
||||
// Tests that an exit code describes an exit due to termination by a
|
||||
// given signal.
|
||||
class GTEST_API_ KilledBySignal {
|
||||
public:
|
||||
explicit KilledBySignal(int signum);
|
||||
bool operator()(int exit_status) const;
|
||||
private:
|
||||
const int signum_;
|
||||
};
|
||||
# endif // !GTEST_OS_WINDOWS
|
||||
|
||||
// EXPECT_DEBUG_DEATH asserts that the given statements die in debug mode.
|
||||
// The death testing framework causes this to have interesting semantics,
|
||||
// since the sideeffects of the call are only visible in opt mode, and not
|
||||
// in debug mode.
|
||||
//
|
||||
// In practice, this can be used to test functions that utilize the
|
||||
// LOG(DFATAL) macro using the following style:
|
||||
//
|
||||
// int DieInDebugOr12(int* sideeffect) {
|
||||
// if (sideeffect) {
|
||||
// *sideeffect = 12;
|
||||
// }
|
||||
// LOG(DFATAL) << "death";
|
||||
// return 12;
|
||||
// }
|
||||
//
|
||||
// TEST(TestCase, TestDieOr12WorksInDgbAndOpt) {
|
||||
// int sideeffect = 0;
|
||||
// // Only asserts in dbg.
|
||||
// EXPECT_DEBUG_DEATH(DieInDebugOr12(&sideeffect), "death");
|
||||
//
|
||||
// #ifdef NDEBUG
|
||||
// // opt-mode has sideeffect visible.
|
||||
// EXPECT_EQ(12, sideeffect);
|
||||
// #else
|
||||
// // dbg-mode no visible sideeffect.
|
||||
// EXPECT_EQ(0, sideeffect);
|
||||
// #endif
|
||||
// }
|
||||
//
|
||||
// This will assert that DieInDebugReturn12InOpt() crashes in debug
|
||||
// mode, usually due to a DCHECK or LOG(DFATAL), but returns the
|
||||
// appropriate fallback value (12 in this case) in opt mode. If you
|
||||
// need to test that a function has appropriate side-effects in opt
|
||||
// mode, include assertions against the side-effects. A general
|
||||
// pattern for this is:
|
||||
//
|
||||
// EXPECT_DEBUG_DEATH({
|
||||
// // Side-effects here will have an effect after this statement in
|
||||
// // opt mode, but none in debug mode.
|
||||
// EXPECT_EQ(12, DieInDebugOr12(&sideeffect));
|
||||
// }, "death");
|
||||
//
|
||||
# ifdef NDEBUG
|
||||
|
||||
# define EXPECT_DEBUG_DEATH(statement, regex) \
|
||||
GTEST_EXECUTE_STATEMENT_(statement, regex)
|
||||
|
||||
# define ASSERT_DEBUG_DEATH(statement, regex) \
|
||||
GTEST_EXECUTE_STATEMENT_(statement, regex)
|
||||
|
||||
# else
|
||||
|
||||
# define EXPECT_DEBUG_DEATH(statement, regex) \
|
||||
EXPECT_DEATH(statement, regex)
|
||||
|
||||
# define ASSERT_DEBUG_DEATH(statement, regex) \
|
||||
ASSERT_DEATH(statement, regex)
|
||||
|
||||
# endif // NDEBUG for EXPECT_DEBUG_DEATH
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
||||
|
||||
// EXPECT_DEATH_IF_SUPPORTED(statement, regex) and
|
||||
// ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if
|
||||
// death tests are supported; otherwise they just issue a warning. This is
|
||||
// useful when you are combining death test assertions with normal test
|
||||
// assertions in one test.
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
|
||||
EXPECT_DEATH(statement, regex)
|
||||
# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \
|
||||
ASSERT_DEATH(statement, regex)
|
||||
#else
|
||||
# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
|
||||
GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, )
|
||||
# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \
|
||||
GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, return)
|
||||
#endif
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
|
||||
@@ -1,250 +1,250 @@
|
||||
// Copyright 2005, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
//
|
||||
// The Google C++ Testing Framework (Google Test)
|
||||
//
|
||||
// This header file defines the Message class.
|
||||
//
|
||||
// IMPORTANT NOTE: Due to limitation of the C++ language, we have to
|
||||
// leave some internal implementation details in this header file.
|
||||
// They are clearly marked by comments like this:
|
||||
//
|
||||
// // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
||||
//
|
||||
// Such code is NOT meant to be used by a user directly, and is subject
|
||||
// to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user
|
||||
// program!
|
||||
|
||||
#ifndef GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
|
||||
#define GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
|
||||
// Ensures that there is at least one operator<< in the global namespace.
|
||||
// See Message& operator<<(...) below for why.
|
||||
void operator<<(const testing::internal::Secret&, int);
|
||||
|
||||
namespace testing {
|
||||
|
||||
// The Message class works like an ostream repeater.
|
||||
//
|
||||
// Typical usage:
|
||||
//
|
||||
// 1. You stream a bunch of values to a Message object.
|
||||
// It will remember the text in a stringstream.
|
||||
// 2. Then you stream the Message object to an ostream.
|
||||
// This causes the text in the Message to be streamed
|
||||
// to the ostream.
|
||||
//
|
||||
// For example;
|
||||
//
|
||||
// testing::Message foo;
|
||||
// foo << 1 << " != " << 2;
|
||||
// std::cout << foo;
|
||||
//
|
||||
// will print "1 != 2".
|
||||
//
|
||||
// Message is not intended to be inherited from. In particular, its
|
||||
// destructor is not virtual.
|
||||
//
|
||||
// Note that stringstream behaves differently in gcc and in MSVC. You
|
||||
// can stream a NULL char pointer to it in the former, but not in the
|
||||
// latter (it causes an access violation if you do). The Message
|
||||
// class hides this difference by treating a NULL char pointer as
|
||||
// "(null)".
|
||||
class GTEST_API_ Message {
|
||||
private:
|
||||
// The type of basic IO manipulators (endl, ends, and flush) for
|
||||
// narrow streams.
|
||||
typedef std::ostream& (*BasicNarrowIoManip)(std::ostream&);
|
||||
|
||||
public:
|
||||
// Constructs an empty Message.
|
||||
Message();
|
||||
|
||||
// Copy constructor.
|
||||
Message(const Message& msg) : ss_(new ::std::stringstream) { // NOLINT
|
||||
*ss_ << msg.GetString();
|
||||
}
|
||||
|
||||
// Constructs a Message from a C-string.
|
||||
explicit Message(const char* str) : ss_(new ::std::stringstream) {
|
||||
*ss_ << str;
|
||||
}
|
||||
|
||||
#if GTEST_OS_SYMBIAN
|
||||
// Streams a value (either a pointer or not) to this object.
|
||||
template <typename T>
|
||||
inline Message& operator <<(const T& value) {
|
||||
StreamHelper(typename internal::is_pointer<T>::type(), value);
|
||||
return *this;
|
||||
}
|
||||
#else
|
||||
// Streams a non-pointer value to this object.
|
||||
template <typename T>
|
||||
inline Message& operator <<(const T& val) {
|
||||
// Some libraries overload << for STL containers. These
|
||||
// overloads are defined in the global namespace instead of ::std.
|
||||
//
|
||||
// C++'s symbol lookup rule (i.e. Koenig lookup) says that these
|
||||
// overloads are visible in either the std namespace or the global
|
||||
// namespace, but not other namespaces, including the testing
|
||||
// namespace which Google Test's Message class is in.
|
||||
//
|
||||
// To allow STL containers (and other types that has a << operator
|
||||
// defined in the global namespace) to be used in Google Test
|
||||
// assertions, testing::Message must access the custom << operator
|
||||
// from the global namespace. With this using declaration,
|
||||
// overloads of << defined in the global namespace and those
|
||||
// visible via Koenig lookup are both exposed in this function.
|
||||
using ::operator <<;
|
||||
*ss_ << val;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Streams a pointer value to this object.
|
||||
//
|
||||
// This function is an overload of the previous one. When you
|
||||
// stream a pointer to a Message, this definition will be used as it
|
||||
// is more specialized. (The C++ Standard, section
|
||||
// [temp.func.order].) If you stream a non-pointer, then the
|
||||
// previous definition will be used.
|
||||
//
|
||||
// The reason for this overload is that streaming a NULL pointer to
|
||||
// ostream is undefined behavior. Depending on the compiler, you
|
||||
// may get "0", "(nil)", "(null)", or an access violation. To
|
||||
// ensure consistent result across compilers, we always treat NULL
|
||||
// as "(null)".
|
||||
template <typename T>
|
||||
inline Message& operator <<(T* const& pointer) { // NOLINT
|
||||
if (pointer == NULL) {
|
||||
*ss_ << "(null)";
|
||||
} else {
|
||||
*ss_ << pointer;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
#endif // GTEST_OS_SYMBIAN
|
||||
|
||||
// Since the basic IO manipulators are overloaded for both narrow
|
||||
// and wide streams, we have to provide this specialized definition
|
||||
// of operator <<, even though its body is the same as the
|
||||
// templatized version above. Without this definition, streaming
|
||||
// endl or other basic IO manipulators to Message will confuse the
|
||||
// compiler.
|
||||
Message& operator <<(BasicNarrowIoManip val) {
|
||||
*ss_ << val;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Instead of 1/0, we want to see true/false for bool values.
|
||||
Message& operator <<(bool b) {
|
||||
return *this << (b ? "true" : "false");
|
||||
}
|
||||
|
||||
// These two overloads allow streaming a wide C string to a Message
|
||||
// using the UTF-8 encoding.
|
||||
Message& operator <<(const wchar_t* wide_c_str);
|
||||
Message& operator <<(wchar_t* wide_c_str);
|
||||
|
||||
#if GTEST_HAS_STD_WSTRING
|
||||
// Converts the given wide string to a narrow string using the UTF-8
|
||||
// encoding, and streams the result to this Message object.
|
||||
Message& operator <<(const ::std::wstring& wstr);
|
||||
#endif // GTEST_HAS_STD_WSTRING
|
||||
|
||||
#if GTEST_HAS_GLOBAL_WSTRING
|
||||
// Converts the given wide string to a narrow string using the UTF-8
|
||||
// encoding, and streams the result to this Message object.
|
||||
Message& operator <<(const ::wstring& wstr);
|
||||
#endif // GTEST_HAS_GLOBAL_WSTRING
|
||||
|
||||
// Gets the text streamed to this object so far as an std::string.
|
||||
// Each '\0' character in the buffer is replaced with "\\0".
|
||||
//
|
||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
||||
std::string GetString() const;
|
||||
|
||||
private:
|
||||
|
||||
#if GTEST_OS_SYMBIAN
|
||||
// These are needed as the Nokia Symbian Compiler cannot decide between
|
||||
// const T& and const T* in a function template. The Nokia compiler _can_
|
||||
// decide between class template specializations for T and T*, so a
|
||||
// tr1::type_traits-like is_pointer works, and we can overload on that.
|
||||
template <typename T>
|
||||
inline void StreamHelper(internal::true_type /*is_pointer*/, T* pointer) {
|
||||
if (pointer == NULL) {
|
||||
*ss_ << "(null)";
|
||||
} else {
|
||||
*ss_ << pointer;
|
||||
}
|
||||
}
|
||||
template <typename T>
|
||||
inline void StreamHelper(internal::false_type /*is_pointer*/,
|
||||
const T& value) {
|
||||
// See the comments in Message& operator <<(const T&) above for why
|
||||
// we need this using statement.
|
||||
using ::operator <<;
|
||||
*ss_ << value;
|
||||
}
|
||||
#endif // GTEST_OS_SYMBIAN
|
||||
|
||||
// We'll hold the text streamed to this object here.
|
||||
const internal::scoped_ptr< ::std::stringstream> ss_;
|
||||
|
||||
// We declare (but don't implement) this to prevent the compiler
|
||||
// from implementing the assignment operator.
|
||||
void operator=(const Message&);
|
||||
};
|
||||
|
||||
// Streams a Message to an ostream.
|
||||
inline std::ostream& operator <<(std::ostream& os, const Message& sb) {
|
||||
return os << sb.GetString();
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
|
||||
// Converts a streamable value to an std::string. A NULL pointer is
|
||||
// converted to "(null)". When the input value is a ::string,
|
||||
// ::std::string, ::wstring, or ::std::wstring object, each NUL
|
||||
// character in it is replaced with "\\0".
|
||||
template <typename T>
|
||||
std::string StreamableToString(const T& streamable) {
|
||||
return (Message() << streamable).GetString();
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
|
||||
// Copyright 2005, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
//
|
||||
// The Google C++ Testing Framework (Google Test)
|
||||
//
|
||||
// This header file defines the Message class.
|
||||
//
|
||||
// IMPORTANT NOTE: Due to limitation of the C++ language, we have to
|
||||
// leave some internal implementation details in this header file.
|
||||
// They are clearly marked by comments like this:
|
||||
//
|
||||
// // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
||||
//
|
||||
// Such code is NOT meant to be used by a user directly, and is subject
|
||||
// to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user
|
||||
// program!
|
||||
|
||||
#ifndef GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
|
||||
#define GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
|
||||
// Ensures that there is at least one operator<< in the global namespace.
|
||||
// See Message& operator<<(...) below for why.
|
||||
void operator<<(const testing::internal::Secret&, int);
|
||||
|
||||
namespace testing {
|
||||
|
||||
// The Message class works like an ostream repeater.
|
||||
//
|
||||
// Typical usage:
|
||||
//
|
||||
// 1. You stream a bunch of values to a Message object.
|
||||
// It will remember the text in a stringstream.
|
||||
// 2. Then you stream the Message object to an ostream.
|
||||
// This causes the text in the Message to be streamed
|
||||
// to the ostream.
|
||||
//
|
||||
// For example;
|
||||
//
|
||||
// testing::Message foo;
|
||||
// foo << 1 << " != " << 2;
|
||||
// std::cout << foo;
|
||||
//
|
||||
// will print "1 != 2".
|
||||
//
|
||||
// Message is not intended to be inherited from. In particular, its
|
||||
// destructor is not virtual.
|
||||
//
|
||||
// Note that stringstream behaves differently in gcc and in MSVC. You
|
||||
// can stream a NULL char pointer to it in the former, but not in the
|
||||
// latter (it causes an access violation if you do). The Message
|
||||
// class hides this difference by treating a NULL char pointer as
|
||||
// "(null)".
|
||||
class GTEST_API_ Message {
|
||||
private:
|
||||
// The type of basic IO manipulators (endl, ends, and flush) for
|
||||
// narrow streams.
|
||||
typedef std::ostream& (*BasicNarrowIoManip)(std::ostream&);
|
||||
|
||||
public:
|
||||
// Constructs an empty Message.
|
||||
Message();
|
||||
|
||||
// Copy constructor.
|
||||
Message(const Message& msg) : ss_(new ::std::stringstream) { // NOLINT
|
||||
*ss_ << msg.GetString();
|
||||
}
|
||||
|
||||
// Constructs a Message from a C-string.
|
||||
explicit Message(const char* str) : ss_(new ::std::stringstream) {
|
||||
*ss_ << str;
|
||||
}
|
||||
|
||||
#if GTEST_OS_SYMBIAN
|
||||
// Streams a value (either a pointer or not) to this object.
|
||||
template <typename T>
|
||||
inline Message& operator <<(const T& value) {
|
||||
StreamHelper(typename internal::is_pointer<T>::type(), value);
|
||||
return *this;
|
||||
}
|
||||
#else
|
||||
// Streams a non-pointer value to this object.
|
||||
template <typename T>
|
||||
inline Message& operator <<(const T& val) {
|
||||
// Some libraries overload << for STL containers. These
|
||||
// overloads are defined in the global namespace instead of ::std.
|
||||
//
|
||||
// C++'s symbol lookup rule (i.e. Koenig lookup) says that these
|
||||
// overloads are visible in either the std namespace or the global
|
||||
// namespace, but not other namespaces, including the testing
|
||||
// namespace which Google Test's Message class is in.
|
||||
//
|
||||
// To allow STL containers (and other types that has a << operator
|
||||
// defined in the global namespace) to be used in Google Test
|
||||
// assertions, testing::Message must access the custom << operator
|
||||
// from the global namespace. With this using declaration,
|
||||
// overloads of << defined in the global namespace and those
|
||||
// visible via Koenig lookup are both exposed in this function.
|
||||
using ::operator <<;
|
||||
*ss_ << val;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Streams a pointer value to this object.
|
||||
//
|
||||
// This function is an overload of the previous one. When you
|
||||
// stream a pointer to a Message, this definition will be used as it
|
||||
// is more specialized. (The C++ Standard, section
|
||||
// [temp.func.order].) If you stream a non-pointer, then the
|
||||
// previous definition will be used.
|
||||
//
|
||||
// The reason for this overload is that streaming a NULL pointer to
|
||||
// ostream is undefined behavior. Depending on the compiler, you
|
||||
// may get "0", "(nil)", "(null)", or an access violation. To
|
||||
// ensure consistent result across compilers, we always treat NULL
|
||||
// as "(null)".
|
||||
template <typename T>
|
||||
inline Message& operator <<(T* const& pointer) { // NOLINT
|
||||
if (pointer == NULL) {
|
||||
*ss_ << "(null)";
|
||||
} else {
|
||||
*ss_ << pointer;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
#endif // GTEST_OS_SYMBIAN
|
||||
|
||||
// Since the basic IO manipulators are overloaded for both narrow
|
||||
// and wide streams, we have to provide this specialized definition
|
||||
// of operator <<, even though its body is the same as the
|
||||
// templatized version above. Without this definition, streaming
|
||||
// endl or other basic IO manipulators to Message will confuse the
|
||||
// compiler.
|
||||
Message& operator <<(BasicNarrowIoManip val) {
|
||||
*ss_ << val;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Instead of 1/0, we want to see true/false for bool values.
|
||||
Message& operator <<(bool b) {
|
||||
return *this << (b ? "true" : "false");
|
||||
}
|
||||
|
||||
// These two overloads allow streaming a wide C string to a Message
|
||||
// using the UTF-8 encoding.
|
||||
Message& operator <<(const wchar_t* wide_c_str);
|
||||
Message& operator <<(wchar_t* wide_c_str);
|
||||
|
||||
#if GTEST_HAS_STD_WSTRING
|
||||
// Converts the given wide string to a narrow string using the UTF-8
|
||||
// encoding, and streams the result to this Message object.
|
||||
Message& operator <<(const ::std::wstring& wstr);
|
||||
#endif // GTEST_HAS_STD_WSTRING
|
||||
|
||||
#if GTEST_HAS_GLOBAL_WSTRING
|
||||
// Converts the given wide string to a narrow string using the UTF-8
|
||||
// encoding, and streams the result to this Message object.
|
||||
Message& operator <<(const ::wstring& wstr);
|
||||
#endif // GTEST_HAS_GLOBAL_WSTRING
|
||||
|
||||
// Gets the text streamed to this object so far as an std::string.
|
||||
// Each '\0' character in the buffer is replaced with "\\0".
|
||||
//
|
||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
||||
std::string GetString() const;
|
||||
|
||||
private:
|
||||
|
||||
#if GTEST_OS_SYMBIAN
|
||||
// These are needed as the Nokia Symbian Compiler cannot decide between
|
||||
// const T& and const T* in a function template. The Nokia compiler _can_
|
||||
// decide between class template specializations for T and T*, so a
|
||||
// tr1::type_traits-like is_pointer works, and we can overload on that.
|
||||
template <typename T>
|
||||
inline void StreamHelper(internal::true_type /*is_pointer*/, T* pointer) {
|
||||
if (pointer == NULL) {
|
||||
*ss_ << "(null)";
|
||||
} else {
|
||||
*ss_ << pointer;
|
||||
}
|
||||
}
|
||||
template <typename T>
|
||||
inline void StreamHelper(internal::false_type /*is_pointer*/,
|
||||
const T& value) {
|
||||
// See the comments in Message& operator <<(const T&) above for why
|
||||
// we need this using statement.
|
||||
using ::operator <<;
|
||||
*ss_ << value;
|
||||
}
|
||||
#endif // GTEST_OS_SYMBIAN
|
||||
|
||||
// We'll hold the text streamed to this object here.
|
||||
const internal::scoped_ptr< ::std::stringstream> ss_;
|
||||
|
||||
// We declare (but don't implement) this to prevent the compiler
|
||||
// from implementing the assignment operator.
|
||||
void operator=(const Message&);
|
||||
};
|
||||
|
||||
// Streams a Message to an ostream.
|
||||
inline std::ostream& operator <<(std::ostream& os, const Message& sb) {
|
||||
return os << sb.GetString();
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
|
||||
// Converts a streamable value to an std::string. A NULL pointer is
|
||||
// converted to "(null)". When the input value is a ::string,
|
||||
// ::std::string, ::wstring, or ::std::wstring object, each NUL
|
||||
// character in it is replaced with "\\0".
|
||||
template <typename T>
|
||||
std::string StreamableToString(const T& streamable) {
|
||||
return (Message() << streamable).GetString();
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,487 +1,487 @@
|
||||
$$ -*- mode: c++; -*-
|
||||
$var n = 50 $$ Maximum length of Values arguments we want to support.
|
||||
$var maxtuple = 10 $$ Maximum number of Combine arguments we want to support.
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Authors: vladl@google.com (Vlad Losev)
|
||||
//
|
||||
// Macros and functions for implementing parameterized tests
|
||||
// in Google C++ Testing Framework (Google Test)
|
||||
//
|
||||
// This file is generated by a SCRIPT. DO NOT EDIT BY HAND!
|
||||
//
|
||||
#ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
|
||||
#define GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
|
||||
|
||||
|
||||
// Value-parameterized tests allow you to test your code with different
|
||||
// parameters without writing multiple copies of the same test.
|
||||
//
|
||||
// Here is how you use value-parameterized tests:
|
||||
|
||||
#if 0
|
||||
|
||||
// To write value-parameterized tests, first you should define a fixture
|
||||
// class. It is usually derived from testing::TestWithParam<T> (see below for
|
||||
// another inheritance scheme that's sometimes useful in more complicated
|
||||
// class hierarchies), where the type of your parameter values.
|
||||
// TestWithParam<T> is itself derived from testing::Test. T can be any
|
||||
// copyable type. If it's a raw pointer, you are responsible for managing the
|
||||
// lifespan of the pointed values.
|
||||
|
||||
class FooTest : public ::testing::TestWithParam<const char*> {
|
||||
// You can implement all the usual class fixture members here.
|
||||
};
|
||||
|
||||
// Then, use the TEST_P macro to define as many parameterized tests
|
||||
// for this fixture as you want. The _P suffix is for "parameterized"
|
||||
// or "pattern", whichever you prefer to think.
|
||||
|
||||
TEST_P(FooTest, DoesBlah) {
|
||||
// Inside a test, access the test parameter with the GetParam() method
|
||||
// of the TestWithParam<T> class:
|
||||
EXPECT_TRUE(foo.Blah(GetParam()));
|
||||
...
|
||||
}
|
||||
|
||||
TEST_P(FooTest, HasBlahBlah) {
|
||||
...
|
||||
}
|
||||
|
||||
// Finally, you can use INSTANTIATE_TEST_CASE_P to instantiate the test
|
||||
// case with any set of parameters you want. Google Test defines a number
|
||||
// of functions for generating test parameters. They return what we call
|
||||
// (surprise!) parameter generators. Here is a summary of them, which
|
||||
// are all in the testing namespace:
|
||||
//
|
||||
//
|
||||
// Range(begin, end [, step]) - Yields values {begin, begin+step,
|
||||
// begin+step+step, ...}. The values do not
|
||||
// include end. step defaults to 1.
|
||||
// Values(v1, v2, ..., vN) - Yields values {v1, v2, ..., vN}.
|
||||
// ValuesIn(container) - Yields values from a C-style array, an STL
|
||||
// ValuesIn(begin,end) container, or an iterator range [begin, end).
|
||||
// Bool() - Yields sequence {false, true}.
|
||||
// Combine(g1, g2, ..., gN) - Yields all combinations (the Cartesian product
|
||||
// for the math savvy) of the values generated
|
||||
// by the N generators.
|
||||
//
|
||||
// For more details, see comments at the definitions of these functions below
|
||||
// in this file.
|
||||
//
|
||||
// The following statement will instantiate tests from the FooTest test case
|
||||
// each with parameter values "meeny", "miny", and "moe".
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(InstantiationName,
|
||||
FooTest,
|
||||
Values("meeny", "miny", "moe"));
|
||||
|
||||
// To distinguish different instances of the pattern, (yes, you
|
||||
// can instantiate it more then once) the first argument to the
|
||||
// INSTANTIATE_TEST_CASE_P macro is a prefix that will be added to the
|
||||
// actual test case name. Remember to pick unique prefixes for different
|
||||
// instantiations. The tests from the instantiation above will have
|
||||
// these names:
|
||||
//
|
||||
// * InstantiationName/FooTest.DoesBlah/0 for "meeny"
|
||||
// * InstantiationName/FooTest.DoesBlah/1 for "miny"
|
||||
// * InstantiationName/FooTest.DoesBlah/2 for "moe"
|
||||
// * InstantiationName/FooTest.HasBlahBlah/0 for "meeny"
|
||||
// * InstantiationName/FooTest.HasBlahBlah/1 for "miny"
|
||||
// * InstantiationName/FooTest.HasBlahBlah/2 for "moe"
|
||||
//
|
||||
// You can use these names in --gtest_filter.
|
||||
//
|
||||
// This statement will instantiate all tests from FooTest again, each
|
||||
// with parameter values "cat" and "dog":
|
||||
|
||||
const char* pets[] = {"cat", "dog"};
|
||||
INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets));
|
||||
|
||||
// The tests from the instantiation above will have these names:
|
||||
//
|
||||
// * AnotherInstantiationName/FooTest.DoesBlah/0 for "cat"
|
||||
// * AnotherInstantiationName/FooTest.DoesBlah/1 for "dog"
|
||||
// * AnotherInstantiationName/FooTest.HasBlahBlah/0 for "cat"
|
||||
// * AnotherInstantiationName/FooTest.HasBlahBlah/1 for "dog"
|
||||
//
|
||||
// Please note that INSTANTIATE_TEST_CASE_P will instantiate all tests
|
||||
// in the given test case, whether their definitions come before or
|
||||
// AFTER the INSTANTIATE_TEST_CASE_P statement.
|
||||
//
|
||||
// Please also note that generator expressions (including parameters to the
|
||||
// generators) are evaluated in InitGoogleTest(), after main() has started.
|
||||
// This allows the user on one hand, to adjust generator parameters in order
|
||||
// to dynamically determine a set of tests to run and on the other hand,
|
||||
// give the user a chance to inspect the generated tests with Google Test
|
||||
// reflection API before RUN_ALL_TESTS() is executed.
|
||||
//
|
||||
// You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc
|
||||
// for more examples.
|
||||
//
|
||||
// In the future, we plan to publish the API for defining new parameter
|
||||
// generators. But for now this interface remains part of the internal
|
||||
// implementation and is subject to change.
|
||||
//
|
||||
//
|
||||
// A parameterized test fixture must be derived from testing::Test and from
|
||||
// testing::WithParamInterface<T>, where T is the type of the parameter
|
||||
// values. Inheriting from TestWithParam<T> satisfies that requirement because
|
||||
// TestWithParam<T> inherits from both Test and WithParamInterface. In more
|
||||
// complicated hierarchies, however, it is occasionally useful to inherit
|
||||
// separately from Test and WithParamInterface. For example:
|
||||
|
||||
class BaseTest : public ::testing::Test {
|
||||
// You can inherit all the usual members for a non-parameterized test
|
||||
// fixture here.
|
||||
};
|
||||
|
||||
class DerivedTest : public BaseTest, public ::testing::WithParamInterface<int> {
|
||||
// The usual test fixture members go here too.
|
||||
};
|
||||
|
||||
TEST_F(BaseTest, HasFoo) {
|
||||
// This is an ordinary non-parameterized test.
|
||||
}
|
||||
|
||||
TEST_P(DerivedTest, DoesBlah) {
|
||||
// GetParam works just the same here as if you inherit from TestWithParam.
|
||||
EXPECT_TRUE(foo.Blah(GetParam()));
|
||||
}
|
||||
|
||||
#endif // 0
|
||||
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
|
||||
#if !GTEST_OS_SYMBIAN
|
||||
# include <utility>
|
||||
#endif
|
||||
|
||||
// scripts/fuse_gtest.py depends on gtest's own header being #included
|
||||
// *unconditionally*. Therefore these #includes cannot be moved
|
||||
// inside #if GTEST_HAS_PARAM_TEST.
|
||||
#include "gtest/internal/gtest-internal.h"
|
||||
#include "gtest/internal/gtest-param-util.h"
|
||||
#include "gtest/internal/gtest-param-util-generated.h"
|
||||
|
||||
#if GTEST_HAS_PARAM_TEST
|
||||
|
||||
namespace testing {
|
||||
|
||||
// Functions producing parameter generators.
|
||||
//
|
||||
// Google Test uses these generators to produce parameters for value-
|
||||
// parameterized tests. When a parameterized test case is instantiated
|
||||
// with a particular generator, Google Test creates and runs tests
|
||||
// for each element in the sequence produced by the generator.
|
||||
//
|
||||
// In the following sample, tests from test case FooTest are instantiated
|
||||
// each three times with parameter values 3, 5, and 8:
|
||||
//
|
||||
// class FooTest : public TestWithParam<int> { ... };
|
||||
//
|
||||
// TEST_P(FooTest, TestThis) {
|
||||
// }
|
||||
// TEST_P(FooTest, TestThat) {
|
||||
// }
|
||||
// INSTANTIATE_TEST_CASE_P(TestSequence, FooTest, Values(3, 5, 8));
|
||||
//
|
||||
|
||||
// Range() returns generators providing sequences of values in a range.
|
||||
//
|
||||
// Synopsis:
|
||||
// Range(start, end)
|
||||
// - returns a generator producing a sequence of values {start, start+1,
|
||||
// start+2, ..., }.
|
||||
// Range(start, end, step)
|
||||
// - returns a generator producing a sequence of values {start, start+step,
|
||||
// start+step+step, ..., }.
|
||||
// Notes:
|
||||
// * The generated sequences never include end. For example, Range(1, 5)
|
||||
// returns a generator producing a sequence {1, 2, 3, 4}. Range(1, 9, 2)
|
||||
// returns a generator producing {1, 3, 5, 7}.
|
||||
// * start and end must have the same type. That type may be any integral or
|
||||
// floating-point type or a user defined type satisfying these conditions:
|
||||
// * It must be assignable (have operator=() defined).
|
||||
// * It must have operator+() (operator+(int-compatible type) for
|
||||
// two-operand version).
|
||||
// * It must have operator<() defined.
|
||||
// Elements in the resulting sequences will also have that type.
|
||||
// * Condition start < end must be satisfied in order for resulting sequences
|
||||
// to contain any elements.
|
||||
//
|
||||
template <typename T, typename IncrementT>
|
||||
internal::ParamGenerator<T> Range(T start, T end, IncrementT step) {
|
||||
return internal::ParamGenerator<T>(
|
||||
new internal::RangeGenerator<T, IncrementT>(start, end, step));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
internal::ParamGenerator<T> Range(T start, T end) {
|
||||
return Range(start, end, 1);
|
||||
}
|
||||
|
||||
// ValuesIn() function allows generation of tests with parameters coming from
|
||||
// a container.
|
||||
//
|
||||
// Synopsis:
|
||||
// ValuesIn(const T (&array)[N])
|
||||
// - returns a generator producing sequences with elements from
|
||||
// a C-style array.
|
||||
// ValuesIn(const Container& container)
|
||||
// - returns a generator producing sequences with elements from
|
||||
// an STL-style container.
|
||||
// ValuesIn(Iterator begin, Iterator end)
|
||||
// - returns a generator producing sequences with elements from
|
||||
// a range [begin, end) defined by a pair of STL-style iterators. These
|
||||
// iterators can also be plain C pointers.
|
||||
//
|
||||
// Please note that ValuesIn copies the values from the containers
|
||||
// passed in and keeps them to generate tests in RUN_ALL_TESTS().
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// This instantiates tests from test case StringTest
|
||||
// each with C-string values of "foo", "bar", and "baz":
|
||||
//
|
||||
// const char* strings[] = {"foo", "bar", "baz"};
|
||||
// INSTANTIATE_TEST_CASE_P(StringSequence, SrtingTest, ValuesIn(strings));
|
||||
//
|
||||
// This instantiates tests from test case StlStringTest
|
||||
// each with STL strings with values "a" and "b":
|
||||
//
|
||||
// ::std::vector< ::std::string> GetParameterStrings() {
|
||||
// ::std::vector< ::std::string> v;
|
||||
// v.push_back("a");
|
||||
// v.push_back("b");
|
||||
// return v;
|
||||
// }
|
||||
//
|
||||
// INSTANTIATE_TEST_CASE_P(CharSequence,
|
||||
// StlStringTest,
|
||||
// ValuesIn(GetParameterStrings()));
|
||||
//
|
||||
//
|
||||
// This will also instantiate tests from CharTest
|
||||
// each with parameter values 'a' and 'b':
|
||||
//
|
||||
// ::std::list<char> GetParameterChars() {
|
||||
// ::std::list<char> list;
|
||||
// list.push_back('a');
|
||||
// list.push_back('b');
|
||||
// return list;
|
||||
// }
|
||||
// ::std::list<char> l = GetParameterChars();
|
||||
// INSTANTIATE_TEST_CASE_P(CharSequence2,
|
||||
// CharTest,
|
||||
// ValuesIn(l.begin(), l.end()));
|
||||
//
|
||||
template <typename ForwardIterator>
|
||||
internal::ParamGenerator<
|
||||
typename ::testing::internal::IteratorTraits<ForwardIterator>::value_type>
|
||||
ValuesIn(ForwardIterator begin, ForwardIterator end) {
|
||||
typedef typename ::testing::internal::IteratorTraits<ForwardIterator>
|
||||
::value_type ParamType;
|
||||
return internal::ParamGenerator<ParamType>(
|
||||
new internal::ValuesInIteratorRangeGenerator<ParamType>(begin, end));
|
||||
}
|
||||
|
||||
template <typename T, size_t N>
|
||||
internal::ParamGenerator<T> ValuesIn(const T (&array)[N]) {
|
||||
return ValuesIn(array, array + N);
|
||||
}
|
||||
|
||||
template <class Container>
|
||||
internal::ParamGenerator<typename Container::value_type> ValuesIn(
|
||||
const Container& container) {
|
||||
return ValuesIn(container.begin(), container.end());
|
||||
}
|
||||
|
||||
// Values() allows generating tests from explicitly specified list of
|
||||
// parameters.
|
||||
//
|
||||
// Synopsis:
|
||||
// Values(T v1, T v2, ..., T vN)
|
||||
// - returns a generator producing sequences with elements v1, v2, ..., vN.
|
||||
//
|
||||
// For example, this instantiates tests from test case BarTest each
|
||||
// with values "one", "two", and "three":
|
||||
//
|
||||
// INSTANTIATE_TEST_CASE_P(NumSequence, BarTest, Values("one", "two", "three"));
|
||||
//
|
||||
// This instantiates tests from test case BazTest each with values 1, 2, 3.5.
|
||||
// The exact type of values will depend on the type of parameter in BazTest.
|
||||
//
|
||||
// INSTANTIATE_TEST_CASE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5));
|
||||
//
|
||||
// Currently, Values() supports from 1 to $n parameters.
|
||||
//
|
||||
$range i 1..n
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
|
||||
template <$for j, [[typename T$j]]>
|
||||
internal::ValueArray$i<$for j, [[T$j]]> Values($for j, [[T$j v$j]]) {
|
||||
return internal::ValueArray$i<$for j, [[T$j]]>($for j, [[v$j]]);
|
||||
}
|
||||
|
||||
]]
|
||||
|
||||
// Bool() allows generating tests with parameters in a set of (false, true).
|
||||
//
|
||||
// Synopsis:
|
||||
// Bool()
|
||||
// - returns a generator producing sequences with elements {false, true}.
|
||||
//
|
||||
// It is useful when testing code that depends on Boolean flags. Combinations
|
||||
// of multiple flags can be tested when several Bool()'s are combined using
|
||||
// Combine() function.
|
||||
//
|
||||
// In the following example all tests in the test case FlagDependentTest
|
||||
// will be instantiated twice with parameters false and true.
|
||||
//
|
||||
// class FlagDependentTest : public testing::TestWithParam<bool> {
|
||||
// virtual void SetUp() {
|
||||
// external_flag = GetParam();
|
||||
// }
|
||||
// }
|
||||
// INSTANTIATE_TEST_CASE_P(BoolSequence, FlagDependentTest, Bool());
|
||||
//
|
||||
inline internal::ParamGenerator<bool> Bool() {
|
||||
return Values(false, true);
|
||||
}
|
||||
|
||||
# if GTEST_HAS_COMBINE
|
||||
// Combine() allows the user to combine two or more sequences to produce
|
||||
// values of a Cartesian product of those sequences' elements.
|
||||
//
|
||||
// Synopsis:
|
||||
// Combine(gen1, gen2, ..., genN)
|
||||
// - returns a generator producing sequences with elements coming from
|
||||
// the Cartesian product of elements from the sequences generated by
|
||||
// gen1, gen2, ..., genN. The sequence elements will have a type of
|
||||
// tuple<T1, T2, ..., TN> where T1, T2, ..., TN are the types
|
||||
// of elements from sequences produces by gen1, gen2, ..., genN.
|
||||
//
|
||||
// Combine can have up to $maxtuple arguments. This number is currently limited
|
||||
// by the maximum number of elements in the tuple implementation used by Google
|
||||
// Test.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// This will instantiate tests in test case AnimalTest each one with
|
||||
// the parameter values tuple("cat", BLACK), tuple("cat", WHITE),
|
||||
// tuple("dog", BLACK), and tuple("dog", WHITE):
|
||||
//
|
||||
// enum Color { BLACK, GRAY, WHITE };
|
||||
// class AnimalTest
|
||||
// : public testing::TestWithParam<tuple<const char*, Color> > {...};
|
||||
//
|
||||
// TEST_P(AnimalTest, AnimalLooksNice) {...}
|
||||
//
|
||||
// INSTANTIATE_TEST_CASE_P(AnimalVariations, AnimalTest,
|
||||
// Combine(Values("cat", "dog"),
|
||||
// Values(BLACK, WHITE)));
|
||||
//
|
||||
// This will instantiate tests in FlagDependentTest with all variations of two
|
||||
// Boolean flags:
|
||||
//
|
||||
// class FlagDependentTest
|
||||
// : public testing::TestWithParam<tuple<bool, bool> > {
|
||||
// virtual void SetUp() {
|
||||
// // Assigns external_flag_1 and external_flag_2 values from the tuple.
|
||||
// tie(external_flag_1, external_flag_2) = GetParam();
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// TEST_P(FlagDependentTest, TestFeature1) {
|
||||
// // Test your code using external_flag_1 and external_flag_2 here.
|
||||
// }
|
||||
// INSTANTIATE_TEST_CASE_P(TwoBoolSequence, FlagDependentTest,
|
||||
// Combine(Bool(), Bool()));
|
||||
//
|
||||
$range i 2..maxtuple
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
|
||||
template <$for j, [[typename Generator$j]]>
|
||||
internal::CartesianProductHolder$i<$for j, [[Generator$j]]> Combine(
|
||||
$for j, [[const Generator$j& g$j]]) {
|
||||
return internal::CartesianProductHolder$i<$for j, [[Generator$j]]>(
|
||||
$for j, [[g$j]]);
|
||||
}
|
||||
|
||||
]]
|
||||
# endif // GTEST_HAS_COMBINE
|
||||
|
||||
|
||||
|
||||
# define TEST_P(test_case_name, test_name) \
|
||||
class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \
|
||||
: public test_case_name { \
|
||||
public: \
|
||||
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {} \
|
||||
virtual void TestBody(); \
|
||||
private: \
|
||||
static int AddToRegistry() { \
|
||||
::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
|
||||
GetTestCasePatternHolder<test_case_name>(\
|
||||
#test_case_name, __FILE__, __LINE__)->AddTestPattern(\
|
||||
#test_case_name, \
|
||||
#test_name, \
|
||||
new ::testing::internal::TestMetaFactory< \
|
||||
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>()); \
|
||||
return 0; \
|
||||
} \
|
||||
static int gtest_registering_dummy_; \
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(\
|
||||
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \
|
||||
}; \
|
||||
int GTEST_TEST_CLASS_NAME_(test_case_name, \
|
||||
test_name)::gtest_registering_dummy_ = \
|
||||
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry(); \
|
||||
void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()
|
||||
|
||||
# define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \
|
||||
::testing::internal::ParamGenerator<test_case_name::ParamType> \
|
||||
gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \
|
||||
int gtest_##prefix##test_case_name##_dummy_ = \
|
||||
::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
|
||||
GetTestCasePatternHolder<test_case_name>(\
|
||||
#test_case_name, __FILE__, __LINE__)->AddTestCaseInstantiation(\
|
||||
#prefix, \
|
||||
>est_##prefix##test_case_name##_EvalGenerator_, \
|
||||
__FILE__, __LINE__)
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GTEST_HAS_PARAM_TEST
|
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
|
||||
$$ -*- mode: c++; -*-
|
||||
$var n = 50 $$ Maximum length of Values arguments we want to support.
|
||||
$var maxtuple = 10 $$ Maximum number of Combine arguments we want to support.
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Authors: vladl@google.com (Vlad Losev)
|
||||
//
|
||||
// Macros and functions for implementing parameterized tests
|
||||
// in Google C++ Testing Framework (Google Test)
|
||||
//
|
||||
// This file is generated by a SCRIPT. DO NOT EDIT BY HAND!
|
||||
//
|
||||
#ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
|
||||
#define GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
|
||||
|
||||
|
||||
// Value-parameterized tests allow you to test your code with different
|
||||
// parameters without writing multiple copies of the same test.
|
||||
//
|
||||
// Here is how you use value-parameterized tests:
|
||||
|
||||
#if 0
|
||||
|
||||
// To write value-parameterized tests, first you should define a fixture
|
||||
// class. It is usually derived from testing::TestWithParam<T> (see below for
|
||||
// another inheritance scheme that's sometimes useful in more complicated
|
||||
// class hierarchies), where the type of your parameter values.
|
||||
// TestWithParam<T> is itself derived from testing::Test. T can be any
|
||||
// copyable type. If it's a raw pointer, you are responsible for managing the
|
||||
// lifespan of the pointed values.
|
||||
|
||||
class FooTest : public ::testing::TestWithParam<const char*> {
|
||||
// You can implement all the usual class fixture members here.
|
||||
};
|
||||
|
||||
// Then, use the TEST_P macro to define as many parameterized tests
|
||||
// for this fixture as you want. The _P suffix is for "parameterized"
|
||||
// or "pattern", whichever you prefer to think.
|
||||
|
||||
TEST_P(FooTest, DoesBlah) {
|
||||
// Inside a test, access the test parameter with the GetParam() method
|
||||
// of the TestWithParam<T> class:
|
||||
EXPECT_TRUE(foo.Blah(GetParam()));
|
||||
...
|
||||
}
|
||||
|
||||
TEST_P(FooTest, HasBlahBlah) {
|
||||
...
|
||||
}
|
||||
|
||||
// Finally, you can use INSTANTIATE_TEST_CASE_P to instantiate the test
|
||||
// case with any set of parameters you want. Google Test defines a number
|
||||
// of functions for generating test parameters. They return what we call
|
||||
// (surprise!) parameter generators. Here is a summary of them, which
|
||||
// are all in the testing namespace:
|
||||
//
|
||||
//
|
||||
// Range(begin, end [, step]) - Yields values {begin, begin+step,
|
||||
// begin+step+step, ...}. The values do not
|
||||
// include end. step defaults to 1.
|
||||
// Values(v1, v2, ..., vN) - Yields values {v1, v2, ..., vN}.
|
||||
// ValuesIn(container) - Yields values from a C-style array, an STL
|
||||
// ValuesIn(begin,end) container, or an iterator range [begin, end).
|
||||
// Bool() - Yields sequence {false, true}.
|
||||
// Combine(g1, g2, ..., gN) - Yields all combinations (the Cartesian product
|
||||
// for the math savvy) of the values generated
|
||||
// by the N generators.
|
||||
//
|
||||
// For more details, see comments at the definitions of these functions below
|
||||
// in this file.
|
||||
//
|
||||
// The following statement will instantiate tests from the FooTest test case
|
||||
// each with parameter values "meeny", "miny", and "moe".
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(InstantiationName,
|
||||
FooTest,
|
||||
Values("meeny", "miny", "moe"));
|
||||
|
||||
// To distinguish different instances of the pattern, (yes, you
|
||||
// can instantiate it more then once) the first argument to the
|
||||
// INSTANTIATE_TEST_CASE_P macro is a prefix that will be added to the
|
||||
// actual test case name. Remember to pick unique prefixes for different
|
||||
// instantiations. The tests from the instantiation above will have
|
||||
// these names:
|
||||
//
|
||||
// * InstantiationName/FooTest.DoesBlah/0 for "meeny"
|
||||
// * InstantiationName/FooTest.DoesBlah/1 for "miny"
|
||||
// * InstantiationName/FooTest.DoesBlah/2 for "moe"
|
||||
// * InstantiationName/FooTest.HasBlahBlah/0 for "meeny"
|
||||
// * InstantiationName/FooTest.HasBlahBlah/1 for "miny"
|
||||
// * InstantiationName/FooTest.HasBlahBlah/2 for "moe"
|
||||
//
|
||||
// You can use these names in --gtest_filter.
|
||||
//
|
||||
// This statement will instantiate all tests from FooTest again, each
|
||||
// with parameter values "cat" and "dog":
|
||||
|
||||
const char* pets[] = {"cat", "dog"};
|
||||
INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets));
|
||||
|
||||
// The tests from the instantiation above will have these names:
|
||||
//
|
||||
// * AnotherInstantiationName/FooTest.DoesBlah/0 for "cat"
|
||||
// * AnotherInstantiationName/FooTest.DoesBlah/1 for "dog"
|
||||
// * AnotherInstantiationName/FooTest.HasBlahBlah/0 for "cat"
|
||||
// * AnotherInstantiationName/FooTest.HasBlahBlah/1 for "dog"
|
||||
//
|
||||
// Please note that INSTANTIATE_TEST_CASE_P will instantiate all tests
|
||||
// in the given test case, whether their definitions come before or
|
||||
// AFTER the INSTANTIATE_TEST_CASE_P statement.
|
||||
//
|
||||
// Please also note that generator expressions (including parameters to the
|
||||
// generators) are evaluated in InitGoogleTest(), after main() has started.
|
||||
// This allows the user on one hand, to adjust generator parameters in order
|
||||
// to dynamically determine a set of tests to run and on the other hand,
|
||||
// give the user a chance to inspect the generated tests with Google Test
|
||||
// reflection API before RUN_ALL_TESTS() is executed.
|
||||
//
|
||||
// You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc
|
||||
// for more examples.
|
||||
//
|
||||
// In the future, we plan to publish the API for defining new parameter
|
||||
// generators. But for now this interface remains part of the internal
|
||||
// implementation and is subject to change.
|
||||
//
|
||||
//
|
||||
// A parameterized test fixture must be derived from testing::Test and from
|
||||
// testing::WithParamInterface<T>, where T is the type of the parameter
|
||||
// values. Inheriting from TestWithParam<T> satisfies that requirement because
|
||||
// TestWithParam<T> inherits from both Test and WithParamInterface. In more
|
||||
// complicated hierarchies, however, it is occasionally useful to inherit
|
||||
// separately from Test and WithParamInterface. For example:
|
||||
|
||||
class BaseTest : public ::testing::Test {
|
||||
// You can inherit all the usual members for a non-parameterized test
|
||||
// fixture here.
|
||||
};
|
||||
|
||||
class DerivedTest : public BaseTest, public ::testing::WithParamInterface<int> {
|
||||
// The usual test fixture members go here too.
|
||||
};
|
||||
|
||||
TEST_F(BaseTest, HasFoo) {
|
||||
// This is an ordinary non-parameterized test.
|
||||
}
|
||||
|
||||
TEST_P(DerivedTest, DoesBlah) {
|
||||
// GetParam works just the same here as if you inherit from TestWithParam.
|
||||
EXPECT_TRUE(foo.Blah(GetParam()));
|
||||
}
|
||||
|
||||
#endif // 0
|
||||
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
|
||||
#if !GTEST_OS_SYMBIAN
|
||||
# include <utility>
|
||||
#endif
|
||||
|
||||
// scripts/fuse_gtest.py depends on gtest's own header being #included
|
||||
// *unconditionally*. Therefore these #includes cannot be moved
|
||||
// inside #if GTEST_HAS_PARAM_TEST.
|
||||
#include "gtest/internal/gtest-internal.h"
|
||||
#include "gtest/internal/gtest-param-util.h"
|
||||
#include "gtest/internal/gtest-param-util-generated.h"
|
||||
|
||||
#if GTEST_HAS_PARAM_TEST
|
||||
|
||||
namespace testing {
|
||||
|
||||
// Functions producing parameter generators.
|
||||
//
|
||||
// Google Test uses these generators to produce parameters for value-
|
||||
// parameterized tests. When a parameterized test case is instantiated
|
||||
// with a particular generator, Google Test creates and runs tests
|
||||
// for each element in the sequence produced by the generator.
|
||||
//
|
||||
// In the following sample, tests from test case FooTest are instantiated
|
||||
// each three times with parameter values 3, 5, and 8:
|
||||
//
|
||||
// class FooTest : public TestWithParam<int> { ... };
|
||||
//
|
||||
// TEST_P(FooTest, TestThis) {
|
||||
// }
|
||||
// TEST_P(FooTest, TestThat) {
|
||||
// }
|
||||
// INSTANTIATE_TEST_CASE_P(TestSequence, FooTest, Values(3, 5, 8));
|
||||
//
|
||||
|
||||
// Range() returns generators providing sequences of values in a range.
|
||||
//
|
||||
// Synopsis:
|
||||
// Range(start, end)
|
||||
// - returns a generator producing a sequence of values {start, start+1,
|
||||
// start+2, ..., }.
|
||||
// Range(start, end, step)
|
||||
// - returns a generator producing a sequence of values {start, start+step,
|
||||
// start+step+step, ..., }.
|
||||
// Notes:
|
||||
// * The generated sequences never include end. For example, Range(1, 5)
|
||||
// returns a generator producing a sequence {1, 2, 3, 4}. Range(1, 9, 2)
|
||||
// returns a generator producing {1, 3, 5, 7}.
|
||||
// * start and end must have the same type. That type may be any integral or
|
||||
// floating-point type or a user defined type satisfying these conditions:
|
||||
// * It must be assignable (have operator=() defined).
|
||||
// * It must have operator+() (operator+(int-compatible type) for
|
||||
// two-operand version).
|
||||
// * It must have operator<() defined.
|
||||
// Elements in the resulting sequences will also have that type.
|
||||
// * Condition start < end must be satisfied in order for resulting sequences
|
||||
// to contain any elements.
|
||||
//
|
||||
template <typename T, typename IncrementT>
|
||||
internal::ParamGenerator<T> Range(T start, T end, IncrementT step) {
|
||||
return internal::ParamGenerator<T>(
|
||||
new internal::RangeGenerator<T, IncrementT>(start, end, step));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
internal::ParamGenerator<T> Range(T start, T end) {
|
||||
return Range(start, end, 1);
|
||||
}
|
||||
|
||||
// ValuesIn() function allows generation of tests with parameters coming from
|
||||
// a container.
|
||||
//
|
||||
// Synopsis:
|
||||
// ValuesIn(const T (&array)[N])
|
||||
// - returns a generator producing sequences with elements from
|
||||
// a C-style array.
|
||||
// ValuesIn(const Container& container)
|
||||
// - returns a generator producing sequences with elements from
|
||||
// an STL-style container.
|
||||
// ValuesIn(Iterator begin, Iterator end)
|
||||
// - returns a generator producing sequences with elements from
|
||||
// a range [begin, end) defined by a pair of STL-style iterators. These
|
||||
// iterators can also be plain C pointers.
|
||||
//
|
||||
// Please note that ValuesIn copies the values from the containers
|
||||
// passed in and keeps them to generate tests in RUN_ALL_TESTS().
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// This instantiates tests from test case StringTest
|
||||
// each with C-string values of "foo", "bar", and "baz":
|
||||
//
|
||||
// const char* strings[] = {"foo", "bar", "baz"};
|
||||
// INSTANTIATE_TEST_CASE_P(StringSequence, SrtingTest, ValuesIn(strings));
|
||||
//
|
||||
// This instantiates tests from test case StlStringTest
|
||||
// each with STL strings with values "a" and "b":
|
||||
//
|
||||
// ::std::vector< ::std::string> GetParameterStrings() {
|
||||
// ::std::vector< ::std::string> v;
|
||||
// v.push_back("a");
|
||||
// v.push_back("b");
|
||||
// return v;
|
||||
// }
|
||||
//
|
||||
// INSTANTIATE_TEST_CASE_P(CharSequence,
|
||||
// StlStringTest,
|
||||
// ValuesIn(GetParameterStrings()));
|
||||
//
|
||||
//
|
||||
// This will also instantiate tests from CharTest
|
||||
// each with parameter values 'a' and 'b':
|
||||
//
|
||||
// ::std::list<char> GetParameterChars() {
|
||||
// ::std::list<char> list;
|
||||
// list.push_back('a');
|
||||
// list.push_back('b');
|
||||
// return list;
|
||||
// }
|
||||
// ::std::list<char> l = GetParameterChars();
|
||||
// INSTANTIATE_TEST_CASE_P(CharSequence2,
|
||||
// CharTest,
|
||||
// ValuesIn(l.begin(), l.end()));
|
||||
//
|
||||
template <typename ForwardIterator>
|
||||
internal::ParamGenerator<
|
||||
typename ::testing::internal::IteratorTraits<ForwardIterator>::value_type>
|
||||
ValuesIn(ForwardIterator begin, ForwardIterator end) {
|
||||
typedef typename ::testing::internal::IteratorTraits<ForwardIterator>
|
||||
::value_type ParamType;
|
||||
return internal::ParamGenerator<ParamType>(
|
||||
new internal::ValuesInIteratorRangeGenerator<ParamType>(begin, end));
|
||||
}
|
||||
|
||||
template <typename T, size_t N>
|
||||
internal::ParamGenerator<T> ValuesIn(const T (&array)[N]) {
|
||||
return ValuesIn(array, array + N);
|
||||
}
|
||||
|
||||
template <class Container>
|
||||
internal::ParamGenerator<typename Container::value_type> ValuesIn(
|
||||
const Container& container) {
|
||||
return ValuesIn(container.begin(), container.end());
|
||||
}
|
||||
|
||||
// Values() allows generating tests from explicitly specified list of
|
||||
// parameters.
|
||||
//
|
||||
// Synopsis:
|
||||
// Values(T v1, T v2, ..., T vN)
|
||||
// - returns a generator producing sequences with elements v1, v2, ..., vN.
|
||||
//
|
||||
// For example, this instantiates tests from test case BarTest each
|
||||
// with values "one", "two", and "three":
|
||||
//
|
||||
// INSTANTIATE_TEST_CASE_P(NumSequence, BarTest, Values("one", "two", "three"));
|
||||
//
|
||||
// This instantiates tests from test case BazTest each with values 1, 2, 3.5.
|
||||
// The exact type of values will depend on the type of parameter in BazTest.
|
||||
//
|
||||
// INSTANTIATE_TEST_CASE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5));
|
||||
//
|
||||
// Currently, Values() supports from 1 to $n parameters.
|
||||
//
|
||||
$range i 1..n
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
|
||||
template <$for j, [[typename T$j]]>
|
||||
internal::ValueArray$i<$for j, [[T$j]]> Values($for j, [[T$j v$j]]) {
|
||||
return internal::ValueArray$i<$for j, [[T$j]]>($for j, [[v$j]]);
|
||||
}
|
||||
|
||||
]]
|
||||
|
||||
// Bool() allows generating tests with parameters in a set of (false, true).
|
||||
//
|
||||
// Synopsis:
|
||||
// Bool()
|
||||
// - returns a generator producing sequences with elements {false, true}.
|
||||
//
|
||||
// It is useful when testing code that depends on Boolean flags. Combinations
|
||||
// of multiple flags can be tested when several Bool()'s are combined using
|
||||
// Combine() function.
|
||||
//
|
||||
// In the following example all tests in the test case FlagDependentTest
|
||||
// will be instantiated twice with parameters false and true.
|
||||
//
|
||||
// class FlagDependentTest : public testing::TestWithParam<bool> {
|
||||
// virtual void SetUp() {
|
||||
// external_flag = GetParam();
|
||||
// }
|
||||
// }
|
||||
// INSTANTIATE_TEST_CASE_P(BoolSequence, FlagDependentTest, Bool());
|
||||
//
|
||||
inline internal::ParamGenerator<bool> Bool() {
|
||||
return Values(false, true);
|
||||
}
|
||||
|
||||
# if GTEST_HAS_COMBINE
|
||||
// Combine() allows the user to combine two or more sequences to produce
|
||||
// values of a Cartesian product of those sequences' elements.
|
||||
//
|
||||
// Synopsis:
|
||||
// Combine(gen1, gen2, ..., genN)
|
||||
// - returns a generator producing sequences with elements coming from
|
||||
// the Cartesian product of elements from the sequences generated by
|
||||
// gen1, gen2, ..., genN. The sequence elements will have a type of
|
||||
// tuple<T1, T2, ..., TN> where T1, T2, ..., TN are the types
|
||||
// of elements from sequences produces by gen1, gen2, ..., genN.
|
||||
//
|
||||
// Combine can have up to $maxtuple arguments. This number is currently limited
|
||||
// by the maximum number of elements in the tuple implementation used by Google
|
||||
// Test.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// This will instantiate tests in test case AnimalTest each one with
|
||||
// the parameter values tuple("cat", BLACK), tuple("cat", WHITE),
|
||||
// tuple("dog", BLACK), and tuple("dog", WHITE):
|
||||
//
|
||||
// enum Color { BLACK, GRAY, WHITE };
|
||||
// class AnimalTest
|
||||
// : public testing::TestWithParam<tuple<const char*, Color> > {...};
|
||||
//
|
||||
// TEST_P(AnimalTest, AnimalLooksNice) {...}
|
||||
//
|
||||
// INSTANTIATE_TEST_CASE_P(AnimalVariations, AnimalTest,
|
||||
// Combine(Values("cat", "dog"),
|
||||
// Values(BLACK, WHITE)));
|
||||
//
|
||||
// This will instantiate tests in FlagDependentTest with all variations of two
|
||||
// Boolean flags:
|
||||
//
|
||||
// class FlagDependentTest
|
||||
// : public testing::TestWithParam<tuple<bool, bool> > {
|
||||
// virtual void SetUp() {
|
||||
// // Assigns external_flag_1 and external_flag_2 values from the tuple.
|
||||
// tie(external_flag_1, external_flag_2) = GetParam();
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// TEST_P(FlagDependentTest, TestFeature1) {
|
||||
// // Test your code using external_flag_1 and external_flag_2 here.
|
||||
// }
|
||||
// INSTANTIATE_TEST_CASE_P(TwoBoolSequence, FlagDependentTest,
|
||||
// Combine(Bool(), Bool()));
|
||||
//
|
||||
$range i 2..maxtuple
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
|
||||
template <$for j, [[typename Generator$j]]>
|
||||
internal::CartesianProductHolder$i<$for j, [[Generator$j]]> Combine(
|
||||
$for j, [[const Generator$j& g$j]]) {
|
||||
return internal::CartesianProductHolder$i<$for j, [[Generator$j]]>(
|
||||
$for j, [[g$j]]);
|
||||
}
|
||||
|
||||
]]
|
||||
# endif // GTEST_HAS_COMBINE
|
||||
|
||||
|
||||
|
||||
# define TEST_P(test_case_name, test_name) \
|
||||
class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \
|
||||
: public test_case_name { \
|
||||
public: \
|
||||
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {} \
|
||||
virtual void TestBody(); \
|
||||
private: \
|
||||
static int AddToRegistry() { \
|
||||
::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
|
||||
GetTestCasePatternHolder<test_case_name>(\
|
||||
#test_case_name, __FILE__, __LINE__)->AddTestPattern(\
|
||||
#test_case_name, \
|
||||
#test_name, \
|
||||
new ::testing::internal::TestMetaFactory< \
|
||||
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>()); \
|
||||
return 0; \
|
||||
} \
|
||||
static int gtest_registering_dummy_; \
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(\
|
||||
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \
|
||||
}; \
|
||||
int GTEST_TEST_CLASS_NAME_(test_case_name, \
|
||||
test_name)::gtest_registering_dummy_ = \
|
||||
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry(); \
|
||||
void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()
|
||||
|
||||
# define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \
|
||||
::testing::internal::ParamGenerator<test_case_name::ParamType> \
|
||||
gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \
|
||||
int gtest_##prefix##test_case_name##_dummy_ = \
|
||||
::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
|
||||
GetTestCasePatternHolder<test_case_name>(\
|
||||
#test_case_name, __FILE__, __LINE__)->AddTestCaseInstantiation(\
|
||||
#prefix, \
|
||||
>est_##prefix##test_case_name##_EvalGenerator_, \
|
||||
__FILE__, __LINE__)
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GTEST_HAS_PARAM_TEST
|
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,232 +1,232 @@
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
//
|
||||
// Utilities for testing Google Test itself and code that uses Google Test
|
||||
// (e.g. frameworks built on top of Google Test).
|
||||
|
||||
#ifndef GTEST_INCLUDE_GTEST_GTEST_SPI_H_
|
||||
#define GTEST_INCLUDE_GTEST_GTEST_SPI_H_
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace testing {
|
||||
|
||||
// This helper class can be used to mock out Google Test failure reporting
|
||||
// so that we can test Google Test or code that builds on Google Test.
|
||||
//
|
||||
// An object of this class appends a TestPartResult object to the
|
||||
// TestPartResultArray object given in the constructor whenever a Google Test
|
||||
// failure is reported. It can either intercept only failures that are
|
||||
// generated in the same thread that created this object or it can intercept
|
||||
// all generated failures. The scope of this mock object can be controlled with
|
||||
// the second argument to the two arguments constructor.
|
||||
class GTEST_API_ ScopedFakeTestPartResultReporter
|
||||
: public TestPartResultReporterInterface {
|
||||
public:
|
||||
// The two possible mocking modes of this object.
|
||||
enum InterceptMode {
|
||||
INTERCEPT_ONLY_CURRENT_THREAD, // Intercepts only thread local failures.
|
||||
INTERCEPT_ALL_THREADS // Intercepts all failures.
|
||||
};
|
||||
|
||||
// The c'tor sets this object as the test part result reporter used
|
||||
// by Google Test. The 'result' parameter specifies where to report the
|
||||
// results. This reporter will only catch failures generated in the current
|
||||
// thread. DEPRECATED
|
||||
explicit ScopedFakeTestPartResultReporter(TestPartResultArray* result);
|
||||
|
||||
// Same as above, but you can choose the interception scope of this object.
|
||||
ScopedFakeTestPartResultReporter(InterceptMode intercept_mode,
|
||||
TestPartResultArray* result);
|
||||
|
||||
// The d'tor restores the previous test part result reporter.
|
||||
virtual ~ScopedFakeTestPartResultReporter();
|
||||
|
||||
// Appends the TestPartResult object to the TestPartResultArray
|
||||
// received in the constructor.
|
||||
//
|
||||
// This method is from the TestPartResultReporterInterface
|
||||
// interface.
|
||||
virtual void ReportTestPartResult(const TestPartResult& result);
|
||||
private:
|
||||
void Init();
|
||||
|
||||
const InterceptMode intercept_mode_;
|
||||
TestPartResultReporterInterface* old_reporter_;
|
||||
TestPartResultArray* const result_;
|
||||
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedFakeTestPartResultReporter);
|
||||
};
|
||||
|
||||
namespace internal {
|
||||
|
||||
// A helper class for implementing EXPECT_FATAL_FAILURE() and
|
||||
// EXPECT_NONFATAL_FAILURE(). Its destructor verifies that the given
|
||||
// TestPartResultArray contains exactly one failure that has the given
|
||||
// type and contains the given substring. If that's not the case, a
|
||||
// non-fatal failure will be generated.
|
||||
class GTEST_API_ SingleFailureChecker {
|
||||
public:
|
||||
// The constructor remembers the arguments.
|
||||
SingleFailureChecker(const TestPartResultArray* results,
|
||||
TestPartResult::Type type,
|
||||
const string& substr);
|
||||
~SingleFailureChecker();
|
||||
private:
|
||||
const TestPartResultArray* const results_;
|
||||
const TestPartResult::Type type_;
|
||||
const string substr_;
|
||||
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker);
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
} // namespace testing
|
||||
|
||||
// A set of macros for testing Google Test assertions or code that's expected
|
||||
// to generate Google Test fatal failures. It verifies that the given
|
||||
// statement will cause exactly one fatal Google Test failure with 'substr'
|
||||
// being part of the failure message.
|
||||
//
|
||||
// There are two different versions of this macro. EXPECT_FATAL_FAILURE only
|
||||
// affects and considers failures generated in the current thread and
|
||||
// EXPECT_FATAL_FAILURE_ON_ALL_THREADS does the same but for all threads.
|
||||
//
|
||||
// The verification of the assertion is done correctly even when the statement
|
||||
// throws an exception or aborts the current function.
|
||||
//
|
||||
// Known restrictions:
|
||||
// - 'statement' cannot reference local non-static variables or
|
||||
// non-static members of the current object.
|
||||
// - 'statement' cannot return a value.
|
||||
// - You cannot stream a failure message to this macro.
|
||||
//
|
||||
// Note that even though the implementations of the following two
|
||||
// macros are much alike, we cannot refactor them to use a common
|
||||
// helper macro, due to some peculiarity in how the preprocessor
|
||||
// works. The AcceptsMacroThatExpandsToUnprotectedComma test in
|
||||
// gtest_unittest.cc will fail to compile if we do that.
|
||||
#define EXPECT_FATAL_FAILURE(statement, substr) \
|
||||
do { \
|
||||
class GTestExpectFatalFailureHelper {\
|
||||
public:\
|
||||
static void Execute() { statement; }\
|
||||
};\
|
||||
::testing::TestPartResultArray gtest_failures;\
|
||||
::testing::internal::SingleFailureChecker gtest_checker(\
|
||||
>est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\
|
||||
{\
|
||||
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
|
||||
::testing::ScopedFakeTestPartResultReporter:: \
|
||||
INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\
|
||||
GTestExpectFatalFailureHelper::Execute();\
|
||||
}\
|
||||
} while (::testing::internal::AlwaysFalse())
|
||||
|
||||
#define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \
|
||||
do { \
|
||||
class GTestExpectFatalFailureHelper {\
|
||||
public:\
|
||||
static void Execute() { statement; }\
|
||||
};\
|
||||
::testing::TestPartResultArray gtest_failures;\
|
||||
::testing::internal::SingleFailureChecker gtest_checker(\
|
||||
>est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\
|
||||
{\
|
||||
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
|
||||
::testing::ScopedFakeTestPartResultReporter:: \
|
||||
INTERCEPT_ALL_THREADS, >est_failures);\
|
||||
GTestExpectFatalFailureHelper::Execute();\
|
||||
}\
|
||||
} while (::testing::internal::AlwaysFalse())
|
||||
|
||||
// A macro for testing Google Test assertions or code that's expected to
|
||||
// generate Google Test non-fatal failures. It asserts that the given
|
||||
// statement will cause exactly one non-fatal Google Test failure with 'substr'
|
||||
// being part of the failure message.
|
||||
//
|
||||
// There are two different versions of this macro. EXPECT_NONFATAL_FAILURE only
|
||||
// affects and considers failures generated in the current thread and
|
||||
// EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS does the same but for all threads.
|
||||
//
|
||||
// 'statement' is allowed to reference local variables and members of
|
||||
// the current object.
|
||||
//
|
||||
// The verification of the assertion is done correctly even when the statement
|
||||
// throws an exception or aborts the current function.
|
||||
//
|
||||
// Known restrictions:
|
||||
// - You cannot stream a failure message to this macro.
|
||||
//
|
||||
// Note that even though the implementations of the following two
|
||||
// macros are much alike, we cannot refactor them to use a common
|
||||
// helper macro, due to some peculiarity in how the preprocessor
|
||||
// works. If we do that, the code won't compile when the user gives
|
||||
// EXPECT_NONFATAL_FAILURE() a statement that contains a macro that
|
||||
// expands to code containing an unprotected comma. The
|
||||
// AcceptsMacroThatExpandsToUnprotectedComma test in gtest_unittest.cc
|
||||
// catches that.
|
||||
//
|
||||
// For the same reason, we have to write
|
||||
// if (::testing::internal::AlwaysTrue()) { statement; }
|
||||
// instead of
|
||||
// GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement)
|
||||
// to avoid an MSVC warning on unreachable code.
|
||||
#define EXPECT_NONFATAL_FAILURE(statement, substr) \
|
||||
do {\
|
||||
::testing::TestPartResultArray gtest_failures;\
|
||||
::testing::internal::SingleFailureChecker gtest_checker(\
|
||||
>est_failures, ::testing::TestPartResult::kNonFatalFailure, \
|
||||
(substr));\
|
||||
{\
|
||||
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
|
||||
::testing::ScopedFakeTestPartResultReporter:: \
|
||||
INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\
|
||||
if (::testing::internal::AlwaysTrue()) { statement; }\
|
||||
}\
|
||||
} while (::testing::internal::AlwaysFalse())
|
||||
|
||||
#define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \
|
||||
do {\
|
||||
::testing::TestPartResultArray gtest_failures;\
|
||||
::testing::internal::SingleFailureChecker gtest_checker(\
|
||||
>est_failures, ::testing::TestPartResult::kNonFatalFailure, \
|
||||
(substr));\
|
||||
{\
|
||||
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
|
||||
::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, \
|
||||
>est_failures);\
|
||||
if (::testing::internal::AlwaysTrue()) { statement; }\
|
||||
}\
|
||||
} while (::testing::internal::AlwaysFalse())
|
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_GTEST_SPI_H_
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
//
|
||||
// Utilities for testing Google Test itself and code that uses Google Test
|
||||
// (e.g. frameworks built on top of Google Test).
|
||||
|
||||
#ifndef GTEST_INCLUDE_GTEST_GTEST_SPI_H_
|
||||
#define GTEST_INCLUDE_GTEST_GTEST_SPI_H_
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace testing {
|
||||
|
||||
// This helper class can be used to mock out Google Test failure reporting
|
||||
// so that we can test Google Test or code that builds on Google Test.
|
||||
//
|
||||
// An object of this class appends a TestPartResult object to the
|
||||
// TestPartResultArray object given in the constructor whenever a Google Test
|
||||
// failure is reported. It can either intercept only failures that are
|
||||
// generated in the same thread that created this object or it can intercept
|
||||
// all generated failures. The scope of this mock object can be controlled with
|
||||
// the second argument to the two arguments constructor.
|
||||
class GTEST_API_ ScopedFakeTestPartResultReporter
|
||||
: public TestPartResultReporterInterface {
|
||||
public:
|
||||
// The two possible mocking modes of this object.
|
||||
enum InterceptMode {
|
||||
INTERCEPT_ONLY_CURRENT_THREAD, // Intercepts only thread local failures.
|
||||
INTERCEPT_ALL_THREADS // Intercepts all failures.
|
||||
};
|
||||
|
||||
// The c'tor sets this object as the test part result reporter used
|
||||
// by Google Test. The 'result' parameter specifies where to report the
|
||||
// results. This reporter will only catch failures generated in the current
|
||||
// thread. DEPRECATED
|
||||
explicit ScopedFakeTestPartResultReporter(TestPartResultArray* result);
|
||||
|
||||
// Same as above, but you can choose the interception scope of this object.
|
||||
ScopedFakeTestPartResultReporter(InterceptMode intercept_mode,
|
||||
TestPartResultArray* result);
|
||||
|
||||
// The d'tor restores the previous test part result reporter.
|
||||
virtual ~ScopedFakeTestPartResultReporter();
|
||||
|
||||
// Appends the TestPartResult object to the TestPartResultArray
|
||||
// received in the constructor.
|
||||
//
|
||||
// This method is from the TestPartResultReporterInterface
|
||||
// interface.
|
||||
virtual void ReportTestPartResult(const TestPartResult& result);
|
||||
private:
|
||||
void Init();
|
||||
|
||||
const InterceptMode intercept_mode_;
|
||||
TestPartResultReporterInterface* old_reporter_;
|
||||
TestPartResultArray* const result_;
|
||||
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedFakeTestPartResultReporter);
|
||||
};
|
||||
|
||||
namespace internal {
|
||||
|
||||
// A helper class for implementing EXPECT_FATAL_FAILURE() and
|
||||
// EXPECT_NONFATAL_FAILURE(). Its destructor verifies that the given
|
||||
// TestPartResultArray contains exactly one failure that has the given
|
||||
// type and contains the given substring. If that's not the case, a
|
||||
// non-fatal failure will be generated.
|
||||
class GTEST_API_ SingleFailureChecker {
|
||||
public:
|
||||
// The constructor remembers the arguments.
|
||||
SingleFailureChecker(const TestPartResultArray* results,
|
||||
TestPartResult::Type type,
|
||||
const string& substr);
|
||||
~SingleFailureChecker();
|
||||
private:
|
||||
const TestPartResultArray* const results_;
|
||||
const TestPartResult::Type type_;
|
||||
const string substr_;
|
||||
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker);
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
} // namespace testing
|
||||
|
||||
// A set of macros for testing Google Test assertions or code that's expected
|
||||
// to generate Google Test fatal failures. It verifies that the given
|
||||
// statement will cause exactly one fatal Google Test failure with 'substr'
|
||||
// being part of the failure message.
|
||||
//
|
||||
// There are two different versions of this macro. EXPECT_FATAL_FAILURE only
|
||||
// affects and considers failures generated in the current thread and
|
||||
// EXPECT_FATAL_FAILURE_ON_ALL_THREADS does the same but for all threads.
|
||||
//
|
||||
// The verification of the assertion is done correctly even when the statement
|
||||
// throws an exception or aborts the current function.
|
||||
//
|
||||
// Known restrictions:
|
||||
// - 'statement' cannot reference local non-static variables or
|
||||
// non-static members of the current object.
|
||||
// - 'statement' cannot return a value.
|
||||
// - You cannot stream a failure message to this macro.
|
||||
//
|
||||
// Note that even though the implementations of the following two
|
||||
// macros are much alike, we cannot refactor them to use a common
|
||||
// helper macro, due to some peculiarity in how the preprocessor
|
||||
// works. The AcceptsMacroThatExpandsToUnprotectedComma test in
|
||||
// gtest_unittest.cc will fail to compile if we do that.
|
||||
#define EXPECT_FATAL_FAILURE(statement, substr) \
|
||||
do { \
|
||||
class GTestExpectFatalFailureHelper {\
|
||||
public:\
|
||||
static void Execute() { statement; }\
|
||||
};\
|
||||
::testing::TestPartResultArray gtest_failures;\
|
||||
::testing::internal::SingleFailureChecker gtest_checker(\
|
||||
>est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\
|
||||
{\
|
||||
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
|
||||
::testing::ScopedFakeTestPartResultReporter:: \
|
||||
INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\
|
||||
GTestExpectFatalFailureHelper::Execute();\
|
||||
}\
|
||||
} while (::testing::internal::AlwaysFalse())
|
||||
|
||||
#define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \
|
||||
do { \
|
||||
class GTestExpectFatalFailureHelper {\
|
||||
public:\
|
||||
static void Execute() { statement; }\
|
||||
};\
|
||||
::testing::TestPartResultArray gtest_failures;\
|
||||
::testing::internal::SingleFailureChecker gtest_checker(\
|
||||
>est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\
|
||||
{\
|
||||
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
|
||||
::testing::ScopedFakeTestPartResultReporter:: \
|
||||
INTERCEPT_ALL_THREADS, >est_failures);\
|
||||
GTestExpectFatalFailureHelper::Execute();\
|
||||
}\
|
||||
} while (::testing::internal::AlwaysFalse())
|
||||
|
||||
// A macro for testing Google Test assertions or code that's expected to
|
||||
// generate Google Test non-fatal failures. It asserts that the given
|
||||
// statement will cause exactly one non-fatal Google Test failure with 'substr'
|
||||
// being part of the failure message.
|
||||
//
|
||||
// There are two different versions of this macro. EXPECT_NONFATAL_FAILURE only
|
||||
// affects and considers failures generated in the current thread and
|
||||
// EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS does the same but for all threads.
|
||||
//
|
||||
// 'statement' is allowed to reference local variables and members of
|
||||
// the current object.
|
||||
//
|
||||
// The verification of the assertion is done correctly even when the statement
|
||||
// throws an exception or aborts the current function.
|
||||
//
|
||||
// Known restrictions:
|
||||
// - You cannot stream a failure message to this macro.
|
||||
//
|
||||
// Note that even though the implementations of the following two
|
||||
// macros are much alike, we cannot refactor them to use a common
|
||||
// helper macro, due to some peculiarity in how the preprocessor
|
||||
// works. If we do that, the code won't compile when the user gives
|
||||
// EXPECT_NONFATAL_FAILURE() a statement that contains a macro that
|
||||
// expands to code containing an unprotected comma. The
|
||||
// AcceptsMacroThatExpandsToUnprotectedComma test in gtest_unittest.cc
|
||||
// catches that.
|
||||
//
|
||||
// For the same reason, we have to write
|
||||
// if (::testing::internal::AlwaysTrue()) { statement; }
|
||||
// instead of
|
||||
// GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement)
|
||||
// to avoid an MSVC warning on unreachable code.
|
||||
#define EXPECT_NONFATAL_FAILURE(statement, substr) \
|
||||
do {\
|
||||
::testing::TestPartResultArray gtest_failures;\
|
||||
::testing::internal::SingleFailureChecker gtest_checker(\
|
||||
>est_failures, ::testing::TestPartResult::kNonFatalFailure, \
|
||||
(substr));\
|
||||
{\
|
||||
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
|
||||
::testing::ScopedFakeTestPartResultReporter:: \
|
||||
INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\
|
||||
if (::testing::internal::AlwaysTrue()) { statement; }\
|
||||
}\
|
||||
} while (::testing::internal::AlwaysFalse())
|
||||
|
||||
#define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \
|
||||
do {\
|
||||
::testing::TestPartResultArray gtest_failures;\
|
||||
::testing::internal::SingleFailureChecker gtest_checker(\
|
||||
>est_failures, ::testing::TestPartResult::kNonFatalFailure, \
|
||||
(substr));\
|
||||
{\
|
||||
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
|
||||
::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, \
|
||||
>est_failures);\
|
||||
if (::testing::internal::AlwaysTrue()) { statement; }\
|
||||
}\
|
||||
} while (::testing::internal::AlwaysFalse())
|
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_GTEST_SPI_H_
|
||||
@@ -1,179 +1,179 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: mheule@google.com (Markus Heule)
|
||||
//
|
||||
|
||||
#ifndef GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
|
||||
#define GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
|
||||
|
||||
#include <iosfwd>
|
||||
#include <vector>
|
||||
#include "gtest/internal/gtest-internal.h"
|
||||
#include "gtest/internal/gtest-string.h"
|
||||
|
||||
namespace testing {
|
||||
|
||||
// A copyable object representing the result of a test part (i.e. an
|
||||
// assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()).
|
||||
//
|
||||
// Don't inherit from TestPartResult as its destructor is not virtual.
|
||||
class GTEST_API_ TestPartResult {
|
||||
public:
|
||||
// The possible outcomes of a test part (i.e. an assertion or an
|
||||
// explicit SUCCEED(), FAIL(), or ADD_FAILURE()).
|
||||
enum Type {
|
||||
kSuccess, // Succeeded.
|
||||
kNonFatalFailure, // Failed but the test can continue.
|
||||
kFatalFailure // Failed and the test should be terminated.
|
||||
};
|
||||
|
||||
// C'tor. TestPartResult does NOT have a default constructor.
|
||||
// Always use this constructor (with parameters) to create a
|
||||
// TestPartResult object.
|
||||
TestPartResult(Type a_type,
|
||||
const char* a_file_name,
|
||||
int a_line_number,
|
||||
const char* a_message)
|
||||
: type_(a_type),
|
||||
file_name_(a_file_name == NULL ? "" : a_file_name),
|
||||
line_number_(a_line_number),
|
||||
summary_(ExtractSummary(a_message)),
|
||||
message_(a_message) {
|
||||
}
|
||||
|
||||
// Gets the outcome of the test part.
|
||||
Type type() const { return type_; }
|
||||
|
||||
// Gets the name of the source file where the test part took place, or
|
||||
// NULL if it's unknown.
|
||||
const char* file_name() const {
|
||||
return file_name_.empty() ? NULL : file_name_.c_str();
|
||||
}
|
||||
|
||||
// Gets the line in the source file where the test part took place,
|
||||
// or -1 if it's unknown.
|
||||
int line_number() const { return line_number_; }
|
||||
|
||||
// Gets the summary of the failure message.
|
||||
const char* summary() const { return summary_.c_str(); }
|
||||
|
||||
// Gets the message associated with the test part.
|
||||
const char* message() const { return message_.c_str(); }
|
||||
|
||||
// Returns true iff the test part passed.
|
||||
bool passed() const { return type_ == kSuccess; }
|
||||
|
||||
// Returns true iff the test part failed.
|
||||
bool failed() const { return type_ != kSuccess; }
|
||||
|
||||
// Returns true iff the test part non-fatally failed.
|
||||
bool nonfatally_failed() const { return type_ == kNonFatalFailure; }
|
||||
|
||||
// Returns true iff the test part fatally failed.
|
||||
bool fatally_failed() const { return type_ == kFatalFailure; }
|
||||
|
||||
private:
|
||||
Type type_;
|
||||
|
||||
// Gets the summary of the failure message by omitting the stack
|
||||
// trace in it.
|
||||
static std::string ExtractSummary(const char* message);
|
||||
|
||||
// The name of the source file where the test part took place, or
|
||||
// "" if the source file is unknown.
|
||||
std::string file_name_;
|
||||
// The line in the source file where the test part took place, or -1
|
||||
// if the line number is unknown.
|
||||
int line_number_;
|
||||
std::string summary_; // The test failure summary.
|
||||
std::string message_; // The test failure message.
|
||||
};
|
||||
|
||||
// Prints a TestPartResult object.
|
||||
std::ostream& operator<<(std::ostream& os, const TestPartResult& result);
|
||||
|
||||
// An array of TestPartResult objects.
|
||||
//
|
||||
// Don't inherit from TestPartResultArray as its destructor is not
|
||||
// virtual.
|
||||
class GTEST_API_ TestPartResultArray {
|
||||
public:
|
||||
TestPartResultArray() {}
|
||||
|
||||
// Appends the given TestPartResult to the array.
|
||||
void Append(const TestPartResult& result);
|
||||
|
||||
// Returns the TestPartResult at the given index (0-based).
|
||||
const TestPartResult& GetTestPartResult(int index) const;
|
||||
|
||||
// Returns the number of TestPartResult objects in the array.
|
||||
int size() const;
|
||||
|
||||
private:
|
||||
std::vector<TestPartResult> array_;
|
||||
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray);
|
||||
};
|
||||
|
||||
// This interface knows how to report a test part result.
|
||||
class TestPartResultReporterInterface {
|
||||
public:
|
||||
virtual ~TestPartResultReporterInterface() {}
|
||||
|
||||
virtual void ReportTestPartResult(const TestPartResult& result) = 0;
|
||||
};
|
||||
|
||||
namespace internal {
|
||||
|
||||
// This helper class is used by {ASSERT|EXPECT}_NO_FATAL_FAILURE to check if a
|
||||
// statement generates new fatal failures. To do so it registers itself as the
|
||||
// current test part result reporter. Besides checking if fatal failures were
|
||||
// reported, it only delegates the reporting to the former result reporter.
|
||||
// The original result reporter is restored in the destructor.
|
||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
||||
class GTEST_API_ HasNewFatalFailureHelper
|
||||
: public TestPartResultReporterInterface {
|
||||
public:
|
||||
HasNewFatalFailureHelper();
|
||||
virtual ~HasNewFatalFailureHelper();
|
||||
virtual void ReportTestPartResult(const TestPartResult& result);
|
||||
bool has_new_fatal_failure() const { return has_new_fatal_failure_; }
|
||||
private:
|
||||
bool has_new_fatal_failure_;
|
||||
TestPartResultReporterInterface* original_reporter_;
|
||||
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(HasNewFatalFailureHelper);
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: mheule@google.com (Markus Heule)
|
||||
//
|
||||
|
||||
#ifndef GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
|
||||
#define GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
|
||||
|
||||
#include <iosfwd>
|
||||
#include <vector>
|
||||
#include "gtest/internal/gtest-internal.h"
|
||||
#include "gtest/internal/gtest-string.h"
|
||||
|
||||
namespace testing {
|
||||
|
||||
// A copyable object representing the result of a test part (i.e. an
|
||||
// assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()).
|
||||
//
|
||||
// Don't inherit from TestPartResult as its destructor is not virtual.
|
||||
class GTEST_API_ TestPartResult {
|
||||
public:
|
||||
// The possible outcomes of a test part (i.e. an assertion or an
|
||||
// explicit SUCCEED(), FAIL(), or ADD_FAILURE()).
|
||||
enum Type {
|
||||
kSuccess, // Succeeded.
|
||||
kNonFatalFailure, // Failed but the test can continue.
|
||||
kFatalFailure // Failed and the test should be terminated.
|
||||
};
|
||||
|
||||
// C'tor. TestPartResult does NOT have a default constructor.
|
||||
// Always use this constructor (with parameters) to create a
|
||||
// TestPartResult object.
|
||||
TestPartResult(Type a_type,
|
||||
const char* a_file_name,
|
||||
int a_line_number,
|
||||
const char* a_message)
|
||||
: type_(a_type),
|
||||
file_name_(a_file_name == NULL ? "" : a_file_name),
|
||||
line_number_(a_line_number),
|
||||
summary_(ExtractSummary(a_message)),
|
||||
message_(a_message) {
|
||||
}
|
||||
|
||||
// Gets the outcome of the test part.
|
||||
Type type() const { return type_; }
|
||||
|
||||
// Gets the name of the source file where the test part took place, or
|
||||
// NULL if it's unknown.
|
||||
const char* file_name() const {
|
||||
return file_name_.empty() ? NULL : file_name_.c_str();
|
||||
}
|
||||
|
||||
// Gets the line in the source file where the test part took place,
|
||||
// or -1 if it's unknown.
|
||||
int line_number() const { return line_number_; }
|
||||
|
||||
// Gets the summary of the failure message.
|
||||
const char* summary() const { return summary_.c_str(); }
|
||||
|
||||
// Gets the message associated with the test part.
|
||||
const char* message() const { return message_.c_str(); }
|
||||
|
||||
// Returns true iff the test part passed.
|
||||
bool passed() const { return type_ == kSuccess; }
|
||||
|
||||
// Returns true iff the test part failed.
|
||||
bool failed() const { return type_ != kSuccess; }
|
||||
|
||||
// Returns true iff the test part non-fatally failed.
|
||||
bool nonfatally_failed() const { return type_ == kNonFatalFailure; }
|
||||
|
||||
// Returns true iff the test part fatally failed.
|
||||
bool fatally_failed() const { return type_ == kFatalFailure; }
|
||||
|
||||
private:
|
||||
Type type_;
|
||||
|
||||
// Gets the summary of the failure message by omitting the stack
|
||||
// trace in it.
|
||||
static std::string ExtractSummary(const char* message);
|
||||
|
||||
// The name of the source file where the test part took place, or
|
||||
// "" if the source file is unknown.
|
||||
std::string file_name_;
|
||||
// The line in the source file where the test part took place, or -1
|
||||
// if the line number is unknown.
|
||||
int line_number_;
|
||||
std::string summary_; // The test failure summary.
|
||||
std::string message_; // The test failure message.
|
||||
};
|
||||
|
||||
// Prints a TestPartResult object.
|
||||
std::ostream& operator<<(std::ostream& os, const TestPartResult& result);
|
||||
|
||||
// An array of TestPartResult objects.
|
||||
//
|
||||
// Don't inherit from TestPartResultArray as its destructor is not
|
||||
// virtual.
|
||||
class GTEST_API_ TestPartResultArray {
|
||||
public:
|
||||
TestPartResultArray() {}
|
||||
|
||||
// Appends the given TestPartResult to the array.
|
||||
void Append(const TestPartResult& result);
|
||||
|
||||
// Returns the TestPartResult at the given index (0-based).
|
||||
const TestPartResult& GetTestPartResult(int index) const;
|
||||
|
||||
// Returns the number of TestPartResult objects in the array.
|
||||
int size() const;
|
||||
|
||||
private:
|
||||
std::vector<TestPartResult> array_;
|
||||
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray);
|
||||
};
|
||||
|
||||
// This interface knows how to report a test part result.
|
||||
class TestPartResultReporterInterface {
|
||||
public:
|
||||
virtual ~TestPartResultReporterInterface() {}
|
||||
|
||||
virtual void ReportTestPartResult(const TestPartResult& result) = 0;
|
||||
};
|
||||
|
||||
namespace internal {
|
||||
|
||||
// This helper class is used by {ASSERT|EXPECT}_NO_FATAL_FAILURE to check if a
|
||||
// statement generates new fatal failures. To do so it registers itself as the
|
||||
// current test part result reporter. Besides checking if fatal failures were
|
||||
// reported, it only delegates the reporting to the former result reporter.
|
||||
// The original result reporter is restored in the destructor.
|
||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
||||
class GTEST_API_ HasNewFatalFailureHelper
|
||||
: public TestPartResultReporterInterface {
|
||||
public:
|
||||
HasNewFatalFailureHelper();
|
||||
virtual ~HasNewFatalFailureHelper();
|
||||
virtual void ReportTestPartResult(const TestPartResult& result);
|
||||
bool has_new_fatal_failure() const { return has_new_fatal_failure_; }
|
||||
private:
|
||||
bool has_new_fatal_failure_;
|
||||
TestPartResultReporterInterface* original_reporter_;
|
||||
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(HasNewFatalFailureHelper);
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
|
||||
@@ -1,259 +1,259 @@
|
||||
// Copyright 2008 Google Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
#ifndef GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
|
||||
#define GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
|
||||
|
||||
// This header implements typed tests and type-parameterized tests.
|
||||
|
||||
// Typed (aka type-driven) tests repeat the same test for types in a
|
||||
// list. You must know which types you want to test with when writing
|
||||
// typed tests. Here's how you do it:
|
||||
|
||||
#if 0
|
||||
|
||||
// First, define a fixture class template. It should be parameterized
|
||||
// by a type. Remember to derive it from testing::Test.
|
||||
template <typename T>
|
||||
class FooTest : public testing::Test {
|
||||
public:
|
||||
...
|
||||
typedef std::list<T> List;
|
||||
static T shared_;
|
||||
T value_;
|
||||
};
|
||||
|
||||
// Next, associate a list of types with the test case, which will be
|
||||
// repeated for each type in the list. The typedef is necessary for
|
||||
// the macro to parse correctly.
|
||||
typedef testing::Types<char, int, unsigned int> MyTypes;
|
||||
TYPED_TEST_CASE(FooTest, MyTypes);
|
||||
|
||||
// If the type list contains only one type, you can write that type
|
||||
// directly without Types<...>:
|
||||
// TYPED_TEST_CASE(FooTest, int);
|
||||
|
||||
// Then, use TYPED_TEST() instead of TEST_F() to define as many typed
|
||||
// tests for this test case as you want.
|
||||
TYPED_TEST(FooTest, DoesBlah) {
|
||||
// Inside a test, refer to TypeParam to get the type parameter.
|
||||
// Since we are inside a derived class template, C++ requires use to
|
||||
// visit the members of FooTest via 'this'.
|
||||
TypeParam n = this->value_;
|
||||
|
||||
// To visit static members of the fixture, add the TestFixture::
|
||||
// prefix.
|
||||
n += TestFixture::shared_;
|
||||
|
||||
// To refer to typedefs in the fixture, add the "typename
|
||||
// TestFixture::" prefix.
|
||||
typename TestFixture::List values;
|
||||
values.push_back(n);
|
||||
...
|
||||
}
|
||||
|
||||
TYPED_TEST(FooTest, HasPropertyA) { ... }
|
||||
|
||||
#endif // 0
|
||||
|
||||
// Type-parameterized tests are abstract test patterns parameterized
|
||||
// by a type. Compared with typed tests, type-parameterized tests
|
||||
// allow you to define the test pattern without knowing what the type
|
||||
// parameters are. The defined pattern can be instantiated with
|
||||
// different types any number of times, in any number of translation
|
||||
// units.
|
||||
//
|
||||
// If you are designing an interface or concept, you can define a
|
||||
// suite of type-parameterized tests to verify properties that any
|
||||
// valid implementation of the interface/concept should have. Then,
|
||||
// each implementation can easily instantiate the test suite to verify
|
||||
// that it conforms to the requirements, without having to write
|
||||
// similar tests repeatedly. Here's an example:
|
||||
|
||||
#if 0
|
||||
|
||||
// First, define a fixture class template. It should be parameterized
|
||||
// by a type. Remember to derive it from testing::Test.
|
||||
template <typename T>
|
||||
class FooTest : public testing::Test {
|
||||
...
|
||||
};
|
||||
|
||||
// Next, declare that you will define a type-parameterized test case
|
||||
// (the _P suffix is for "parameterized" or "pattern", whichever you
|
||||
// prefer):
|
||||
TYPED_TEST_CASE_P(FooTest);
|
||||
|
||||
// Then, use TYPED_TEST_P() to define as many type-parameterized tests
|
||||
// for this type-parameterized test case as you want.
|
||||
TYPED_TEST_P(FooTest, DoesBlah) {
|
||||
// Inside a test, refer to TypeParam to get the type parameter.
|
||||
TypeParam n = 0;
|
||||
...
|
||||
}
|
||||
|
||||
TYPED_TEST_P(FooTest, HasPropertyA) { ... }
|
||||
|
||||
// Now the tricky part: you need to register all test patterns before
|
||||
// you can instantiate them. The first argument of the macro is the
|
||||
// test case name; the rest are the names of the tests in this test
|
||||
// case.
|
||||
REGISTER_TYPED_TEST_CASE_P(FooTest,
|
||||
DoesBlah, HasPropertyA);
|
||||
|
||||
// Finally, you are free to instantiate the pattern with the types you
|
||||
// want. If you put the above code in a header file, you can #include
|
||||
// it in multiple C++ source files and instantiate it multiple times.
|
||||
//
|
||||
// To distinguish different instances of the pattern, the first
|
||||
// argument to the INSTANTIATE_* macro is a prefix that will be added
|
||||
// to the actual test case name. Remember to pick unique prefixes for
|
||||
// different instances.
|
||||
typedef testing::Types<char, int, unsigned int> MyTypes;
|
||||
INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes);
|
||||
|
||||
// If the type list contains only one type, you can write that type
|
||||
// directly without Types<...>:
|
||||
// INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, int);
|
||||
|
||||
#endif // 0
|
||||
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
#include "gtest/internal/gtest-type-util.h"
|
||||
|
||||
// Implements typed tests.
|
||||
|
||||
#if GTEST_HAS_TYPED_TEST
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||
//
|
||||
// Expands to the name of the typedef for the type parameters of the
|
||||
// given test case.
|
||||
# define GTEST_TYPE_PARAMS_(TestCaseName) gtest_type_params_##TestCaseName##_
|
||||
|
||||
// The 'Types' template argument below must have spaces around it
|
||||
// since some compilers may choke on '>>' when passing a template
|
||||
// instance (e.g. Types<int>)
|
||||
# define TYPED_TEST_CASE(CaseName, Types) \
|
||||
typedef ::testing::internal::TypeList< Types >::type \
|
||||
GTEST_TYPE_PARAMS_(CaseName)
|
||||
|
||||
# define TYPED_TEST(CaseName, TestName) \
|
||||
template <typename gtest_TypeParam_> \
|
||||
class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \
|
||||
: public CaseName<gtest_TypeParam_> { \
|
||||
private: \
|
||||
typedef CaseName<gtest_TypeParam_> TestFixture; \
|
||||
typedef gtest_TypeParam_ TypeParam; \
|
||||
virtual void TestBody(); \
|
||||
}; \
|
||||
bool gtest_##CaseName##_##TestName##_registered_ GTEST_ATTRIBUTE_UNUSED_ = \
|
||||
::testing::internal::TypeParameterizedTest< \
|
||||
CaseName, \
|
||||
::testing::internal::TemplateSel< \
|
||||
GTEST_TEST_CLASS_NAME_(CaseName, TestName)>, \
|
||||
GTEST_TYPE_PARAMS_(CaseName)>::Register(\
|
||||
"", #CaseName, #TestName, 0); \
|
||||
template <typename gtest_TypeParam_> \
|
||||
void GTEST_TEST_CLASS_NAME_(CaseName, TestName)<gtest_TypeParam_>::TestBody()
|
||||
|
||||
#endif // GTEST_HAS_TYPED_TEST
|
||||
|
||||
// Implements type-parameterized tests.
|
||||
|
||||
#if GTEST_HAS_TYPED_TEST_P
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||
//
|
||||
// Expands to the namespace name that the type-parameterized tests for
|
||||
// the given type-parameterized test case are defined in. The exact
|
||||
// name of the namespace is subject to change without notice.
|
||||
# define GTEST_CASE_NAMESPACE_(TestCaseName) \
|
||||
gtest_case_##TestCaseName##_
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||
//
|
||||
// Expands to the name of the variable used to remember the names of
|
||||
// the defined tests in the given test case.
|
||||
# define GTEST_TYPED_TEST_CASE_P_STATE_(TestCaseName) \
|
||||
gtest_typed_test_case_p_state_##TestCaseName##_
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY.
|
||||
//
|
||||
// Expands to the name of the variable used to remember the names of
|
||||
// the registered tests in the given test case.
|
||||
# define GTEST_REGISTERED_TEST_NAMES_(TestCaseName) \
|
||||
gtest_registered_test_names_##TestCaseName##_
|
||||
|
||||
// The variables defined in the type-parameterized test macros are
|
||||
// static as typically these macros are used in a .h file that can be
|
||||
// #included in multiple translation units linked together.
|
||||
# define TYPED_TEST_CASE_P(CaseName) \
|
||||
static ::testing::internal::TypedTestCasePState \
|
||||
GTEST_TYPED_TEST_CASE_P_STATE_(CaseName)
|
||||
|
||||
# define TYPED_TEST_P(CaseName, TestName) \
|
||||
namespace GTEST_CASE_NAMESPACE_(CaseName) { \
|
||||
template <typename gtest_TypeParam_> \
|
||||
class TestName : public CaseName<gtest_TypeParam_> { \
|
||||
private: \
|
||||
typedef CaseName<gtest_TypeParam_> TestFixture; \
|
||||
typedef gtest_TypeParam_ TypeParam; \
|
||||
virtual void TestBody(); \
|
||||
}; \
|
||||
static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \
|
||||
GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).AddTestName(\
|
||||
__FILE__, __LINE__, #CaseName, #TestName); \
|
||||
} \
|
||||
template <typename gtest_TypeParam_> \
|
||||
void GTEST_CASE_NAMESPACE_(CaseName)::TestName<gtest_TypeParam_>::TestBody()
|
||||
|
||||
# define REGISTER_TYPED_TEST_CASE_P(CaseName, ...) \
|
||||
namespace GTEST_CASE_NAMESPACE_(CaseName) { \
|
||||
typedef ::testing::internal::Templates<__VA_ARGS__>::type gtest_AllTests_; \
|
||||
} \
|
||||
static const char* const GTEST_REGISTERED_TEST_NAMES_(CaseName) = \
|
||||
GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).VerifyRegisteredTestNames(\
|
||||
__FILE__, __LINE__, #__VA_ARGS__)
|
||||
|
||||
// The 'Types' template argument below must have spaces around it
|
||||
// since some compilers may choke on '>>' when passing a template
|
||||
// instance (e.g. Types<int>)
|
||||
# define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types) \
|
||||
bool gtest_##Prefix##_##CaseName GTEST_ATTRIBUTE_UNUSED_ = \
|
||||
::testing::internal::TypeParameterizedTestCase<CaseName, \
|
||||
GTEST_CASE_NAMESPACE_(CaseName)::gtest_AllTests_, \
|
||||
::testing::internal::TypeList< Types >::type>::Register(\
|
||||
#Prefix, #CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName))
|
||||
|
||||
#endif // GTEST_HAS_TYPED_TEST_P
|
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
|
||||
// Copyright 2008 Google Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
#ifndef GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
|
||||
#define GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
|
||||
|
||||
// This header implements typed tests and type-parameterized tests.
|
||||
|
||||
// Typed (aka type-driven) tests repeat the same test for types in a
|
||||
// list. You must know which types you want to test with when writing
|
||||
// typed tests. Here's how you do it:
|
||||
|
||||
#if 0
|
||||
|
||||
// First, define a fixture class template. It should be parameterized
|
||||
// by a type. Remember to derive it from testing::Test.
|
||||
template <typename T>
|
||||
class FooTest : public testing::Test {
|
||||
public:
|
||||
...
|
||||
typedef std::list<T> List;
|
||||
static T shared_;
|
||||
T value_;
|
||||
};
|
||||
|
||||
// Next, associate a list of types with the test case, which will be
|
||||
// repeated for each type in the list. The typedef is necessary for
|
||||
// the macro to parse correctly.
|
||||
typedef testing::Types<char, int, unsigned int> MyTypes;
|
||||
TYPED_TEST_CASE(FooTest, MyTypes);
|
||||
|
||||
// If the type list contains only one type, you can write that type
|
||||
// directly without Types<...>:
|
||||
// TYPED_TEST_CASE(FooTest, int);
|
||||
|
||||
// Then, use TYPED_TEST() instead of TEST_F() to define as many typed
|
||||
// tests for this test case as you want.
|
||||
TYPED_TEST(FooTest, DoesBlah) {
|
||||
// Inside a test, refer to TypeParam to get the type parameter.
|
||||
// Since we are inside a derived class template, C++ requires use to
|
||||
// visit the members of FooTest via 'this'.
|
||||
TypeParam n = this->value_;
|
||||
|
||||
// To visit static members of the fixture, add the TestFixture::
|
||||
// prefix.
|
||||
n += TestFixture::shared_;
|
||||
|
||||
// To refer to typedefs in the fixture, add the "typename
|
||||
// TestFixture::" prefix.
|
||||
typename TestFixture::List values;
|
||||
values.push_back(n);
|
||||
...
|
||||
}
|
||||
|
||||
TYPED_TEST(FooTest, HasPropertyA) { ... }
|
||||
|
||||
#endif // 0
|
||||
|
||||
// Type-parameterized tests are abstract test patterns parameterized
|
||||
// by a type. Compared with typed tests, type-parameterized tests
|
||||
// allow you to define the test pattern without knowing what the type
|
||||
// parameters are. The defined pattern can be instantiated with
|
||||
// different types any number of times, in any number of translation
|
||||
// units.
|
||||
//
|
||||
// If you are designing an interface or concept, you can define a
|
||||
// suite of type-parameterized tests to verify properties that any
|
||||
// valid implementation of the interface/concept should have. Then,
|
||||
// each implementation can easily instantiate the test suite to verify
|
||||
// that it conforms to the requirements, without having to write
|
||||
// similar tests repeatedly. Here's an example:
|
||||
|
||||
#if 0
|
||||
|
||||
// First, define a fixture class template. It should be parameterized
|
||||
// by a type. Remember to derive it from testing::Test.
|
||||
template <typename T>
|
||||
class FooTest : public testing::Test {
|
||||
...
|
||||
};
|
||||
|
||||
// Next, declare that you will define a type-parameterized test case
|
||||
// (the _P suffix is for "parameterized" or "pattern", whichever you
|
||||
// prefer):
|
||||
TYPED_TEST_CASE_P(FooTest);
|
||||
|
||||
// Then, use TYPED_TEST_P() to define as many type-parameterized tests
|
||||
// for this type-parameterized test case as you want.
|
||||
TYPED_TEST_P(FooTest, DoesBlah) {
|
||||
// Inside a test, refer to TypeParam to get the type parameter.
|
||||
TypeParam n = 0;
|
||||
...
|
||||
}
|
||||
|
||||
TYPED_TEST_P(FooTest, HasPropertyA) { ... }
|
||||
|
||||
// Now the tricky part: you need to register all test patterns before
|
||||
// you can instantiate them. The first argument of the macro is the
|
||||
// test case name; the rest are the names of the tests in this test
|
||||
// case.
|
||||
REGISTER_TYPED_TEST_CASE_P(FooTest,
|
||||
DoesBlah, HasPropertyA);
|
||||
|
||||
// Finally, you are free to instantiate the pattern with the types you
|
||||
// want. If you put the above code in a header file, you can #include
|
||||
// it in multiple C++ source files and instantiate it multiple times.
|
||||
//
|
||||
// To distinguish different instances of the pattern, the first
|
||||
// argument to the INSTANTIATE_* macro is a prefix that will be added
|
||||
// to the actual test case name. Remember to pick unique prefixes for
|
||||
// different instances.
|
||||
typedef testing::Types<char, int, unsigned int> MyTypes;
|
||||
INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes);
|
||||
|
||||
// If the type list contains only one type, you can write that type
|
||||
// directly without Types<...>:
|
||||
// INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, int);
|
||||
|
||||
#endif // 0
|
||||
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
#include "gtest/internal/gtest-type-util.h"
|
||||
|
||||
// Implements typed tests.
|
||||
|
||||
#if GTEST_HAS_TYPED_TEST
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||
//
|
||||
// Expands to the name of the typedef for the type parameters of the
|
||||
// given test case.
|
||||
# define GTEST_TYPE_PARAMS_(TestCaseName) gtest_type_params_##TestCaseName##_
|
||||
|
||||
// The 'Types' template argument below must have spaces around it
|
||||
// since some compilers may choke on '>>' when passing a template
|
||||
// instance (e.g. Types<int>)
|
||||
# define TYPED_TEST_CASE(CaseName, Types) \
|
||||
typedef ::testing::internal::TypeList< Types >::type \
|
||||
GTEST_TYPE_PARAMS_(CaseName)
|
||||
|
||||
# define TYPED_TEST(CaseName, TestName) \
|
||||
template <typename gtest_TypeParam_> \
|
||||
class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \
|
||||
: public CaseName<gtest_TypeParam_> { \
|
||||
private: \
|
||||
typedef CaseName<gtest_TypeParam_> TestFixture; \
|
||||
typedef gtest_TypeParam_ TypeParam; \
|
||||
virtual void TestBody(); \
|
||||
}; \
|
||||
bool gtest_##CaseName##_##TestName##_registered_ GTEST_ATTRIBUTE_UNUSED_ = \
|
||||
::testing::internal::TypeParameterizedTest< \
|
||||
CaseName, \
|
||||
::testing::internal::TemplateSel< \
|
||||
GTEST_TEST_CLASS_NAME_(CaseName, TestName)>, \
|
||||
GTEST_TYPE_PARAMS_(CaseName)>::Register(\
|
||||
"", #CaseName, #TestName, 0); \
|
||||
template <typename gtest_TypeParam_> \
|
||||
void GTEST_TEST_CLASS_NAME_(CaseName, TestName)<gtest_TypeParam_>::TestBody()
|
||||
|
||||
#endif // GTEST_HAS_TYPED_TEST
|
||||
|
||||
// Implements type-parameterized tests.
|
||||
|
||||
#if GTEST_HAS_TYPED_TEST_P
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||
//
|
||||
// Expands to the namespace name that the type-parameterized tests for
|
||||
// the given type-parameterized test case are defined in. The exact
|
||||
// name of the namespace is subject to change without notice.
|
||||
# define GTEST_CASE_NAMESPACE_(TestCaseName) \
|
||||
gtest_case_##TestCaseName##_
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||
//
|
||||
// Expands to the name of the variable used to remember the names of
|
||||
// the defined tests in the given test case.
|
||||
# define GTEST_TYPED_TEST_CASE_P_STATE_(TestCaseName) \
|
||||
gtest_typed_test_case_p_state_##TestCaseName##_
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY.
|
||||
//
|
||||
// Expands to the name of the variable used to remember the names of
|
||||
// the registered tests in the given test case.
|
||||
# define GTEST_REGISTERED_TEST_NAMES_(TestCaseName) \
|
||||
gtest_registered_test_names_##TestCaseName##_
|
||||
|
||||
// The variables defined in the type-parameterized test macros are
|
||||
// static as typically these macros are used in a .h file that can be
|
||||
// #included in multiple translation units linked together.
|
||||
# define TYPED_TEST_CASE_P(CaseName) \
|
||||
static ::testing::internal::TypedTestCasePState \
|
||||
GTEST_TYPED_TEST_CASE_P_STATE_(CaseName)
|
||||
|
||||
# define TYPED_TEST_P(CaseName, TestName) \
|
||||
namespace GTEST_CASE_NAMESPACE_(CaseName) { \
|
||||
template <typename gtest_TypeParam_> \
|
||||
class TestName : public CaseName<gtest_TypeParam_> { \
|
||||
private: \
|
||||
typedef CaseName<gtest_TypeParam_> TestFixture; \
|
||||
typedef gtest_TypeParam_ TypeParam; \
|
||||
virtual void TestBody(); \
|
||||
}; \
|
||||
static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \
|
||||
GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).AddTestName(\
|
||||
__FILE__, __LINE__, #CaseName, #TestName); \
|
||||
} \
|
||||
template <typename gtest_TypeParam_> \
|
||||
void GTEST_CASE_NAMESPACE_(CaseName)::TestName<gtest_TypeParam_>::TestBody()
|
||||
|
||||
# define REGISTER_TYPED_TEST_CASE_P(CaseName, ...) \
|
||||
namespace GTEST_CASE_NAMESPACE_(CaseName) { \
|
||||
typedef ::testing::internal::Templates<__VA_ARGS__>::type gtest_AllTests_; \
|
||||
} \
|
||||
static const char* const GTEST_REGISTERED_TEST_NAMES_(CaseName) = \
|
||||
GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).VerifyRegisteredTestNames(\
|
||||
__FILE__, __LINE__, #__VA_ARGS__)
|
||||
|
||||
// The 'Types' template argument below must have spaces around it
|
||||
// since some compilers may choke on '>>' when passing a template
|
||||
// instance (e.g. Types<int>)
|
||||
# define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types) \
|
||||
bool gtest_##Prefix##_##CaseName GTEST_ATTRIBUTE_UNUSED_ = \
|
||||
::testing::internal::TypeParameterizedTestCase<CaseName, \
|
||||
GTEST_CASE_NAMESPACE_(CaseName)::gtest_AllTests_, \
|
||||
::testing::internal::TypeList< Types >::type>::Register(\
|
||||
#Prefix, #CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName))
|
||||
|
||||
#endif // GTEST_HAS_TYPED_TEST_P
|
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,358 +1,358 @@
|
||||
// Copyright 2006, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// This file is AUTOMATICALLY GENERATED on 10/31/2011 by command
|
||||
// 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND!
|
||||
//
|
||||
// Implements a family of generic predicate assertion macros.
|
||||
|
||||
#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
|
||||
#define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
|
||||
|
||||
// Makes sure this header is not included before gtest.h.
|
||||
#ifndef GTEST_INCLUDE_GTEST_GTEST_H_
|
||||
# error Do not include gtest_pred_impl.h directly. Include gtest.h instead.
|
||||
#endif // GTEST_INCLUDE_GTEST_GTEST_H_
|
||||
|
||||
// This header implements a family of generic predicate assertion
|
||||
// macros:
|
||||
//
|
||||
// ASSERT_PRED_FORMAT1(pred_format, v1)
|
||||
// ASSERT_PRED_FORMAT2(pred_format, v1, v2)
|
||||
// ...
|
||||
//
|
||||
// where pred_format is a function or functor that takes n (in the
|
||||
// case of ASSERT_PRED_FORMATn) values and their source expression
|
||||
// text, and returns a testing::AssertionResult. See the definition
|
||||
// of ASSERT_EQ in gtest.h for an example.
|
||||
//
|
||||
// If you don't care about formatting, you can use the more
|
||||
// restrictive version:
|
||||
//
|
||||
// ASSERT_PRED1(pred, v1)
|
||||
// ASSERT_PRED2(pred, v1, v2)
|
||||
// ...
|
||||
//
|
||||
// where pred is an n-ary function or functor that returns bool,
|
||||
// and the values v1, v2, ..., must support the << operator for
|
||||
// streaming to std::ostream.
|
||||
//
|
||||
// We also define the EXPECT_* variations.
|
||||
//
|
||||
// For now we only support predicates whose arity is at most 5.
|
||||
// Please email googletestframework@googlegroups.com if you need
|
||||
// support for higher arities.
|
||||
|
||||
// GTEST_ASSERT_ is the basic statement to which all of the assertions
|
||||
// in this file reduce. Don't use this in your code.
|
||||
|
||||
#define GTEST_ASSERT_(expression, on_failure) \
|
||||
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
||||
if (const ::testing::AssertionResult gtest_ar = (expression)) \
|
||||
; \
|
||||
else \
|
||||
on_failure(gtest_ar.failure_message())
|
||||
|
||||
|
||||
// Helper function for implementing {EXPECT|ASSERT}_PRED1. Don't use
|
||||
// this in your code.
|
||||
template <typename Pred,
|
||||
typename T1>
|
||||
AssertionResult AssertPred1Helper(const char* pred_text,
|
||||
const char* e1,
|
||||
Pred pred,
|
||||
const T1& v1) {
|
||||
if (pred(v1)) return AssertionSuccess();
|
||||
|
||||
return AssertionFailure() << pred_text << "("
|
||||
<< e1 << ") evaluates to false, where"
|
||||
<< "\n" << e1 << " evaluates to " << v1;
|
||||
}
|
||||
|
||||
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1.
|
||||
// Don't use this in your code.
|
||||
#define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure)\
|
||||
GTEST_ASSERT_(pred_format(#v1, v1), \
|
||||
on_failure)
|
||||
|
||||
// Internal macro for implementing {EXPECT|ASSERT}_PRED1. Don't use
|
||||
// this in your code.
|
||||
#define GTEST_PRED1_(pred, v1, on_failure)\
|
||||
GTEST_ASSERT_(::testing::AssertPred1Helper(#pred, \
|
||||
#v1, \
|
||||
pred, \
|
||||
v1), on_failure)
|
||||
|
||||
// Unary predicate assertion macros.
|
||||
#define EXPECT_PRED_FORMAT1(pred_format, v1) \
|
||||
GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_NONFATAL_FAILURE_)
|
||||
#define EXPECT_PRED1(pred, v1) \
|
||||
GTEST_PRED1_(pred, v1, GTEST_NONFATAL_FAILURE_)
|
||||
#define ASSERT_PRED_FORMAT1(pred_format, v1) \
|
||||
GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_FATAL_FAILURE_)
|
||||
#define ASSERT_PRED1(pred, v1) \
|
||||
GTEST_PRED1_(pred, v1, GTEST_FATAL_FAILURE_)
|
||||
|
||||
|
||||
|
||||
// Helper function for implementing {EXPECT|ASSERT}_PRED2. Don't use
|
||||
// this in your code.
|
||||
template <typename Pred,
|
||||
typename T1,
|
||||
typename T2>
|
||||
AssertionResult AssertPred2Helper(const char* pred_text,
|
||||
const char* e1,
|
||||
const char* e2,
|
||||
Pred pred,
|
||||
const T1& v1,
|
||||
const T2& v2) {
|
||||
if (pred(v1, v2)) return AssertionSuccess();
|
||||
|
||||
return AssertionFailure() << pred_text << "("
|
||||
<< e1 << ", "
|
||||
<< e2 << ") evaluates to false, where"
|
||||
<< "\n" << e1 << " evaluates to " << v1
|
||||
<< "\n" << e2 << " evaluates to " << v2;
|
||||
}
|
||||
|
||||
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2.
|
||||
// Don't use this in your code.
|
||||
#define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure)\
|
||||
GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), \
|
||||
on_failure)
|
||||
|
||||
// Internal macro for implementing {EXPECT|ASSERT}_PRED2. Don't use
|
||||
// this in your code.
|
||||
#define GTEST_PRED2_(pred, v1, v2, on_failure)\
|
||||
GTEST_ASSERT_(::testing::AssertPred2Helper(#pred, \
|
||||
#v1, \
|
||||
#v2, \
|
||||
pred, \
|
||||
v1, \
|
||||
v2), on_failure)
|
||||
|
||||
// Binary predicate assertion macros.
|
||||
#define EXPECT_PRED_FORMAT2(pred_format, v1, v2) \
|
||||
GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_)
|
||||
#define EXPECT_PRED2(pred, v1, v2) \
|
||||
GTEST_PRED2_(pred, v1, v2, GTEST_NONFATAL_FAILURE_)
|
||||
#define ASSERT_PRED_FORMAT2(pred_format, v1, v2) \
|
||||
GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_FATAL_FAILURE_)
|
||||
#define ASSERT_PRED2(pred, v1, v2) \
|
||||
GTEST_PRED2_(pred, v1, v2, GTEST_FATAL_FAILURE_)
|
||||
|
||||
|
||||
|
||||
// Helper function for implementing {EXPECT|ASSERT}_PRED3. Don't use
|
||||
// this in your code.
|
||||
template <typename Pred,
|
||||
typename T1,
|
||||
typename T2,
|
||||
typename T3>
|
||||
AssertionResult AssertPred3Helper(const char* pred_text,
|
||||
const char* e1,
|
||||
const char* e2,
|
||||
const char* e3,
|
||||
Pred pred,
|
||||
const T1& v1,
|
||||
const T2& v2,
|
||||
const T3& v3) {
|
||||
if (pred(v1, v2, v3)) return AssertionSuccess();
|
||||
|
||||
return AssertionFailure() << pred_text << "("
|
||||
<< e1 << ", "
|
||||
<< e2 << ", "
|
||||
<< e3 << ") evaluates to false, where"
|
||||
<< "\n" << e1 << " evaluates to " << v1
|
||||
<< "\n" << e2 << " evaluates to " << v2
|
||||
<< "\n" << e3 << " evaluates to " << v3;
|
||||
}
|
||||
|
||||
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3.
|
||||
// Don't use this in your code.
|
||||
#define GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, on_failure)\
|
||||
GTEST_ASSERT_(pred_format(#v1, #v2, #v3, v1, v2, v3), \
|
||||
on_failure)
|
||||
|
||||
// Internal macro for implementing {EXPECT|ASSERT}_PRED3. Don't use
|
||||
// this in your code.
|
||||
#define GTEST_PRED3_(pred, v1, v2, v3, on_failure)\
|
||||
GTEST_ASSERT_(::testing::AssertPred3Helper(#pred, \
|
||||
#v1, \
|
||||
#v2, \
|
||||
#v3, \
|
||||
pred, \
|
||||
v1, \
|
||||
v2, \
|
||||
v3), on_failure)
|
||||
|
||||
// Ternary predicate assertion macros.
|
||||
#define EXPECT_PRED_FORMAT3(pred_format, v1, v2, v3) \
|
||||
GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_NONFATAL_FAILURE_)
|
||||
#define EXPECT_PRED3(pred, v1, v2, v3) \
|
||||
GTEST_PRED3_(pred, v1, v2, v3, GTEST_NONFATAL_FAILURE_)
|
||||
#define ASSERT_PRED_FORMAT3(pred_format, v1, v2, v3) \
|
||||
GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_FATAL_FAILURE_)
|
||||
#define ASSERT_PRED3(pred, v1, v2, v3) \
|
||||
GTEST_PRED3_(pred, v1, v2, v3, GTEST_FATAL_FAILURE_)
|
||||
|
||||
|
||||
|
||||
// Helper function for implementing {EXPECT|ASSERT}_PRED4. Don't use
|
||||
// this in your code.
|
||||
template <typename Pred,
|
||||
typename T1,
|
||||
typename T2,
|
||||
typename T3,
|
||||
typename T4>
|
||||
AssertionResult AssertPred4Helper(const char* pred_text,
|
||||
const char* e1,
|
||||
const char* e2,
|
||||
const char* e3,
|
||||
const char* e4,
|
||||
Pred pred,
|
||||
const T1& v1,
|
||||
const T2& v2,
|
||||
const T3& v3,
|
||||
const T4& v4) {
|
||||
if (pred(v1, v2, v3, v4)) return AssertionSuccess();
|
||||
|
||||
return AssertionFailure() << pred_text << "("
|
||||
<< e1 << ", "
|
||||
<< e2 << ", "
|
||||
<< e3 << ", "
|
||||
<< e4 << ") evaluates to false, where"
|
||||
<< "\n" << e1 << " evaluates to " << v1
|
||||
<< "\n" << e2 << " evaluates to " << v2
|
||||
<< "\n" << e3 << " evaluates to " << v3
|
||||
<< "\n" << e4 << " evaluates to " << v4;
|
||||
}
|
||||
|
||||
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4.
|
||||
// Don't use this in your code.
|
||||
#define GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, on_failure)\
|
||||
GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4), \
|
||||
on_failure)
|
||||
|
||||
// Internal macro for implementing {EXPECT|ASSERT}_PRED4. Don't use
|
||||
// this in your code.
|
||||
#define GTEST_PRED4_(pred, v1, v2, v3, v4, on_failure)\
|
||||
GTEST_ASSERT_(::testing::AssertPred4Helper(#pred, \
|
||||
#v1, \
|
||||
#v2, \
|
||||
#v3, \
|
||||
#v4, \
|
||||
pred, \
|
||||
v1, \
|
||||
v2, \
|
||||
v3, \
|
||||
v4), on_failure)
|
||||
|
||||
// 4-ary predicate assertion macros.
|
||||
#define EXPECT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \
|
||||
GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_)
|
||||
#define EXPECT_PRED4(pred, v1, v2, v3, v4) \
|
||||
GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_)
|
||||
#define ASSERT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \
|
||||
GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_FATAL_FAILURE_)
|
||||
#define ASSERT_PRED4(pred, v1, v2, v3, v4) \
|
||||
GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_FATAL_FAILURE_)
|
||||
|
||||
|
||||
|
||||
// Helper function for implementing {EXPECT|ASSERT}_PRED5. Don't use
|
||||
// this in your code.
|
||||
template <typename Pred,
|
||||
typename T1,
|
||||
typename T2,
|
||||
typename T3,
|
||||
typename T4,
|
||||
typename T5>
|
||||
AssertionResult AssertPred5Helper(const char* pred_text,
|
||||
const char* e1,
|
||||
const char* e2,
|
||||
const char* e3,
|
||||
const char* e4,
|
||||
const char* e5,
|
||||
Pred pred,
|
||||
const T1& v1,
|
||||
const T2& v2,
|
||||
const T3& v3,
|
||||
const T4& v4,
|
||||
const T5& v5) {
|
||||
if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess();
|
||||
|
||||
return AssertionFailure() << pred_text << "("
|
||||
<< e1 << ", "
|
||||
<< e2 << ", "
|
||||
<< e3 << ", "
|
||||
<< e4 << ", "
|
||||
<< e5 << ") evaluates to false, where"
|
||||
<< "\n" << e1 << " evaluates to " << v1
|
||||
<< "\n" << e2 << " evaluates to " << v2
|
||||
<< "\n" << e3 << " evaluates to " << v3
|
||||
<< "\n" << e4 << " evaluates to " << v4
|
||||
<< "\n" << e5 << " evaluates to " << v5;
|
||||
}
|
||||
|
||||
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5.
|
||||
// Don't use this in your code.
|
||||
#define GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, on_failure)\
|
||||
GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, #v5, v1, v2, v3, v4, v5), \
|
||||
on_failure)
|
||||
|
||||
// Internal macro for implementing {EXPECT|ASSERT}_PRED5. Don't use
|
||||
// this in your code.
|
||||
#define GTEST_PRED5_(pred, v1, v2, v3, v4, v5, on_failure)\
|
||||
GTEST_ASSERT_(::testing::AssertPred5Helper(#pred, \
|
||||
#v1, \
|
||||
#v2, \
|
||||
#v3, \
|
||||
#v4, \
|
||||
#v5, \
|
||||
pred, \
|
||||
v1, \
|
||||
v2, \
|
||||
v3, \
|
||||
v4, \
|
||||
v5), on_failure)
|
||||
|
||||
// 5-ary predicate assertion macros.
|
||||
#define EXPECT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \
|
||||
GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_)
|
||||
#define EXPECT_PRED5(pred, v1, v2, v3, v4, v5) \
|
||||
GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_)
|
||||
#define ASSERT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \
|
||||
GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_)
|
||||
#define ASSERT_PRED5(pred, v1, v2, v3, v4, v5) \
|
||||
GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_)
|
||||
|
||||
|
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
|
||||
// Copyright 2006, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// This file is AUTOMATICALLY GENERATED on 10/31/2011 by command
|
||||
// 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND!
|
||||
//
|
||||
// Implements a family of generic predicate assertion macros.
|
||||
|
||||
#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
|
||||
#define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
|
||||
|
||||
// Makes sure this header is not included before gtest.h.
|
||||
#ifndef GTEST_INCLUDE_GTEST_GTEST_H_
|
||||
# error Do not include gtest_pred_impl.h directly. Include gtest.h instead.
|
||||
#endif // GTEST_INCLUDE_GTEST_GTEST_H_
|
||||
|
||||
// This header implements a family of generic predicate assertion
|
||||
// macros:
|
||||
//
|
||||
// ASSERT_PRED_FORMAT1(pred_format, v1)
|
||||
// ASSERT_PRED_FORMAT2(pred_format, v1, v2)
|
||||
// ...
|
||||
//
|
||||
// where pred_format is a function or functor that takes n (in the
|
||||
// case of ASSERT_PRED_FORMATn) values and their source expression
|
||||
// text, and returns a testing::AssertionResult. See the definition
|
||||
// of ASSERT_EQ in gtest.h for an example.
|
||||
//
|
||||
// If you don't care about formatting, you can use the more
|
||||
// restrictive version:
|
||||
//
|
||||
// ASSERT_PRED1(pred, v1)
|
||||
// ASSERT_PRED2(pred, v1, v2)
|
||||
// ...
|
||||
//
|
||||
// where pred is an n-ary function or functor that returns bool,
|
||||
// and the values v1, v2, ..., must support the << operator for
|
||||
// streaming to std::ostream.
|
||||
//
|
||||
// We also define the EXPECT_* variations.
|
||||
//
|
||||
// For now we only support predicates whose arity is at most 5.
|
||||
// Please email googletestframework@googlegroups.com if you need
|
||||
// support for higher arities.
|
||||
|
||||
// GTEST_ASSERT_ is the basic statement to which all of the assertions
|
||||
// in this file reduce. Don't use this in your code.
|
||||
|
||||
#define GTEST_ASSERT_(expression, on_failure) \
|
||||
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
||||
if (const ::testing::AssertionResult gtest_ar = (expression)) \
|
||||
; \
|
||||
else \
|
||||
on_failure(gtest_ar.failure_message())
|
||||
|
||||
|
||||
// Helper function for implementing {EXPECT|ASSERT}_PRED1. Don't use
|
||||
// this in your code.
|
||||
template <typename Pred,
|
||||
typename T1>
|
||||
AssertionResult AssertPred1Helper(const char* pred_text,
|
||||
const char* e1,
|
||||
Pred pred,
|
||||
const T1& v1) {
|
||||
if (pred(v1)) return AssertionSuccess();
|
||||
|
||||
return AssertionFailure() << pred_text << "("
|
||||
<< e1 << ") evaluates to false, where"
|
||||
<< "\n" << e1 << " evaluates to " << v1;
|
||||
}
|
||||
|
||||
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1.
|
||||
// Don't use this in your code.
|
||||
#define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure)\
|
||||
GTEST_ASSERT_(pred_format(#v1, v1), \
|
||||
on_failure)
|
||||
|
||||
// Internal macro for implementing {EXPECT|ASSERT}_PRED1. Don't use
|
||||
// this in your code.
|
||||
#define GTEST_PRED1_(pred, v1, on_failure)\
|
||||
GTEST_ASSERT_(::testing::AssertPred1Helper(#pred, \
|
||||
#v1, \
|
||||
pred, \
|
||||
v1), on_failure)
|
||||
|
||||
// Unary predicate assertion macros.
|
||||
#define EXPECT_PRED_FORMAT1(pred_format, v1) \
|
||||
GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_NONFATAL_FAILURE_)
|
||||
#define EXPECT_PRED1(pred, v1) \
|
||||
GTEST_PRED1_(pred, v1, GTEST_NONFATAL_FAILURE_)
|
||||
#define ASSERT_PRED_FORMAT1(pred_format, v1) \
|
||||
GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_FATAL_FAILURE_)
|
||||
#define ASSERT_PRED1(pred, v1) \
|
||||
GTEST_PRED1_(pred, v1, GTEST_FATAL_FAILURE_)
|
||||
|
||||
|
||||
|
||||
// Helper function for implementing {EXPECT|ASSERT}_PRED2. Don't use
|
||||
// this in your code.
|
||||
template <typename Pred,
|
||||
typename T1,
|
||||
typename T2>
|
||||
AssertionResult AssertPred2Helper(const char* pred_text,
|
||||
const char* e1,
|
||||
const char* e2,
|
||||
Pred pred,
|
||||
const T1& v1,
|
||||
const T2& v2) {
|
||||
if (pred(v1, v2)) return AssertionSuccess();
|
||||
|
||||
return AssertionFailure() << pred_text << "("
|
||||
<< e1 << ", "
|
||||
<< e2 << ") evaluates to false, where"
|
||||
<< "\n" << e1 << " evaluates to " << v1
|
||||
<< "\n" << e2 << " evaluates to " << v2;
|
||||
}
|
||||
|
||||
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2.
|
||||
// Don't use this in your code.
|
||||
#define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure)\
|
||||
GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), \
|
||||
on_failure)
|
||||
|
||||
// Internal macro for implementing {EXPECT|ASSERT}_PRED2. Don't use
|
||||
// this in your code.
|
||||
#define GTEST_PRED2_(pred, v1, v2, on_failure)\
|
||||
GTEST_ASSERT_(::testing::AssertPred2Helper(#pred, \
|
||||
#v1, \
|
||||
#v2, \
|
||||
pred, \
|
||||
v1, \
|
||||
v2), on_failure)
|
||||
|
||||
// Binary predicate assertion macros.
|
||||
#define EXPECT_PRED_FORMAT2(pred_format, v1, v2) \
|
||||
GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_)
|
||||
#define EXPECT_PRED2(pred, v1, v2) \
|
||||
GTEST_PRED2_(pred, v1, v2, GTEST_NONFATAL_FAILURE_)
|
||||
#define ASSERT_PRED_FORMAT2(pred_format, v1, v2) \
|
||||
GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_FATAL_FAILURE_)
|
||||
#define ASSERT_PRED2(pred, v1, v2) \
|
||||
GTEST_PRED2_(pred, v1, v2, GTEST_FATAL_FAILURE_)
|
||||
|
||||
|
||||
|
||||
// Helper function for implementing {EXPECT|ASSERT}_PRED3. Don't use
|
||||
// this in your code.
|
||||
template <typename Pred,
|
||||
typename T1,
|
||||
typename T2,
|
||||
typename T3>
|
||||
AssertionResult AssertPred3Helper(const char* pred_text,
|
||||
const char* e1,
|
||||
const char* e2,
|
||||
const char* e3,
|
||||
Pred pred,
|
||||
const T1& v1,
|
||||
const T2& v2,
|
||||
const T3& v3) {
|
||||
if (pred(v1, v2, v3)) return AssertionSuccess();
|
||||
|
||||
return AssertionFailure() << pred_text << "("
|
||||
<< e1 << ", "
|
||||
<< e2 << ", "
|
||||
<< e3 << ") evaluates to false, where"
|
||||
<< "\n" << e1 << " evaluates to " << v1
|
||||
<< "\n" << e2 << " evaluates to " << v2
|
||||
<< "\n" << e3 << " evaluates to " << v3;
|
||||
}
|
||||
|
||||
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3.
|
||||
// Don't use this in your code.
|
||||
#define GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, on_failure)\
|
||||
GTEST_ASSERT_(pred_format(#v1, #v2, #v3, v1, v2, v3), \
|
||||
on_failure)
|
||||
|
||||
// Internal macro for implementing {EXPECT|ASSERT}_PRED3. Don't use
|
||||
// this in your code.
|
||||
#define GTEST_PRED3_(pred, v1, v2, v3, on_failure)\
|
||||
GTEST_ASSERT_(::testing::AssertPred3Helper(#pred, \
|
||||
#v1, \
|
||||
#v2, \
|
||||
#v3, \
|
||||
pred, \
|
||||
v1, \
|
||||
v2, \
|
||||
v3), on_failure)
|
||||
|
||||
// Ternary predicate assertion macros.
|
||||
#define EXPECT_PRED_FORMAT3(pred_format, v1, v2, v3) \
|
||||
GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_NONFATAL_FAILURE_)
|
||||
#define EXPECT_PRED3(pred, v1, v2, v3) \
|
||||
GTEST_PRED3_(pred, v1, v2, v3, GTEST_NONFATAL_FAILURE_)
|
||||
#define ASSERT_PRED_FORMAT3(pred_format, v1, v2, v3) \
|
||||
GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_FATAL_FAILURE_)
|
||||
#define ASSERT_PRED3(pred, v1, v2, v3) \
|
||||
GTEST_PRED3_(pred, v1, v2, v3, GTEST_FATAL_FAILURE_)
|
||||
|
||||
|
||||
|
||||
// Helper function for implementing {EXPECT|ASSERT}_PRED4. Don't use
|
||||
// this in your code.
|
||||
template <typename Pred,
|
||||
typename T1,
|
||||
typename T2,
|
||||
typename T3,
|
||||
typename T4>
|
||||
AssertionResult AssertPred4Helper(const char* pred_text,
|
||||
const char* e1,
|
||||
const char* e2,
|
||||
const char* e3,
|
||||
const char* e4,
|
||||
Pred pred,
|
||||
const T1& v1,
|
||||
const T2& v2,
|
||||
const T3& v3,
|
||||
const T4& v4) {
|
||||
if (pred(v1, v2, v3, v4)) return AssertionSuccess();
|
||||
|
||||
return AssertionFailure() << pred_text << "("
|
||||
<< e1 << ", "
|
||||
<< e2 << ", "
|
||||
<< e3 << ", "
|
||||
<< e4 << ") evaluates to false, where"
|
||||
<< "\n" << e1 << " evaluates to " << v1
|
||||
<< "\n" << e2 << " evaluates to " << v2
|
||||
<< "\n" << e3 << " evaluates to " << v3
|
||||
<< "\n" << e4 << " evaluates to " << v4;
|
||||
}
|
||||
|
||||
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4.
|
||||
// Don't use this in your code.
|
||||
#define GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, on_failure)\
|
||||
GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4), \
|
||||
on_failure)
|
||||
|
||||
// Internal macro for implementing {EXPECT|ASSERT}_PRED4. Don't use
|
||||
// this in your code.
|
||||
#define GTEST_PRED4_(pred, v1, v2, v3, v4, on_failure)\
|
||||
GTEST_ASSERT_(::testing::AssertPred4Helper(#pred, \
|
||||
#v1, \
|
||||
#v2, \
|
||||
#v3, \
|
||||
#v4, \
|
||||
pred, \
|
||||
v1, \
|
||||
v2, \
|
||||
v3, \
|
||||
v4), on_failure)
|
||||
|
||||
// 4-ary predicate assertion macros.
|
||||
#define EXPECT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \
|
||||
GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_)
|
||||
#define EXPECT_PRED4(pred, v1, v2, v3, v4) \
|
||||
GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_)
|
||||
#define ASSERT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \
|
||||
GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_FATAL_FAILURE_)
|
||||
#define ASSERT_PRED4(pred, v1, v2, v3, v4) \
|
||||
GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_FATAL_FAILURE_)
|
||||
|
||||
|
||||
|
||||
// Helper function for implementing {EXPECT|ASSERT}_PRED5. Don't use
|
||||
// this in your code.
|
||||
template <typename Pred,
|
||||
typename T1,
|
||||
typename T2,
|
||||
typename T3,
|
||||
typename T4,
|
||||
typename T5>
|
||||
AssertionResult AssertPred5Helper(const char* pred_text,
|
||||
const char* e1,
|
||||
const char* e2,
|
||||
const char* e3,
|
||||
const char* e4,
|
||||
const char* e5,
|
||||
Pred pred,
|
||||
const T1& v1,
|
||||
const T2& v2,
|
||||
const T3& v3,
|
||||
const T4& v4,
|
||||
const T5& v5) {
|
||||
if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess();
|
||||
|
||||
return AssertionFailure() << pred_text << "("
|
||||
<< e1 << ", "
|
||||
<< e2 << ", "
|
||||
<< e3 << ", "
|
||||
<< e4 << ", "
|
||||
<< e5 << ") evaluates to false, where"
|
||||
<< "\n" << e1 << " evaluates to " << v1
|
||||
<< "\n" << e2 << " evaluates to " << v2
|
||||
<< "\n" << e3 << " evaluates to " << v3
|
||||
<< "\n" << e4 << " evaluates to " << v4
|
||||
<< "\n" << e5 << " evaluates to " << v5;
|
||||
}
|
||||
|
||||
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5.
|
||||
// Don't use this in your code.
|
||||
#define GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, on_failure)\
|
||||
GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, #v5, v1, v2, v3, v4, v5), \
|
||||
on_failure)
|
||||
|
||||
// Internal macro for implementing {EXPECT|ASSERT}_PRED5. Don't use
|
||||
// this in your code.
|
||||
#define GTEST_PRED5_(pred, v1, v2, v3, v4, v5, on_failure)\
|
||||
GTEST_ASSERT_(::testing::AssertPred5Helper(#pred, \
|
||||
#v1, \
|
||||
#v2, \
|
||||
#v3, \
|
||||
#v4, \
|
||||
#v5, \
|
||||
pred, \
|
||||
v1, \
|
||||
v2, \
|
||||
v3, \
|
||||
v4, \
|
||||
v5), on_failure)
|
||||
|
||||
// 5-ary predicate assertion macros.
|
||||
#define EXPECT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \
|
||||
GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_)
|
||||
#define EXPECT_PRED5(pred, v1, v2, v3, v4, v5) \
|
||||
GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_)
|
||||
#define ASSERT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \
|
||||
GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_)
|
||||
#define ASSERT_PRED5(pred, v1, v2, v3, v4, v5) \
|
||||
GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_)
|
||||
|
||||
|
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
|
||||
@@ -1,58 +1,58 @@
|
||||
// Copyright 2006, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
//
|
||||
// Google C++ Testing Framework definitions useful in production code.
|
||||
|
||||
#ifndef GTEST_INCLUDE_GTEST_GTEST_PROD_H_
|
||||
#define GTEST_INCLUDE_GTEST_GTEST_PROD_H_
|
||||
|
||||
// When you need to test the private or protected members of a class,
|
||||
// use the FRIEND_TEST macro to declare your tests as friends of the
|
||||
// class. For example:
|
||||
//
|
||||
// class MyClass {
|
||||
// private:
|
||||
// void MyMethod();
|
||||
// FRIEND_TEST(MyClassTest, MyMethod);
|
||||
// };
|
||||
//
|
||||
// class MyClassTest : public testing::Test {
|
||||
// // ...
|
||||
// };
|
||||
//
|
||||
// TEST_F(MyClassTest, MyMethod) {
|
||||
// // Can call MyClass::MyMethod() here.
|
||||
// }
|
||||
|
||||
#define FRIEND_TEST(test_case_name, test_name)\
|
||||
friend class test_case_name##_##test_name##_Test
|
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_GTEST_PROD_H_
|
||||
// Copyright 2006, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
//
|
||||
// Google C++ Testing Framework definitions useful in production code.
|
||||
|
||||
#ifndef GTEST_INCLUDE_GTEST_GTEST_PROD_H_
|
||||
#define GTEST_INCLUDE_GTEST_GTEST_PROD_H_
|
||||
|
||||
// When you need to test the private or protected members of a class,
|
||||
// use the FRIEND_TEST macro to declare your tests as friends of the
|
||||
// class. For example:
|
||||
//
|
||||
// class MyClass {
|
||||
// private:
|
||||
// void MyMethod();
|
||||
// FRIEND_TEST(MyClassTest, MyMethod);
|
||||
// };
|
||||
//
|
||||
// class MyClassTest : public testing::Test {
|
||||
// // ...
|
||||
// };
|
||||
//
|
||||
// TEST_F(MyClassTest, MyMethod) {
|
||||
// // Can call MyClass::MyMethod() here.
|
||||
// }
|
||||
|
||||
#define FRIEND_TEST(test_case_name, test_name)\
|
||||
friend class test_case_name##_##test_name##_Test
|
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_GTEST_PROD_H_
|
||||
@@ -1,319 +1,319 @@
|
||||
// Copyright 2005, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee)
|
||||
//
|
||||
// The Google C++ Testing Framework (Google Test)
|
||||
//
|
||||
// This header file defines internal utilities needed for implementing
|
||||
// death tests. They are subject to change without notice.
|
||||
|
||||
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
|
||||
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
|
||||
|
||||
#include "gtest/internal/gtest-internal.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
GTEST_DECLARE_string_(internal_run_death_test);
|
||||
|
||||
// Names of the flags (needed for parsing Google Test flags).
|
||||
const char kDeathTestStyleFlag[] = "death_test_style";
|
||||
const char kDeathTestUseFork[] = "death_test_use_fork";
|
||||
const char kInternalRunDeathTestFlag[] = "internal_run_death_test";
|
||||
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
|
||||
// DeathTest is a class that hides much of the complexity of the
|
||||
// GTEST_DEATH_TEST_ macro. It is abstract; its static Create method
|
||||
// returns a concrete class that depends on the prevailing death test
|
||||
// style, as defined by the --gtest_death_test_style and/or
|
||||
// --gtest_internal_run_death_test flags.
|
||||
|
||||
// In describing the results of death tests, these terms are used with
|
||||
// the corresponding definitions:
|
||||
//
|
||||
// exit status: The integer exit information in the format specified
|
||||
// by wait(2)
|
||||
// exit code: The integer code passed to exit(3), _exit(2), or
|
||||
// returned from main()
|
||||
class GTEST_API_ DeathTest {
|
||||
public:
|
||||
// Create returns false if there was an error determining the
|
||||
// appropriate action to take for the current death test; for example,
|
||||
// if the gtest_death_test_style flag is set to an invalid value.
|
||||
// The LastMessage method will return a more detailed message in that
|
||||
// case. Otherwise, the DeathTest pointer pointed to by the "test"
|
||||
// argument is set. If the death test should be skipped, the pointer
|
||||
// is set to NULL; otherwise, it is set to the address of a new concrete
|
||||
// DeathTest object that controls the execution of the current test.
|
||||
static bool Create(const char* statement, const RE* regex,
|
||||
const char* file, int line, DeathTest** test);
|
||||
DeathTest();
|
||||
virtual ~DeathTest() { }
|
||||
|
||||
// A helper class that aborts a death test when it's deleted.
|
||||
class ReturnSentinel {
|
||||
public:
|
||||
explicit ReturnSentinel(DeathTest* test) : test_(test) { }
|
||||
~ReturnSentinel() { test_->Abort(TEST_ENCOUNTERED_RETURN_STATEMENT); }
|
||||
private:
|
||||
DeathTest* const test_;
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(ReturnSentinel);
|
||||
} GTEST_ATTRIBUTE_UNUSED_;
|
||||
|
||||
// An enumeration of possible roles that may be taken when a death
|
||||
// test is encountered. EXECUTE means that the death test logic should
|
||||
// be executed immediately. OVERSEE means that the program should prepare
|
||||
// the appropriate environment for a child process to execute the death
|
||||
// test, then wait for it to complete.
|
||||
enum TestRole { OVERSEE_TEST, EXECUTE_TEST };
|
||||
|
||||
// An enumeration of the three reasons that a test might be aborted.
|
||||
enum AbortReason {
|
||||
TEST_ENCOUNTERED_RETURN_STATEMENT,
|
||||
TEST_THREW_EXCEPTION,
|
||||
TEST_DID_NOT_DIE
|
||||
};
|
||||
|
||||
// Assumes one of the above roles.
|
||||
virtual TestRole AssumeRole() = 0;
|
||||
|
||||
// Waits for the death test to finish and returns its status.
|
||||
virtual int Wait() = 0;
|
||||
|
||||
// Returns true if the death test passed; that is, the test process
|
||||
// exited during the test, its exit status matches a user-supplied
|
||||
// predicate, and its stderr output matches a user-supplied regular
|
||||
// expression.
|
||||
// The user-supplied predicate may be a macro expression rather
|
||||
// than a function pointer or functor, or else Wait and Passed could
|
||||
// be combined.
|
||||
virtual bool Passed(bool exit_status_ok) = 0;
|
||||
|
||||
// Signals that the death test did not die as expected.
|
||||
virtual void Abort(AbortReason reason) = 0;
|
||||
|
||||
// Returns a human-readable outcome message regarding the outcome of
|
||||
// the last death test.
|
||||
static const char* LastMessage();
|
||||
|
||||
static void set_last_death_test_message(const std::string& message);
|
||||
|
||||
private:
|
||||
// A string containing a description of the outcome of the last death test.
|
||||
static std::string last_death_test_message_;
|
||||
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(DeathTest);
|
||||
};
|
||||
|
||||
// Factory interface for death tests. May be mocked out for testing.
|
||||
class DeathTestFactory {
|
||||
public:
|
||||
virtual ~DeathTestFactory() { }
|
||||
virtual bool Create(const char* statement, const RE* regex,
|
||||
const char* file, int line, DeathTest** test) = 0;
|
||||
};
|
||||
|
||||
// A concrete DeathTestFactory implementation for normal use.
|
||||
class DefaultDeathTestFactory : public DeathTestFactory {
|
||||
public:
|
||||
virtual bool Create(const char* statement, const RE* regex,
|
||||
const char* file, int line, DeathTest** test);
|
||||
};
|
||||
|
||||
// Returns true if exit_status describes a process that was terminated
|
||||
// by a signal, or exited normally with a nonzero exit code.
|
||||
GTEST_API_ bool ExitedUnsuccessfully(int exit_status);
|
||||
|
||||
// Traps C++ exceptions escaping statement and reports them as test
|
||||
// failures. Note that trapping SEH exceptions is not implemented here.
|
||||
# if GTEST_HAS_EXCEPTIONS
|
||||
# define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \
|
||||
try { \
|
||||
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
|
||||
} catch (const ::std::exception& gtest_exception) { \
|
||||
fprintf(\
|
||||
stderr, \
|
||||
"\n%s: Caught std::exception-derived exception escaping the " \
|
||||
"death test statement. Exception message: %s\n", \
|
||||
::testing::internal::FormatFileLocation(__FILE__, __LINE__).c_str(), \
|
||||
gtest_exception.what()); \
|
||||
fflush(stderr); \
|
||||
death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \
|
||||
} catch (...) { \
|
||||
death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \
|
||||
}
|
||||
|
||||
# else
|
||||
# define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \
|
||||
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement)
|
||||
|
||||
# endif
|
||||
|
||||
// This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*,
|
||||
// ASSERT_EXIT*, and EXPECT_EXIT*.
|
||||
# define GTEST_DEATH_TEST_(statement, predicate, regex, fail) \
|
||||
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
||||
if (::testing::internal::AlwaysTrue()) { \
|
||||
const ::testing::internal::RE& gtest_regex = (regex); \
|
||||
::testing::internal::DeathTest* gtest_dt; \
|
||||
if (!::testing::internal::DeathTest::Create(#statement, >est_regex, \
|
||||
__FILE__, __LINE__, >est_dt)) { \
|
||||
goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \
|
||||
} \
|
||||
if (gtest_dt != NULL) { \
|
||||
::testing::internal::scoped_ptr< ::testing::internal::DeathTest> \
|
||||
gtest_dt_ptr(gtest_dt); \
|
||||
switch (gtest_dt->AssumeRole()) { \
|
||||
case ::testing::internal::DeathTest::OVERSEE_TEST: \
|
||||
if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \
|
||||
goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \
|
||||
} \
|
||||
break; \
|
||||
case ::testing::internal::DeathTest::EXECUTE_TEST: { \
|
||||
::testing::internal::DeathTest::ReturnSentinel \
|
||||
gtest_sentinel(gtest_dt); \
|
||||
GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt); \
|
||||
gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \
|
||||
break; \
|
||||
} \
|
||||
default: \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} else \
|
||||
GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__): \
|
||||
fail(::testing::internal::DeathTest::LastMessage())
|
||||
// The symbol "fail" here expands to something into which a message
|
||||
// can be streamed.
|
||||
|
||||
// This macro is for implementing ASSERT/EXPECT_DEBUG_DEATH when compiled in
|
||||
// NDEBUG mode. In this case we need the statements to be executed, the regex is
|
||||
// ignored, and the macro must accept a streamed message even though the message
|
||||
// is never printed.
|
||||
# define GTEST_EXECUTE_STATEMENT_(statement, regex) \
|
||||
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
||||
if (::testing::internal::AlwaysTrue()) { \
|
||||
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
|
||||
} else \
|
||||
::testing::Message()
|
||||
|
||||
// A class representing the parsed contents of the
|
||||
// --gtest_internal_run_death_test flag, as it existed when
|
||||
// RUN_ALL_TESTS was called.
|
||||
class InternalRunDeathTestFlag {
|
||||
public:
|
||||
InternalRunDeathTestFlag(const std::string& a_file,
|
||||
int a_line,
|
||||
int an_index,
|
||||
int a_write_fd)
|
||||
: file_(a_file), line_(a_line), index_(an_index),
|
||||
write_fd_(a_write_fd) {}
|
||||
|
||||
~InternalRunDeathTestFlag() {
|
||||
if (write_fd_ >= 0)
|
||||
posix::Close(write_fd_);
|
||||
}
|
||||
|
||||
const std::string& file() const { return file_; }
|
||||
int line() const { return line_; }
|
||||
int index() const { return index_; }
|
||||
int write_fd() const { return write_fd_; }
|
||||
|
||||
private:
|
||||
std::string file_;
|
||||
int line_;
|
||||
int index_;
|
||||
int write_fd_;
|
||||
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(InternalRunDeathTestFlag);
|
||||
};
|
||||
|
||||
// Returns a newly created InternalRunDeathTestFlag object with fields
|
||||
// initialized from the GTEST_FLAG(internal_run_death_test) flag if
|
||||
// the flag is specified; otherwise returns NULL.
|
||||
InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag();
|
||||
|
||||
#else // GTEST_HAS_DEATH_TEST
|
||||
|
||||
// This macro is used for implementing macros such as
|
||||
// EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED on systems where
|
||||
// death tests are not supported. Those macros must compile on such systems
|
||||
// iff EXPECT_DEATH and ASSERT_DEATH compile with the same parameters on
|
||||
// systems that support death tests. This allows one to write such a macro
|
||||
// on a system that does not support death tests and be sure that it will
|
||||
// compile on a death-test supporting system.
|
||||
//
|
||||
// Parameters:
|
||||
// statement - A statement that a macro such as EXPECT_DEATH would test
|
||||
// for program termination. This macro has to make sure this
|
||||
// statement is compiled but not executed, to ensure that
|
||||
// EXPECT_DEATH_IF_SUPPORTED compiles with a certain
|
||||
// parameter iff EXPECT_DEATH compiles with it.
|
||||
// regex - A regex that a macro such as EXPECT_DEATH would use to test
|
||||
// the output of statement. This parameter has to be
|
||||
// compiled but not evaluated by this macro, to ensure that
|
||||
// this macro only accepts expressions that a macro such as
|
||||
// EXPECT_DEATH would accept.
|
||||
// terminator - Must be an empty statement for EXPECT_DEATH_IF_SUPPORTED
|
||||
// and a return statement for ASSERT_DEATH_IF_SUPPORTED.
|
||||
// This ensures that ASSERT_DEATH_IF_SUPPORTED will not
|
||||
// compile inside functions where ASSERT_DEATH doesn't
|
||||
// compile.
|
||||
//
|
||||
// The branch that has an always false condition is used to ensure that
|
||||
// statement and regex are compiled (and thus syntactically correct) but
|
||||
// never executed. The unreachable code macro protects the terminator
|
||||
// statement from generating an 'unreachable code' warning in case
|
||||
// statement unconditionally returns or throws. The Message constructor at
|
||||
// the end allows the syntax of streaming additional messages into the
|
||||
// macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH.
|
||||
# define GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, terminator) \
|
||||
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
||||
if (::testing::internal::AlwaysTrue()) { \
|
||||
GTEST_LOG_(WARNING) \
|
||||
<< "Death tests are not supported on this platform.\n" \
|
||||
<< "Statement '" #statement "' cannot be verified."; \
|
||||
} else if (::testing::internal::AlwaysFalse()) { \
|
||||
::testing::internal::RE::PartialMatch(".*", (regex)); \
|
||||
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
|
||||
terminator; \
|
||||
} else \
|
||||
::testing::Message()
|
||||
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
|
||||
// Copyright 2005, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee)
|
||||
//
|
||||
// The Google C++ Testing Framework (Google Test)
|
||||
//
|
||||
// This header file defines internal utilities needed for implementing
|
||||
// death tests. They are subject to change without notice.
|
||||
|
||||
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
|
||||
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
|
||||
|
||||
#include "gtest/internal/gtest-internal.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
GTEST_DECLARE_string_(internal_run_death_test);
|
||||
|
||||
// Names of the flags (needed for parsing Google Test flags).
|
||||
const char kDeathTestStyleFlag[] = "death_test_style";
|
||||
const char kDeathTestUseFork[] = "death_test_use_fork";
|
||||
const char kInternalRunDeathTestFlag[] = "internal_run_death_test";
|
||||
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
|
||||
// DeathTest is a class that hides much of the complexity of the
|
||||
// GTEST_DEATH_TEST_ macro. It is abstract; its static Create method
|
||||
// returns a concrete class that depends on the prevailing death test
|
||||
// style, as defined by the --gtest_death_test_style and/or
|
||||
// --gtest_internal_run_death_test flags.
|
||||
|
||||
// In describing the results of death tests, these terms are used with
|
||||
// the corresponding definitions:
|
||||
//
|
||||
// exit status: The integer exit information in the format specified
|
||||
// by wait(2)
|
||||
// exit code: The integer code passed to exit(3), _exit(2), or
|
||||
// returned from main()
|
||||
class GTEST_API_ DeathTest {
|
||||
public:
|
||||
// Create returns false if there was an error determining the
|
||||
// appropriate action to take for the current death test; for example,
|
||||
// if the gtest_death_test_style flag is set to an invalid value.
|
||||
// The LastMessage method will return a more detailed message in that
|
||||
// case. Otherwise, the DeathTest pointer pointed to by the "test"
|
||||
// argument is set. If the death test should be skipped, the pointer
|
||||
// is set to NULL; otherwise, it is set to the address of a new concrete
|
||||
// DeathTest object that controls the execution of the current test.
|
||||
static bool Create(const char* statement, const RE* regex,
|
||||
const char* file, int line, DeathTest** test);
|
||||
DeathTest();
|
||||
virtual ~DeathTest() { }
|
||||
|
||||
// A helper class that aborts a death test when it's deleted.
|
||||
class ReturnSentinel {
|
||||
public:
|
||||
explicit ReturnSentinel(DeathTest* test) : test_(test) { }
|
||||
~ReturnSentinel() { test_->Abort(TEST_ENCOUNTERED_RETURN_STATEMENT); }
|
||||
private:
|
||||
DeathTest* const test_;
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(ReturnSentinel);
|
||||
} GTEST_ATTRIBUTE_UNUSED_;
|
||||
|
||||
// An enumeration of possible roles that may be taken when a death
|
||||
// test is encountered. EXECUTE means that the death test logic should
|
||||
// be executed immediately. OVERSEE means that the program should prepare
|
||||
// the appropriate environment for a child process to execute the death
|
||||
// test, then wait for it to complete.
|
||||
enum TestRole { OVERSEE_TEST, EXECUTE_TEST };
|
||||
|
||||
// An enumeration of the three reasons that a test might be aborted.
|
||||
enum AbortReason {
|
||||
TEST_ENCOUNTERED_RETURN_STATEMENT,
|
||||
TEST_THREW_EXCEPTION,
|
||||
TEST_DID_NOT_DIE
|
||||
};
|
||||
|
||||
// Assumes one of the above roles.
|
||||
virtual TestRole AssumeRole() = 0;
|
||||
|
||||
// Waits for the death test to finish and returns its status.
|
||||
virtual int Wait() = 0;
|
||||
|
||||
// Returns true if the death test passed; that is, the test process
|
||||
// exited during the test, its exit status matches a user-supplied
|
||||
// predicate, and its stderr output matches a user-supplied regular
|
||||
// expression.
|
||||
// The user-supplied predicate may be a macro expression rather
|
||||
// than a function pointer or functor, or else Wait and Passed could
|
||||
// be combined.
|
||||
virtual bool Passed(bool exit_status_ok) = 0;
|
||||
|
||||
// Signals that the death test did not die as expected.
|
||||
virtual void Abort(AbortReason reason) = 0;
|
||||
|
||||
// Returns a human-readable outcome message regarding the outcome of
|
||||
// the last death test.
|
||||
static const char* LastMessage();
|
||||
|
||||
static void set_last_death_test_message(const std::string& message);
|
||||
|
||||
private:
|
||||
// A string containing a description of the outcome of the last death test.
|
||||
static std::string last_death_test_message_;
|
||||
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(DeathTest);
|
||||
};
|
||||
|
||||
// Factory interface for death tests. May be mocked out for testing.
|
||||
class DeathTestFactory {
|
||||
public:
|
||||
virtual ~DeathTestFactory() { }
|
||||
virtual bool Create(const char* statement, const RE* regex,
|
||||
const char* file, int line, DeathTest** test) = 0;
|
||||
};
|
||||
|
||||
// A concrete DeathTestFactory implementation for normal use.
|
||||
class DefaultDeathTestFactory : public DeathTestFactory {
|
||||
public:
|
||||
virtual bool Create(const char* statement, const RE* regex,
|
||||
const char* file, int line, DeathTest** test);
|
||||
};
|
||||
|
||||
// Returns true if exit_status describes a process that was terminated
|
||||
// by a signal, or exited normally with a nonzero exit code.
|
||||
GTEST_API_ bool ExitedUnsuccessfully(int exit_status);
|
||||
|
||||
// Traps C++ exceptions escaping statement and reports them as test
|
||||
// failures. Note that trapping SEH exceptions is not implemented here.
|
||||
# if GTEST_HAS_EXCEPTIONS
|
||||
# define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \
|
||||
try { \
|
||||
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
|
||||
} catch (const ::std::exception& gtest_exception) { \
|
||||
fprintf(\
|
||||
stderr, \
|
||||
"\n%s: Caught std::exception-derived exception escaping the " \
|
||||
"death test statement. Exception message: %s\n", \
|
||||
::testing::internal::FormatFileLocation(__FILE__, __LINE__).c_str(), \
|
||||
gtest_exception.what()); \
|
||||
fflush(stderr); \
|
||||
death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \
|
||||
} catch (...) { \
|
||||
death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \
|
||||
}
|
||||
|
||||
# else
|
||||
# define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \
|
||||
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement)
|
||||
|
||||
# endif
|
||||
|
||||
// This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*,
|
||||
// ASSERT_EXIT*, and EXPECT_EXIT*.
|
||||
# define GTEST_DEATH_TEST_(statement, predicate, regex, fail) \
|
||||
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
||||
if (::testing::internal::AlwaysTrue()) { \
|
||||
const ::testing::internal::RE& gtest_regex = (regex); \
|
||||
::testing::internal::DeathTest* gtest_dt; \
|
||||
if (!::testing::internal::DeathTest::Create(#statement, >est_regex, \
|
||||
__FILE__, __LINE__, >est_dt)) { \
|
||||
goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \
|
||||
} \
|
||||
if (gtest_dt != NULL) { \
|
||||
::testing::internal::scoped_ptr< ::testing::internal::DeathTest> \
|
||||
gtest_dt_ptr(gtest_dt); \
|
||||
switch (gtest_dt->AssumeRole()) { \
|
||||
case ::testing::internal::DeathTest::OVERSEE_TEST: \
|
||||
if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \
|
||||
goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \
|
||||
} \
|
||||
break; \
|
||||
case ::testing::internal::DeathTest::EXECUTE_TEST: { \
|
||||
::testing::internal::DeathTest::ReturnSentinel \
|
||||
gtest_sentinel(gtest_dt); \
|
||||
GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt); \
|
||||
gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \
|
||||
break; \
|
||||
} \
|
||||
default: \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} else \
|
||||
GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__): \
|
||||
fail(::testing::internal::DeathTest::LastMessage())
|
||||
// The symbol "fail" here expands to something into which a message
|
||||
// can be streamed.
|
||||
|
||||
// This macro is for implementing ASSERT/EXPECT_DEBUG_DEATH when compiled in
|
||||
// NDEBUG mode. In this case we need the statements to be executed, the regex is
|
||||
// ignored, and the macro must accept a streamed message even though the message
|
||||
// is never printed.
|
||||
# define GTEST_EXECUTE_STATEMENT_(statement, regex) \
|
||||
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
||||
if (::testing::internal::AlwaysTrue()) { \
|
||||
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
|
||||
} else \
|
||||
::testing::Message()
|
||||
|
||||
// A class representing the parsed contents of the
|
||||
// --gtest_internal_run_death_test flag, as it existed when
|
||||
// RUN_ALL_TESTS was called.
|
||||
class InternalRunDeathTestFlag {
|
||||
public:
|
||||
InternalRunDeathTestFlag(const std::string& a_file,
|
||||
int a_line,
|
||||
int an_index,
|
||||
int a_write_fd)
|
||||
: file_(a_file), line_(a_line), index_(an_index),
|
||||
write_fd_(a_write_fd) {}
|
||||
|
||||
~InternalRunDeathTestFlag() {
|
||||
if (write_fd_ >= 0)
|
||||
posix::Close(write_fd_);
|
||||
}
|
||||
|
||||
const std::string& file() const { return file_; }
|
||||
int line() const { return line_; }
|
||||
int index() const { return index_; }
|
||||
int write_fd() const { return write_fd_; }
|
||||
|
||||
private:
|
||||
std::string file_;
|
||||
int line_;
|
||||
int index_;
|
||||
int write_fd_;
|
||||
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(InternalRunDeathTestFlag);
|
||||
};
|
||||
|
||||
// Returns a newly created InternalRunDeathTestFlag object with fields
|
||||
// initialized from the GTEST_FLAG(internal_run_death_test) flag if
|
||||
// the flag is specified; otherwise returns NULL.
|
||||
InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag();
|
||||
|
||||
#else // GTEST_HAS_DEATH_TEST
|
||||
|
||||
// This macro is used for implementing macros such as
|
||||
// EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED on systems where
|
||||
// death tests are not supported. Those macros must compile on such systems
|
||||
// iff EXPECT_DEATH and ASSERT_DEATH compile with the same parameters on
|
||||
// systems that support death tests. This allows one to write such a macro
|
||||
// on a system that does not support death tests and be sure that it will
|
||||
// compile on a death-test supporting system.
|
||||
//
|
||||
// Parameters:
|
||||
// statement - A statement that a macro such as EXPECT_DEATH would test
|
||||
// for program termination. This macro has to make sure this
|
||||
// statement is compiled but not executed, to ensure that
|
||||
// EXPECT_DEATH_IF_SUPPORTED compiles with a certain
|
||||
// parameter iff EXPECT_DEATH compiles with it.
|
||||
// regex - A regex that a macro such as EXPECT_DEATH would use to test
|
||||
// the output of statement. This parameter has to be
|
||||
// compiled but not evaluated by this macro, to ensure that
|
||||
// this macro only accepts expressions that a macro such as
|
||||
// EXPECT_DEATH would accept.
|
||||
// terminator - Must be an empty statement for EXPECT_DEATH_IF_SUPPORTED
|
||||
// and a return statement for ASSERT_DEATH_IF_SUPPORTED.
|
||||
// This ensures that ASSERT_DEATH_IF_SUPPORTED will not
|
||||
// compile inside functions where ASSERT_DEATH doesn't
|
||||
// compile.
|
||||
//
|
||||
// The branch that has an always false condition is used to ensure that
|
||||
// statement and regex are compiled (and thus syntactically correct) but
|
||||
// never executed. The unreachable code macro protects the terminator
|
||||
// statement from generating an 'unreachable code' warning in case
|
||||
// statement unconditionally returns or throws. The Message constructor at
|
||||
// the end allows the syntax of streaming additional messages into the
|
||||
// macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH.
|
||||
# define GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, terminator) \
|
||||
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
||||
if (::testing::internal::AlwaysTrue()) { \
|
||||
GTEST_LOG_(WARNING) \
|
||||
<< "Death tests are not supported on this platform.\n" \
|
||||
<< "Statement '" #statement "' cannot be verified."; \
|
||||
} else if (::testing::internal::AlwaysFalse()) { \
|
||||
::testing::internal::RE::PartialMatch(".*", (regex)); \
|
||||
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
|
||||
terminator; \
|
||||
} else \
|
||||
::testing::Message()
|
||||
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
|
||||
@@ -1,206 +1,206 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: keith.ray@gmail.com (Keith Ray)
|
||||
//
|
||||
// Google Test filepath utilities
|
||||
//
|
||||
// This header file declares classes and functions used internally by
|
||||
// Google Test. They are subject to change without notice.
|
||||
//
|
||||
// This file is #included in <gtest/internal/gtest-internal.h>.
|
||||
// Do not include this header file separately!
|
||||
|
||||
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
|
||||
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
|
||||
|
||||
#include "gtest/internal/gtest-string.h"
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// FilePath - a class for file and directory pathname manipulation which
|
||||
// handles platform-specific conventions (like the pathname separator).
|
||||
// Used for helper functions for naming files in a directory for xml output.
|
||||
// Except for Set methods, all methods are const or static, which provides an
|
||||
// "immutable value object" -- useful for peace of mind.
|
||||
// A FilePath with a value ending in a path separator ("like/this/") represents
|
||||
// a directory, otherwise it is assumed to represent a file. In either case,
|
||||
// it may or may not represent an actual file or directory in the file system.
|
||||
// Names are NOT checked for syntax correctness -- no checking for illegal
|
||||
// characters, malformed paths, etc.
|
||||
|
||||
class GTEST_API_ FilePath {
|
||||
public:
|
||||
FilePath() : pathname_("") { }
|
||||
FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) { }
|
||||
|
||||
explicit FilePath(const std::string& pathname) : pathname_(pathname) {
|
||||
Normalize();
|
||||
}
|
||||
|
||||
FilePath& operator=(const FilePath& rhs) {
|
||||
Set(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Set(const FilePath& rhs) {
|
||||
pathname_ = rhs.pathname_;
|
||||
}
|
||||
|
||||
const std::string& string() const { return pathname_; }
|
||||
const char* c_str() const { return pathname_.c_str(); }
|
||||
|
||||
// Returns the current working directory, or "" if unsuccessful.
|
||||
static FilePath GetCurrentDir();
|
||||
|
||||
// Given directory = "dir", base_name = "test", number = 0,
|
||||
// extension = "xml", returns "dir/test.xml". If number is greater
|
||||
// than zero (e.g., 12), returns "dir/test_12.xml".
|
||||
// On Windows platform, uses \ as the separator rather than /.
|
||||
static FilePath MakeFileName(const FilePath& directory,
|
||||
const FilePath& base_name,
|
||||
int number,
|
||||
const char* extension);
|
||||
|
||||
// Given directory = "dir", relative_path = "test.xml",
|
||||
// returns "dir/test.xml".
|
||||
// On Windows, uses \ as the separator rather than /.
|
||||
static FilePath ConcatPaths(const FilePath& directory,
|
||||
const FilePath& relative_path);
|
||||
|
||||
// Returns a pathname for a file that does not currently exist. The pathname
|
||||
// will be directory/base_name.extension or
|
||||
// directory/base_name_<number>.extension if directory/base_name.extension
|
||||
// already exists. The number will be incremented until a pathname is found
|
||||
// that does not already exist.
|
||||
// Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'.
|
||||
// There could be a race condition if two or more processes are calling this
|
||||
// function at the same time -- they could both pick the same filename.
|
||||
static FilePath GenerateUniqueFileName(const FilePath& directory,
|
||||
const FilePath& base_name,
|
||||
const char* extension);
|
||||
|
||||
// Returns true iff the path is "".
|
||||
bool IsEmpty() const { return pathname_.empty(); }
|
||||
|
||||
// If input name has a trailing separator character, removes it and returns
|
||||
// the name, otherwise return the name string unmodified.
|
||||
// On Windows platform, uses \ as the separator, other platforms use /.
|
||||
FilePath RemoveTrailingPathSeparator() const;
|
||||
|
||||
// Returns a copy of the FilePath with the directory part removed.
|
||||
// Example: FilePath("path/to/file").RemoveDirectoryName() returns
|
||||
// FilePath("file"). If there is no directory part ("just_a_file"), it returns
|
||||
// the FilePath unmodified. If there is no file part ("just_a_dir/") it
|
||||
// returns an empty FilePath ("").
|
||||
// On Windows platform, '\' is the path separator, otherwise it is '/'.
|
||||
FilePath RemoveDirectoryName() const;
|
||||
|
||||
// RemoveFileName returns the directory path with the filename removed.
|
||||
// Example: FilePath("path/to/file").RemoveFileName() returns "path/to/".
|
||||
// If the FilePath is "a_file" or "/a_file", RemoveFileName returns
|
||||
// FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does
|
||||
// not have a file, like "just/a/dir/", it returns the FilePath unmodified.
|
||||
// On Windows platform, '\' is the path separator, otherwise it is '/'.
|
||||
FilePath RemoveFileName() const;
|
||||
|
||||
// Returns a copy of the FilePath with the case-insensitive extension removed.
|
||||
// Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns
|
||||
// FilePath("dir/file"). If a case-insensitive extension is not
|
||||
// found, returns a copy of the original FilePath.
|
||||
FilePath RemoveExtension(const char* extension) const;
|
||||
|
||||
// Creates directories so that path exists. Returns true if successful or if
|
||||
// the directories already exist; returns false if unable to create
|
||||
// directories for any reason. Will also return false if the FilePath does
|
||||
// not represent a directory (that is, it doesn't end with a path separator).
|
||||
bool CreateDirectoriesRecursively() const;
|
||||
|
||||
// Create the directory so that path exists. Returns true if successful or
|
||||
// if the directory already exists; returns false if unable to create the
|
||||
// directory for any reason, including if the parent directory does not
|
||||
// exist. Not named "CreateDirectory" because that's a macro on Windows.
|
||||
bool CreateFolder() const;
|
||||
|
||||
// Returns true if FilePath describes something in the file-system,
|
||||
// either a file, directory, or whatever, and that something exists.
|
||||
bool FileOrDirectoryExists() const;
|
||||
|
||||
// Returns true if pathname describes a directory in the file-system
|
||||
// that exists.
|
||||
bool DirectoryExists() const;
|
||||
|
||||
// Returns true if FilePath ends with a path separator, which indicates that
|
||||
// it is intended to represent a directory. Returns false otherwise.
|
||||
// This does NOT check that a directory (or file) actually exists.
|
||||
bool IsDirectory() const;
|
||||
|
||||
// Returns true if pathname describes a root directory. (Windows has one
|
||||
// root directory per disk drive.)
|
||||
bool IsRootDirectory() const;
|
||||
|
||||
// Returns true if pathname describes an absolute path.
|
||||
bool IsAbsolutePath() const;
|
||||
|
||||
private:
|
||||
// Replaces multiple consecutive separators with a single separator.
|
||||
// For example, "bar///foo" becomes "bar/foo". Does not eliminate other
|
||||
// redundancies that might be in a pathname involving "." or "..".
|
||||
//
|
||||
// A pathname with multiple consecutive separators may occur either through
|
||||
// user error or as a result of some scripts or APIs that generate a pathname
|
||||
// with a trailing separator. On other platforms the same API or script
|
||||
// may NOT generate a pathname with a trailing "/". Then elsewhere that
|
||||
// pathname may have another "/" and pathname components added to it,
|
||||
// without checking for the separator already being there.
|
||||
// The script language and operating system may allow paths like "foo//bar"
|
||||
// but some of the functions in FilePath will not handle that correctly. In
|
||||
// particular, RemoveTrailingPathSeparator() only removes one separator, and
|
||||
// it is called in CreateDirectoriesRecursively() assuming that it will change
|
||||
// a pathname from directory syntax (trailing separator) to filename syntax.
|
||||
//
|
||||
// On Windows this method also replaces the alternate path separator '/' with
|
||||
// the primary path separator '\\', so that for example "bar\\/\\foo" becomes
|
||||
// "bar\\foo".
|
||||
|
||||
void Normalize();
|
||||
|
||||
// Returns a pointer to the last occurence of a valid path separator in
|
||||
// the FilePath. On Windows, for example, both '/' and '\' are valid path
|
||||
// separators. Returns NULL if no path separator was found.
|
||||
const char* FindLastPathSeparator() const;
|
||||
|
||||
std::string pathname_;
|
||||
}; // class FilePath
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: keith.ray@gmail.com (Keith Ray)
|
||||
//
|
||||
// Google Test filepath utilities
|
||||
//
|
||||
// This header file declares classes and functions used internally by
|
||||
// Google Test. They are subject to change without notice.
|
||||
//
|
||||
// This file is #included in <gtest/internal/gtest-internal.h>.
|
||||
// Do not include this header file separately!
|
||||
|
||||
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
|
||||
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
|
||||
|
||||
#include "gtest/internal/gtest-string.h"
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// FilePath - a class for file and directory pathname manipulation which
|
||||
// handles platform-specific conventions (like the pathname separator).
|
||||
// Used for helper functions for naming files in a directory for xml output.
|
||||
// Except for Set methods, all methods are const or static, which provides an
|
||||
// "immutable value object" -- useful for peace of mind.
|
||||
// A FilePath with a value ending in a path separator ("like/this/") represents
|
||||
// a directory, otherwise it is assumed to represent a file. In either case,
|
||||
// it may or may not represent an actual file or directory in the file system.
|
||||
// Names are NOT checked for syntax correctness -- no checking for illegal
|
||||
// characters, malformed paths, etc.
|
||||
|
||||
class GTEST_API_ FilePath {
|
||||
public:
|
||||
FilePath() : pathname_("") { }
|
||||
FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) { }
|
||||
|
||||
explicit FilePath(const std::string& pathname) : pathname_(pathname) {
|
||||
Normalize();
|
||||
}
|
||||
|
||||
FilePath& operator=(const FilePath& rhs) {
|
||||
Set(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Set(const FilePath& rhs) {
|
||||
pathname_ = rhs.pathname_;
|
||||
}
|
||||
|
||||
const std::string& string() const { return pathname_; }
|
||||
const char* c_str() const { return pathname_.c_str(); }
|
||||
|
||||
// Returns the current working directory, or "" if unsuccessful.
|
||||
static FilePath GetCurrentDir();
|
||||
|
||||
// Given directory = "dir", base_name = "test", number = 0,
|
||||
// extension = "xml", returns "dir/test.xml". If number is greater
|
||||
// than zero (e.g., 12), returns "dir/test_12.xml".
|
||||
// On Windows platform, uses \ as the separator rather than /.
|
||||
static FilePath MakeFileName(const FilePath& directory,
|
||||
const FilePath& base_name,
|
||||
int number,
|
||||
const char* extension);
|
||||
|
||||
// Given directory = "dir", relative_path = "test.xml",
|
||||
// returns "dir/test.xml".
|
||||
// On Windows, uses \ as the separator rather than /.
|
||||
static FilePath ConcatPaths(const FilePath& directory,
|
||||
const FilePath& relative_path);
|
||||
|
||||
// Returns a pathname for a file that does not currently exist. The pathname
|
||||
// will be directory/base_name.extension or
|
||||
// directory/base_name_<number>.extension if directory/base_name.extension
|
||||
// already exists. The number will be incremented until a pathname is found
|
||||
// that does not already exist.
|
||||
// Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'.
|
||||
// There could be a race condition if two or more processes are calling this
|
||||
// function at the same time -- they could both pick the same filename.
|
||||
static FilePath GenerateUniqueFileName(const FilePath& directory,
|
||||
const FilePath& base_name,
|
||||
const char* extension);
|
||||
|
||||
// Returns true iff the path is "".
|
||||
bool IsEmpty() const { return pathname_.empty(); }
|
||||
|
||||
// If input name has a trailing separator character, removes it and returns
|
||||
// the name, otherwise return the name string unmodified.
|
||||
// On Windows platform, uses \ as the separator, other platforms use /.
|
||||
FilePath RemoveTrailingPathSeparator() const;
|
||||
|
||||
// Returns a copy of the FilePath with the directory part removed.
|
||||
// Example: FilePath("path/to/file").RemoveDirectoryName() returns
|
||||
// FilePath("file"). If there is no directory part ("just_a_file"), it returns
|
||||
// the FilePath unmodified. If there is no file part ("just_a_dir/") it
|
||||
// returns an empty FilePath ("").
|
||||
// On Windows platform, '\' is the path separator, otherwise it is '/'.
|
||||
FilePath RemoveDirectoryName() const;
|
||||
|
||||
// RemoveFileName returns the directory path with the filename removed.
|
||||
// Example: FilePath("path/to/file").RemoveFileName() returns "path/to/".
|
||||
// If the FilePath is "a_file" or "/a_file", RemoveFileName returns
|
||||
// FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does
|
||||
// not have a file, like "just/a/dir/", it returns the FilePath unmodified.
|
||||
// On Windows platform, '\' is the path separator, otherwise it is '/'.
|
||||
FilePath RemoveFileName() const;
|
||||
|
||||
// Returns a copy of the FilePath with the case-insensitive extension removed.
|
||||
// Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns
|
||||
// FilePath("dir/file"). If a case-insensitive extension is not
|
||||
// found, returns a copy of the original FilePath.
|
||||
FilePath RemoveExtension(const char* extension) const;
|
||||
|
||||
// Creates directories so that path exists. Returns true if successful or if
|
||||
// the directories already exist; returns false if unable to create
|
||||
// directories for any reason. Will also return false if the FilePath does
|
||||
// not represent a directory (that is, it doesn't end with a path separator).
|
||||
bool CreateDirectoriesRecursively() const;
|
||||
|
||||
// Create the directory so that path exists. Returns true if successful or
|
||||
// if the directory already exists; returns false if unable to create the
|
||||
// directory for any reason, including if the parent directory does not
|
||||
// exist. Not named "CreateDirectory" because that's a macro on Windows.
|
||||
bool CreateFolder() const;
|
||||
|
||||
// Returns true if FilePath describes something in the file-system,
|
||||
// either a file, directory, or whatever, and that something exists.
|
||||
bool FileOrDirectoryExists() const;
|
||||
|
||||
// Returns true if pathname describes a directory in the file-system
|
||||
// that exists.
|
||||
bool DirectoryExists() const;
|
||||
|
||||
// Returns true if FilePath ends with a path separator, which indicates that
|
||||
// it is intended to represent a directory. Returns false otherwise.
|
||||
// This does NOT check that a directory (or file) actually exists.
|
||||
bool IsDirectory() const;
|
||||
|
||||
// Returns true if pathname describes a root directory. (Windows has one
|
||||
// root directory per disk drive.)
|
||||
bool IsRootDirectory() const;
|
||||
|
||||
// Returns true if pathname describes an absolute path.
|
||||
bool IsAbsolutePath() const;
|
||||
|
||||
private:
|
||||
// Replaces multiple consecutive separators with a single separator.
|
||||
// For example, "bar///foo" becomes "bar/foo". Does not eliminate other
|
||||
// redundancies that might be in a pathname involving "." or "..".
|
||||
//
|
||||
// A pathname with multiple consecutive separators may occur either through
|
||||
// user error or as a result of some scripts or APIs that generate a pathname
|
||||
// with a trailing separator. On other platforms the same API or script
|
||||
// may NOT generate a pathname with a trailing "/". Then elsewhere that
|
||||
// pathname may have another "/" and pathname components added to it,
|
||||
// without checking for the separator already being there.
|
||||
// The script language and operating system may allow paths like "foo//bar"
|
||||
// but some of the functions in FilePath will not handle that correctly. In
|
||||
// particular, RemoveTrailingPathSeparator() only removes one separator, and
|
||||
// it is called in CreateDirectoriesRecursively() assuming that it will change
|
||||
// a pathname from directory syntax (trailing separator) to filename syntax.
|
||||
//
|
||||
// On Windows this method also replaces the alternate path separator '/' with
|
||||
// the primary path separator '\\', so that for example "bar\\/\\foo" becomes
|
||||
// "bar\\foo".
|
||||
|
||||
void Normalize();
|
||||
|
||||
// Returns a pointer to the last occurence of a valid path separator in
|
||||
// the FilePath. On Windows, for example, both '/' and '\' are valid path
|
||||
// separators. Returns NULL if no path separator was found.
|
||||
const char* FindLastPathSeparator() const;
|
||||
|
||||
std::string pathname_;
|
||||
}; // class FilePath
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,233 +1,233 @@
|
||||
// Copyright 2003 Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Authors: Dan Egnor (egnor@google.com)
|
||||
//
|
||||
// A "smart" pointer type with reference tracking. Every pointer to a
|
||||
// particular object is kept on a circular linked list. When the last pointer
|
||||
// to an object is destroyed or reassigned, the object is deleted.
|
||||
//
|
||||
// Used properly, this deletes the object when the last reference goes away.
|
||||
// There are several caveats:
|
||||
// - Like all reference counting schemes, cycles lead to leaks.
|
||||
// - Each smart pointer is actually two pointers (8 bytes instead of 4).
|
||||
// - Every time a pointer is assigned, the entire list of pointers to that
|
||||
// object is traversed. This class is therefore NOT SUITABLE when there
|
||||
// will often be more than two or three pointers to a particular object.
|
||||
// - References are only tracked as long as linked_ptr<> objects are copied.
|
||||
// If a linked_ptr<> is converted to a raw pointer and back, BAD THINGS
|
||||
// will happen (double deletion).
|
||||
//
|
||||
// A good use of this class is storing object references in STL containers.
|
||||
// You can safely put linked_ptr<> in a vector<>.
|
||||
// Other uses may not be as good.
|
||||
//
|
||||
// Note: If you use an incomplete type with linked_ptr<>, the class
|
||||
// *containing* linked_ptr<> must have a constructor and destructor (even
|
||||
// if they do nothing!).
|
||||
//
|
||||
// Bill Gibbons suggested we use something like this.
|
||||
//
|
||||
// Thread Safety:
|
||||
// Unlike other linked_ptr implementations, in this implementation
|
||||
// a linked_ptr object is thread-safe in the sense that:
|
||||
// - it's safe to copy linked_ptr objects concurrently,
|
||||
// - it's safe to copy *from* a linked_ptr and read its underlying
|
||||
// raw pointer (e.g. via get()) concurrently, and
|
||||
// - it's safe to write to two linked_ptrs that point to the same
|
||||
// shared object concurrently.
|
||||
// TODO(wan@google.com): rename this to safe_linked_ptr to avoid
|
||||
// confusion with normal linked_ptr.
|
||||
|
||||
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_
|
||||
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// Protects copying of all linked_ptr objects.
|
||||
GTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_linked_ptr_mutex);
|
||||
|
||||
// This is used internally by all instances of linked_ptr<>. It needs to be
|
||||
// a non-template class because different types of linked_ptr<> can refer to
|
||||
// the same object (linked_ptr<Superclass>(obj) vs linked_ptr<Subclass>(obj)).
|
||||
// So, it needs to be possible for different types of linked_ptr to participate
|
||||
// in the same circular linked list, so we need a single class type here.
|
||||
//
|
||||
// DO NOT USE THIS CLASS DIRECTLY YOURSELF. Use linked_ptr<T>.
|
||||
class linked_ptr_internal {
|
||||
public:
|
||||
// Create a new circle that includes only this instance.
|
||||
void join_new() {
|
||||
next_ = this;
|
||||
}
|
||||
|
||||
// Many linked_ptr operations may change p.link_ for some linked_ptr
|
||||
// variable p in the same circle as this object. Therefore we need
|
||||
// to prevent two such operations from occurring concurrently.
|
||||
//
|
||||
// Note that different types of linked_ptr objects can coexist in a
|
||||
// circle (e.g. linked_ptr<Base>, linked_ptr<Derived1>, and
|
||||
// linked_ptr<Derived2>). Therefore we must use a single mutex to
|
||||
// protect all linked_ptr objects. This can create serious
|
||||
// contention in production code, but is acceptable in a testing
|
||||
// framework.
|
||||
|
||||
// Join an existing circle.
|
||||
void join(linked_ptr_internal const* ptr)
|
||||
GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) {
|
||||
MutexLock lock(&g_linked_ptr_mutex);
|
||||
|
||||
linked_ptr_internal const* p = ptr;
|
||||
while (p->next_ != ptr) p = p->next_;
|
||||
p->next_ = this;
|
||||
next_ = ptr;
|
||||
}
|
||||
|
||||
// Leave whatever circle we're part of. Returns true if we were the
|
||||
// last member of the circle. Once this is done, you can join() another.
|
||||
bool depart()
|
||||
GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) {
|
||||
MutexLock lock(&g_linked_ptr_mutex);
|
||||
|
||||
if (next_ == this) return true;
|
||||
linked_ptr_internal const* p = next_;
|
||||
while (p->next_ != this) p = p->next_;
|
||||
p->next_ = next_;
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
mutable linked_ptr_internal const* next_;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class linked_ptr {
|
||||
public:
|
||||
typedef T element_type;
|
||||
|
||||
// Take over ownership of a raw pointer. This should happen as soon as
|
||||
// possible after the object is created.
|
||||
explicit linked_ptr(T* ptr = NULL) { capture(ptr); }
|
||||
~linked_ptr() { depart(); }
|
||||
|
||||
// Copy an existing linked_ptr<>, adding ourselves to the list of references.
|
||||
template <typename U> linked_ptr(linked_ptr<U> const& ptr) { copy(&ptr); }
|
||||
linked_ptr(linked_ptr const& ptr) { // NOLINT
|
||||
assert(&ptr != this);
|
||||
copy(&ptr);
|
||||
}
|
||||
|
||||
// Assignment releases the old value and acquires the new.
|
||||
template <typename U> linked_ptr& operator=(linked_ptr<U> const& ptr) {
|
||||
depart();
|
||||
copy(&ptr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
linked_ptr& operator=(linked_ptr const& ptr) {
|
||||
if (&ptr != this) {
|
||||
depart();
|
||||
copy(&ptr);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Smart pointer members.
|
||||
void reset(T* ptr = NULL) {
|
||||
depart();
|
||||
capture(ptr);
|
||||
}
|
||||
T* get() const { return value_; }
|
||||
T* operator->() const { return value_; }
|
||||
T& operator*() const { return *value_; }
|
||||
|
||||
bool operator==(T* p) const { return value_ == p; }
|
||||
bool operator!=(T* p) const { return value_ != p; }
|
||||
template <typename U>
|
||||
bool operator==(linked_ptr<U> const& ptr) const {
|
||||
return value_ == ptr.get();
|
||||
}
|
||||
template <typename U>
|
||||
bool operator!=(linked_ptr<U> const& ptr) const {
|
||||
return value_ != ptr.get();
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename U>
|
||||
friend class linked_ptr;
|
||||
|
||||
T* value_;
|
||||
linked_ptr_internal link_;
|
||||
|
||||
void depart() {
|
||||
if (link_.depart()) delete value_;
|
||||
}
|
||||
|
||||
void capture(T* ptr) {
|
||||
value_ = ptr;
|
||||
link_.join_new();
|
||||
}
|
||||
|
||||
template <typename U> void copy(linked_ptr<U> const* ptr) {
|
||||
value_ = ptr->get();
|
||||
if (value_)
|
||||
link_.join(&ptr->link_);
|
||||
else
|
||||
link_.join_new();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T> inline
|
||||
bool operator==(T* ptr, const linked_ptr<T>& x) {
|
||||
return ptr == x.get();
|
||||
}
|
||||
|
||||
template<typename T> inline
|
||||
bool operator!=(T* ptr, const linked_ptr<T>& x) {
|
||||
return ptr != x.get();
|
||||
}
|
||||
|
||||
// A function to convert T* into linked_ptr<T>
|
||||
// Doing e.g. make_linked_ptr(new FooBarBaz<type>(arg)) is a shorter notation
|
||||
// for linked_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg))
|
||||
template <typename T>
|
||||
linked_ptr<T> make_linked_ptr(T* ptr) {
|
||||
return linked_ptr<T>(ptr);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_
|
||||
// Copyright 2003 Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Authors: Dan Egnor (egnor@google.com)
|
||||
//
|
||||
// A "smart" pointer type with reference tracking. Every pointer to a
|
||||
// particular object is kept on a circular linked list. When the last pointer
|
||||
// to an object is destroyed or reassigned, the object is deleted.
|
||||
//
|
||||
// Used properly, this deletes the object when the last reference goes away.
|
||||
// There are several caveats:
|
||||
// - Like all reference counting schemes, cycles lead to leaks.
|
||||
// - Each smart pointer is actually two pointers (8 bytes instead of 4).
|
||||
// - Every time a pointer is assigned, the entire list of pointers to that
|
||||
// object is traversed. This class is therefore NOT SUITABLE when there
|
||||
// will often be more than two or three pointers to a particular object.
|
||||
// - References are only tracked as long as linked_ptr<> objects are copied.
|
||||
// If a linked_ptr<> is converted to a raw pointer and back, BAD THINGS
|
||||
// will happen (double deletion).
|
||||
//
|
||||
// A good use of this class is storing object references in STL containers.
|
||||
// You can safely put linked_ptr<> in a vector<>.
|
||||
// Other uses may not be as good.
|
||||
//
|
||||
// Note: If you use an incomplete type with linked_ptr<>, the class
|
||||
// *containing* linked_ptr<> must have a constructor and destructor (even
|
||||
// if they do nothing!).
|
||||
//
|
||||
// Bill Gibbons suggested we use something like this.
|
||||
//
|
||||
// Thread Safety:
|
||||
// Unlike other linked_ptr implementations, in this implementation
|
||||
// a linked_ptr object is thread-safe in the sense that:
|
||||
// - it's safe to copy linked_ptr objects concurrently,
|
||||
// - it's safe to copy *from* a linked_ptr and read its underlying
|
||||
// raw pointer (e.g. via get()) concurrently, and
|
||||
// - it's safe to write to two linked_ptrs that point to the same
|
||||
// shared object concurrently.
|
||||
// TODO(wan@google.com): rename this to safe_linked_ptr to avoid
|
||||
// confusion with normal linked_ptr.
|
||||
|
||||
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_
|
||||
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// Protects copying of all linked_ptr objects.
|
||||
GTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_linked_ptr_mutex);
|
||||
|
||||
// This is used internally by all instances of linked_ptr<>. It needs to be
|
||||
// a non-template class because different types of linked_ptr<> can refer to
|
||||
// the same object (linked_ptr<Superclass>(obj) vs linked_ptr<Subclass>(obj)).
|
||||
// So, it needs to be possible for different types of linked_ptr to participate
|
||||
// in the same circular linked list, so we need a single class type here.
|
||||
//
|
||||
// DO NOT USE THIS CLASS DIRECTLY YOURSELF. Use linked_ptr<T>.
|
||||
class linked_ptr_internal {
|
||||
public:
|
||||
// Create a new circle that includes only this instance.
|
||||
void join_new() {
|
||||
next_ = this;
|
||||
}
|
||||
|
||||
// Many linked_ptr operations may change p.link_ for some linked_ptr
|
||||
// variable p in the same circle as this object. Therefore we need
|
||||
// to prevent two such operations from occurring concurrently.
|
||||
//
|
||||
// Note that different types of linked_ptr objects can coexist in a
|
||||
// circle (e.g. linked_ptr<Base>, linked_ptr<Derived1>, and
|
||||
// linked_ptr<Derived2>). Therefore we must use a single mutex to
|
||||
// protect all linked_ptr objects. This can create serious
|
||||
// contention in production code, but is acceptable in a testing
|
||||
// framework.
|
||||
|
||||
// Join an existing circle.
|
||||
void join(linked_ptr_internal const* ptr)
|
||||
GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) {
|
||||
MutexLock lock(&g_linked_ptr_mutex);
|
||||
|
||||
linked_ptr_internal const* p = ptr;
|
||||
while (p->next_ != ptr) p = p->next_;
|
||||
p->next_ = this;
|
||||
next_ = ptr;
|
||||
}
|
||||
|
||||
// Leave whatever circle we're part of. Returns true if we were the
|
||||
// last member of the circle. Once this is done, you can join() another.
|
||||
bool depart()
|
||||
GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) {
|
||||
MutexLock lock(&g_linked_ptr_mutex);
|
||||
|
||||
if (next_ == this) return true;
|
||||
linked_ptr_internal const* p = next_;
|
||||
while (p->next_ != this) p = p->next_;
|
||||
p->next_ = next_;
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
mutable linked_ptr_internal const* next_;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class linked_ptr {
|
||||
public:
|
||||
typedef T element_type;
|
||||
|
||||
// Take over ownership of a raw pointer. This should happen as soon as
|
||||
// possible after the object is created.
|
||||
explicit linked_ptr(T* ptr = NULL) { capture(ptr); }
|
||||
~linked_ptr() { depart(); }
|
||||
|
||||
// Copy an existing linked_ptr<>, adding ourselves to the list of references.
|
||||
template <typename U> linked_ptr(linked_ptr<U> const& ptr) { copy(&ptr); }
|
||||
linked_ptr(linked_ptr const& ptr) { // NOLINT
|
||||
assert(&ptr != this);
|
||||
copy(&ptr);
|
||||
}
|
||||
|
||||
// Assignment releases the old value and acquires the new.
|
||||
template <typename U> linked_ptr& operator=(linked_ptr<U> const& ptr) {
|
||||
depart();
|
||||
copy(&ptr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
linked_ptr& operator=(linked_ptr const& ptr) {
|
||||
if (&ptr != this) {
|
||||
depart();
|
||||
copy(&ptr);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Smart pointer members.
|
||||
void reset(T* ptr = NULL) {
|
||||
depart();
|
||||
capture(ptr);
|
||||
}
|
||||
T* get() const { return value_; }
|
||||
T* operator->() const { return value_; }
|
||||
T& operator*() const { return *value_; }
|
||||
|
||||
bool operator==(T* p) const { return value_ == p; }
|
||||
bool operator!=(T* p) const { return value_ != p; }
|
||||
template <typename U>
|
||||
bool operator==(linked_ptr<U> const& ptr) const {
|
||||
return value_ == ptr.get();
|
||||
}
|
||||
template <typename U>
|
||||
bool operator!=(linked_ptr<U> const& ptr) const {
|
||||
return value_ != ptr.get();
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename U>
|
||||
friend class linked_ptr;
|
||||
|
||||
T* value_;
|
||||
linked_ptr_internal link_;
|
||||
|
||||
void depart() {
|
||||
if (link_.depart()) delete value_;
|
||||
}
|
||||
|
||||
void capture(T* ptr) {
|
||||
value_ = ptr;
|
||||
link_.join_new();
|
||||
}
|
||||
|
||||
template <typename U> void copy(linked_ptr<U> const* ptr) {
|
||||
value_ = ptr->get();
|
||||
if (value_)
|
||||
link_.join(&ptr->link_);
|
||||
else
|
||||
link_.join_new();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T> inline
|
||||
bool operator==(T* ptr, const linked_ptr<T>& x) {
|
||||
return ptr == x.get();
|
||||
}
|
||||
|
||||
template<typename T> inline
|
||||
bool operator!=(T* ptr, const linked_ptr<T>& x) {
|
||||
return ptr != x.get();
|
||||
}
|
||||
|
||||
// A function to convert T* into linked_ptr<T>
|
||||
// Doing e.g. make_linked_ptr(new FooBarBaz<type>(arg)) is a shorter notation
|
||||
// for linked_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg))
|
||||
template <typename T>
|
||||
linked_ptr<T> make_linked_ptr(T* ptr) {
|
||||
return linked_ptr<T>(ptr);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,301 +1,301 @@
|
||||
$$ -*- mode: c++; -*-
|
||||
$var n = 50 $$ Maximum length of Values arguments we want to support.
|
||||
$var maxtuple = 10 $$ Maximum number of Combine arguments we want to support.
|
||||
// Copyright 2008 Google Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: vladl@google.com (Vlad Losev)
|
||||
|
||||
// Type and function utilities for implementing parameterized tests.
|
||||
// This file is generated by a SCRIPT. DO NOT EDIT BY HAND!
|
||||
//
|
||||
// Currently Google Test supports at most $n arguments in Values,
|
||||
// and at most $maxtuple arguments in Combine. Please contact
|
||||
// googletestframework@googlegroups.com if you need more.
|
||||
// Please note that the number of arguments to Combine is limited
|
||||
// by the maximum arity of the implementation of tuple which is
|
||||
// currently set at $maxtuple.
|
||||
|
||||
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
|
||||
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
|
||||
|
||||
// scripts/fuse_gtest.py depends on gtest's own header being #included
|
||||
// *unconditionally*. Therefore these #includes cannot be moved
|
||||
// inside #if GTEST_HAS_PARAM_TEST.
|
||||
#include "gtest/internal/gtest-param-util.h"
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
|
||||
#if GTEST_HAS_PARAM_TEST
|
||||
|
||||
namespace testing {
|
||||
|
||||
// Forward declarations of ValuesIn(), which is implemented in
|
||||
// include/gtest/gtest-param-test.h.
|
||||
template <typename ForwardIterator>
|
||||
internal::ParamGenerator<
|
||||
typename ::testing::internal::IteratorTraits<ForwardIterator>::value_type>
|
||||
ValuesIn(ForwardIterator begin, ForwardIterator end);
|
||||
|
||||
template <typename T, size_t N>
|
||||
internal::ParamGenerator<T> ValuesIn(const T (&array)[N]);
|
||||
|
||||
template <class Container>
|
||||
internal::ParamGenerator<typename Container::value_type> ValuesIn(
|
||||
const Container& container);
|
||||
|
||||
namespace internal {
|
||||
|
||||
// Used in the Values() function to provide polymorphic capabilities.
|
||||
template <typename T1>
|
||||
class ValueArray1 {
|
||||
public:
|
||||
explicit ValueArray1(T1 v1) : v1_(v1) {}
|
||||
|
||||
template <typename T>
|
||||
operator ParamGenerator<T>() const { return ValuesIn(&v1_, &v1_ + 1); }
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray1& other);
|
||||
|
||||
const T1 v1_;
|
||||
};
|
||||
|
||||
$range i 2..n
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
|
||||
template <$for j, [[typename T$j]]>
|
||||
class ValueArray$i {
|
||||
public:
|
||||
ValueArray$i($for j, [[T$j v$j]]) : $for j, [[v$(j)_(v$j)]] {}
|
||||
|
||||
template <typename T>
|
||||
operator ParamGenerator<T>() const {
|
||||
const T array[] = {$for j, [[static_cast<T>(v$(j)_)]]};
|
||||
return ValuesIn(array);
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray$i& other);
|
||||
|
||||
$for j [[
|
||||
|
||||
const T$j v$(j)_;
|
||||
]]
|
||||
|
||||
};
|
||||
|
||||
]]
|
||||
|
||||
# if GTEST_HAS_COMBINE
|
||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||
//
|
||||
// Generates values from the Cartesian product of values produced
|
||||
// by the argument generators.
|
||||
//
|
||||
$range i 2..maxtuple
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
$range k 2..i
|
||||
|
||||
template <$for j, [[typename T$j]]>
|
||||
class CartesianProductGenerator$i
|
||||
: public ParamGeneratorInterface< ::testing::tuple<$for j, [[T$j]]> > {
|
||||
public:
|
||||
typedef ::testing::tuple<$for j, [[T$j]]> ParamType;
|
||||
|
||||
CartesianProductGenerator$i($for j, [[const ParamGenerator<T$j>& g$j]])
|
||||
: $for j, [[g$(j)_(g$j)]] {}
|
||||
virtual ~CartesianProductGenerator$i() {}
|
||||
|
||||
virtual ParamIteratorInterface<ParamType>* Begin() const {
|
||||
return new Iterator(this, $for j, [[g$(j)_, g$(j)_.begin()]]);
|
||||
}
|
||||
virtual ParamIteratorInterface<ParamType>* End() const {
|
||||
return new Iterator(this, $for j, [[g$(j)_, g$(j)_.end()]]);
|
||||
}
|
||||
|
||||
private:
|
||||
class Iterator : public ParamIteratorInterface<ParamType> {
|
||||
public:
|
||||
Iterator(const ParamGeneratorInterface<ParamType>* base, $for j, [[
|
||||
|
||||
const ParamGenerator<T$j>& g$j,
|
||||
const typename ParamGenerator<T$j>::iterator& current$(j)]])
|
||||
: base_(base),
|
||||
$for j, [[
|
||||
|
||||
begin$(j)_(g$j.begin()), end$(j)_(g$j.end()), current$(j)_(current$j)
|
||||
]] {
|
||||
ComputeCurrentValue();
|
||||
}
|
||||
virtual ~Iterator() {}
|
||||
|
||||
virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
|
||||
return base_;
|
||||
}
|
||||
// Advance should not be called on beyond-of-range iterators
|
||||
// so no component iterators must be beyond end of range, either.
|
||||
virtual void Advance() {
|
||||
assert(!AtEnd());
|
||||
++current$(i)_;
|
||||
|
||||
$for k [[
|
||||
if (current$(i+2-k)_ == end$(i+2-k)_) {
|
||||
current$(i+2-k)_ = begin$(i+2-k)_;
|
||||
++current$(i+2-k-1)_;
|
||||
}
|
||||
|
||||
]]
|
||||
ComputeCurrentValue();
|
||||
}
|
||||
virtual ParamIteratorInterface<ParamType>* Clone() const {
|
||||
return new Iterator(*this);
|
||||
}
|
||||
virtual const ParamType* Current() const { return ¤t_value_; }
|
||||
virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
|
||||
// Having the same base generator guarantees that the other
|
||||
// iterator is of the same type and we can downcast.
|
||||
GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
|
||||
<< "The program attempted to compare iterators "
|
||||
<< "from different generators." << std::endl;
|
||||
const Iterator* typed_other =
|
||||
CheckedDowncastToActualType<const Iterator>(&other);
|
||||
// We must report iterators equal if they both point beyond their
|
||||
// respective ranges. That can happen in a variety of fashions,
|
||||
// so we have to consult AtEnd().
|
||||
return (AtEnd() && typed_other->AtEnd()) ||
|
||||
($for j && [[
|
||||
|
||||
current$(j)_ == typed_other->current$(j)_
|
||||
]]);
|
||||
}
|
||||
|
||||
private:
|
||||
Iterator(const Iterator& other)
|
||||
: base_(other.base_), $for j, [[
|
||||
|
||||
begin$(j)_(other.begin$(j)_),
|
||||
end$(j)_(other.end$(j)_),
|
||||
current$(j)_(other.current$(j)_)
|
||||
]] {
|
||||
ComputeCurrentValue();
|
||||
}
|
||||
|
||||
void ComputeCurrentValue() {
|
||||
if (!AtEnd())
|
||||
current_value_ = ParamType($for j, [[*current$(j)_]]);
|
||||
}
|
||||
bool AtEnd() const {
|
||||
// We must report iterator past the end of the range when either of the
|
||||
// component iterators has reached the end of its range.
|
||||
return
|
||||
$for j || [[
|
||||
|
||||
current$(j)_ == end$(j)_
|
||||
]];
|
||||
}
|
||||
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const Iterator& other);
|
||||
|
||||
const ParamGeneratorInterface<ParamType>* const base_;
|
||||
// begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
|
||||
// current[i]_ is the actual traversing iterator.
|
||||
$for j [[
|
||||
|
||||
const typename ParamGenerator<T$j>::iterator begin$(j)_;
|
||||
const typename ParamGenerator<T$j>::iterator end$(j)_;
|
||||
typename ParamGenerator<T$j>::iterator current$(j)_;
|
||||
]]
|
||||
|
||||
ParamType current_value_;
|
||||
}; // class CartesianProductGenerator$i::Iterator
|
||||
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const CartesianProductGenerator$i& other);
|
||||
|
||||
|
||||
$for j [[
|
||||
const ParamGenerator<T$j> g$(j)_;
|
||||
|
||||
]]
|
||||
}; // class CartesianProductGenerator$i
|
||||
|
||||
|
||||
]]
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||
//
|
||||
// Helper classes providing Combine() with polymorphic features. They allow
|
||||
// casting CartesianProductGeneratorN<T> to ParamGenerator<U> if T is
|
||||
// convertible to U.
|
||||
//
|
||||
$range i 2..maxtuple
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
|
||||
template <$for j, [[class Generator$j]]>
|
||||
class CartesianProductHolder$i {
|
||||
public:
|
||||
CartesianProductHolder$i($for j, [[const Generator$j& g$j]])
|
||||
: $for j, [[g$(j)_(g$j)]] {}
|
||||
template <$for j, [[typename T$j]]>
|
||||
operator ParamGenerator< ::testing::tuple<$for j, [[T$j]]> >() const {
|
||||
return ParamGenerator< ::testing::tuple<$for j, [[T$j]]> >(
|
||||
new CartesianProductGenerator$i<$for j, [[T$j]]>(
|
||||
$for j,[[
|
||||
|
||||
static_cast<ParamGenerator<T$j> >(g$(j)_)
|
||||
]]));
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const CartesianProductHolder$i& other);
|
||||
|
||||
|
||||
$for j [[
|
||||
const Generator$j g$(j)_;
|
||||
|
||||
]]
|
||||
}; // class CartesianProductHolder$i
|
||||
|
||||
]]
|
||||
|
||||
# endif // GTEST_HAS_COMBINE
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
|
||||
#endif // GTEST_HAS_PARAM_TEST
|
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
|
||||
$$ -*- mode: c++; -*-
|
||||
$var n = 50 $$ Maximum length of Values arguments we want to support.
|
||||
$var maxtuple = 10 $$ Maximum number of Combine arguments we want to support.
|
||||
// Copyright 2008 Google Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: vladl@google.com (Vlad Losev)
|
||||
|
||||
// Type and function utilities for implementing parameterized tests.
|
||||
// This file is generated by a SCRIPT. DO NOT EDIT BY HAND!
|
||||
//
|
||||
// Currently Google Test supports at most $n arguments in Values,
|
||||
// and at most $maxtuple arguments in Combine. Please contact
|
||||
// googletestframework@googlegroups.com if you need more.
|
||||
// Please note that the number of arguments to Combine is limited
|
||||
// by the maximum arity of the implementation of tr1::tuple which is
|
||||
// currently set at $maxtuple.
|
||||
|
||||
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
|
||||
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
|
||||
|
||||
// scripts/fuse_gtest.py depends on gtest's own header being #included
|
||||
// *unconditionally*. Therefore these #includes cannot be moved
|
||||
// inside #if GTEST_HAS_PARAM_TEST.
|
||||
#include "gtest/internal/gtest-param-util.h"
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
|
||||
#if GTEST_HAS_PARAM_TEST
|
||||
|
||||
namespace testing {
|
||||
|
||||
// Forward declarations of ValuesIn(), which is implemented in
|
||||
// include/gtest/gtest-param-test.h.
|
||||
template <typename ForwardIterator>
|
||||
internal::ParamGenerator<
|
||||
typename ::testing::internal::IteratorTraits<ForwardIterator>::value_type>
|
||||
ValuesIn(ForwardIterator begin, ForwardIterator end);
|
||||
|
||||
template <typename T, size_t N>
|
||||
internal::ParamGenerator<T> ValuesIn(const T (&array)[N]);
|
||||
|
||||
template <class Container>
|
||||
internal::ParamGenerator<typename Container::value_type> ValuesIn(
|
||||
const Container& container);
|
||||
|
||||
namespace internal {
|
||||
|
||||
// Used in the Values() function to provide polymorphic capabilities.
|
||||
template <typename T1>
|
||||
class ValueArray1 {
|
||||
public:
|
||||
explicit ValueArray1(T1 v1) : v1_(v1) {}
|
||||
|
||||
template <typename T>
|
||||
operator ParamGenerator<T>() const { return ValuesIn(&v1_, &v1_ + 1); }
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray1& other);
|
||||
|
||||
const T1 v1_;
|
||||
};
|
||||
|
||||
$range i 2..n
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
|
||||
template <$for j, [[typename T$j]]>
|
||||
class ValueArray$i {
|
||||
public:
|
||||
ValueArray$i($for j, [[T$j v$j]]) : $for j, [[v$(j)_(v$j)]] {}
|
||||
|
||||
template <typename T>
|
||||
operator ParamGenerator<T>() const {
|
||||
const T array[] = {$for j, [[static_cast<T>(v$(j)_)]]};
|
||||
return ValuesIn(array);
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray$i& other);
|
||||
|
||||
$for j [[
|
||||
|
||||
const T$j v$(j)_;
|
||||
]]
|
||||
|
||||
};
|
||||
|
||||
]]
|
||||
|
||||
# if GTEST_HAS_COMBINE
|
||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||
//
|
||||
// Generates values from the Cartesian product of values produced
|
||||
// by the argument generators.
|
||||
//
|
||||
$range i 2..maxtuple
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
$range k 2..i
|
||||
|
||||
template <$for j, [[typename T$j]]>
|
||||
class CartesianProductGenerator$i
|
||||
: public ParamGeneratorInterface< ::std::tr1::tuple<$for j, [[T$j]]> > {
|
||||
public:
|
||||
typedef ::std::tr1::tuple<$for j, [[T$j]]> ParamType;
|
||||
|
||||
CartesianProductGenerator$i($for j, [[const ParamGenerator<T$j>& g$j]])
|
||||
: $for j, [[g$(j)_(g$j)]] {}
|
||||
virtual ~CartesianProductGenerator$i() {}
|
||||
|
||||
virtual ParamIteratorInterface<ParamType>* Begin() const {
|
||||
return new Iterator(this, $for j, [[g$(j)_, g$(j)_.begin()]]);
|
||||
}
|
||||
virtual ParamIteratorInterface<ParamType>* End() const {
|
||||
return new Iterator(this, $for j, [[g$(j)_, g$(j)_.end()]]);
|
||||
}
|
||||
|
||||
private:
|
||||
class Iterator : public ParamIteratorInterface<ParamType> {
|
||||
public:
|
||||
Iterator(const ParamGeneratorInterface<ParamType>* base, $for j, [[
|
||||
|
||||
const ParamGenerator<T$j>& g$j,
|
||||
const typename ParamGenerator<T$j>::iterator& current$(j)]])
|
||||
: base_(base),
|
||||
$for j, [[
|
||||
|
||||
begin$(j)_(g$j.begin()), end$(j)_(g$j.end()), current$(j)_(current$j)
|
||||
]] {
|
||||
ComputeCurrentValue();
|
||||
}
|
||||
virtual ~Iterator() {}
|
||||
|
||||
virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
|
||||
return base_;
|
||||
}
|
||||
// Advance should not be called on beyond-of-range iterators
|
||||
// so no component iterators must be beyond end of range, either.
|
||||
virtual void Advance() {
|
||||
assert(!AtEnd());
|
||||
++current$(i)_;
|
||||
|
||||
$for k [[
|
||||
if (current$(i+2-k)_ == end$(i+2-k)_) {
|
||||
current$(i+2-k)_ = begin$(i+2-k)_;
|
||||
++current$(i+2-k-1)_;
|
||||
}
|
||||
|
||||
]]
|
||||
ComputeCurrentValue();
|
||||
}
|
||||
virtual ParamIteratorInterface<ParamType>* Clone() const {
|
||||
return new Iterator(*this);
|
||||
}
|
||||
virtual const ParamType* Current() const { return ¤t_value_; }
|
||||
virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
|
||||
// Having the same base generator guarantees that the other
|
||||
// iterator is of the same type and we can downcast.
|
||||
GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
|
||||
<< "The program attempted to compare iterators "
|
||||
<< "from different generators." << std::endl;
|
||||
const Iterator* typed_other =
|
||||
CheckedDowncastToActualType<const Iterator>(&other);
|
||||
// We must report iterators equal if they both point beyond their
|
||||
// respective ranges. That can happen in a variety of fashions,
|
||||
// so we have to consult AtEnd().
|
||||
return (AtEnd() && typed_other->AtEnd()) ||
|
||||
($for j && [[
|
||||
|
||||
current$(j)_ == typed_other->current$(j)_
|
||||
]]);
|
||||
}
|
||||
|
||||
private:
|
||||
Iterator(const Iterator& other)
|
||||
: base_(other.base_), $for j, [[
|
||||
|
||||
begin$(j)_(other.begin$(j)_),
|
||||
end$(j)_(other.end$(j)_),
|
||||
current$(j)_(other.current$(j)_)
|
||||
]] {
|
||||
ComputeCurrentValue();
|
||||
}
|
||||
|
||||
void ComputeCurrentValue() {
|
||||
if (!AtEnd())
|
||||
current_value_ = ParamType($for j, [[*current$(j)_]]);
|
||||
}
|
||||
bool AtEnd() const {
|
||||
// We must report iterator past the end of the range when either of the
|
||||
// component iterators has reached the end of its range.
|
||||
return
|
||||
$for j || [[
|
||||
|
||||
current$(j)_ == end$(j)_
|
||||
]];
|
||||
}
|
||||
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const Iterator& other);
|
||||
|
||||
const ParamGeneratorInterface<ParamType>* const base_;
|
||||
// begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
|
||||
// current[i]_ is the actual traversing iterator.
|
||||
$for j [[
|
||||
|
||||
const typename ParamGenerator<T$j>::iterator begin$(j)_;
|
||||
const typename ParamGenerator<T$j>::iterator end$(j)_;
|
||||
typename ParamGenerator<T$j>::iterator current$(j)_;
|
||||
]]
|
||||
|
||||
ParamType current_value_;
|
||||
}; // class CartesianProductGenerator$i::Iterator
|
||||
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const CartesianProductGenerator$i& other);
|
||||
|
||||
|
||||
$for j [[
|
||||
const ParamGenerator<T$j> g$(j)_;
|
||||
|
||||
]]
|
||||
}; // class CartesianProductGenerator$i
|
||||
|
||||
|
||||
]]
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||
//
|
||||
// Helper classes providing Combine() with polymorphic features. They allow
|
||||
// casting CartesianProductGeneratorN<T> to ParamGenerator<U> if T is
|
||||
// convertible to U.
|
||||
//
|
||||
$range i 2..maxtuple
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
|
||||
template <$for j, [[class Generator$j]]>
|
||||
class CartesianProductHolder$i {
|
||||
public:
|
||||
CartesianProductHolder$i($for j, [[const Generator$j& g$j]])
|
||||
: $for j, [[g$(j)_(g$j)]] {}
|
||||
template <$for j, [[typename T$j]]>
|
||||
operator ParamGenerator< ::std::tr1::tuple<$for j, [[T$j]]> >() const {
|
||||
return ParamGenerator< ::std::tr1::tuple<$for j, [[T$j]]> >(
|
||||
new CartesianProductGenerator$i<$for j, [[T$j]]>(
|
||||
$for j,[[
|
||||
|
||||
static_cast<ParamGenerator<T$j> >(g$(j)_)
|
||||
]]));
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const CartesianProductHolder$i& other);
|
||||
|
||||
|
||||
$for j [[
|
||||
const Generator$j g$(j)_;
|
||||
|
||||
]]
|
||||
}; // class CartesianProductHolder$i
|
||||
|
||||
]]
|
||||
|
||||
# endif // GTEST_HAS_COMBINE
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
|
||||
#endif // GTEST_HAS_PARAM_TEST
|
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,167 +1,167 @@
|
||||
// Copyright 2005, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee)
|
||||
//
|
||||
// The Google C++ Testing Framework (Google Test)
|
||||
//
|
||||
// This header file declares the String class and functions used internally by
|
||||
// Google Test. They are subject to change without notice. They should not used
|
||||
// by code external to Google Test.
|
||||
//
|
||||
// This header file is #included by <gtest/internal/gtest-internal.h>.
|
||||
// It should not be #included by other files.
|
||||
|
||||
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
|
||||
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
// string.h is not guaranteed to provide strcpy on C++ Builder.
|
||||
# include <mem.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// String - an abstract class holding static string utilities.
|
||||
class GTEST_API_ String {
|
||||
public:
|
||||
// Static utility methods
|
||||
|
||||
// Clones a 0-terminated C string, allocating memory using new. The
|
||||
// caller is responsible for deleting the return value using
|
||||
// delete[]. Returns the cloned string, or NULL if the input is
|
||||
// NULL.
|
||||
//
|
||||
// This is different from strdup() in string.h, which allocates
|
||||
// memory using malloc().
|
||||
static const char* CloneCString(const char* c_str);
|
||||
|
||||
#if GTEST_OS_WINDOWS_MOBILE
|
||||
// Windows CE does not have the 'ANSI' versions of Win32 APIs. To be
|
||||
// able to pass strings to Win32 APIs on CE we need to convert them
|
||||
// to 'Unicode', UTF-16.
|
||||
|
||||
// Creates a UTF-16 wide string from the given ANSI string, allocating
|
||||
// memory using new. The caller is responsible for deleting the return
|
||||
// value using delete[]. Returns the wide string, or NULL if the
|
||||
// input is NULL.
|
||||
//
|
||||
// The wide string is created using the ANSI codepage (CP_ACP) to
|
||||
// match the behaviour of the ANSI versions of Win32 calls and the
|
||||
// C runtime.
|
||||
static LPCWSTR AnsiToUtf16(const char* c_str);
|
||||
|
||||
// Creates an ANSI string from the given wide string, allocating
|
||||
// memory using new. The caller is responsible for deleting the return
|
||||
// value using delete[]. Returns the ANSI string, or NULL if the
|
||||
// input is NULL.
|
||||
//
|
||||
// The returned string is created using the ANSI codepage (CP_ACP) to
|
||||
// match the behaviour of the ANSI versions of Win32 calls and the
|
||||
// C runtime.
|
||||
static const char* Utf16ToAnsi(LPCWSTR utf16_str);
|
||||
#endif
|
||||
|
||||
// Compares two C strings. Returns true iff they have the same content.
|
||||
//
|
||||
// Unlike strcmp(), this function can handle NULL argument(s). A
|
||||
// NULL C string is considered different to any non-NULL C string,
|
||||
// including the empty string.
|
||||
static bool CStringEquals(const char* lhs, const char* rhs);
|
||||
|
||||
// Converts a wide C string to a String using the UTF-8 encoding.
|
||||
// NULL will be converted to "(null)". If an error occurred during
|
||||
// the conversion, "(failed to convert from wide string)" is
|
||||
// returned.
|
||||
static std::string ShowWideCString(const wchar_t* wide_c_str);
|
||||
|
||||
// Compares two wide C strings. Returns true iff they have the same
|
||||
// content.
|
||||
//
|
||||
// Unlike wcscmp(), this function can handle NULL argument(s). A
|
||||
// NULL C string is considered different to any non-NULL C string,
|
||||
// including the empty string.
|
||||
static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs);
|
||||
|
||||
// Compares two C strings, ignoring case. Returns true iff they
|
||||
// have the same content.
|
||||
//
|
||||
// Unlike strcasecmp(), this function can handle NULL argument(s).
|
||||
// A NULL C string is considered different to any non-NULL C string,
|
||||
// including the empty string.
|
||||
static bool CaseInsensitiveCStringEquals(const char* lhs,
|
||||
const char* rhs);
|
||||
|
||||
// Compares two wide C strings, ignoring case. Returns true iff they
|
||||
// have the same content.
|
||||
//
|
||||
// Unlike wcscasecmp(), this function can handle NULL argument(s).
|
||||
// A NULL C string is considered different to any non-NULL wide C string,
|
||||
// including the empty string.
|
||||
// NB: The implementations on different platforms slightly differ.
|
||||
// On windows, this method uses _wcsicmp which compares according to LC_CTYPE
|
||||
// environment variable. On GNU platform this method uses wcscasecmp
|
||||
// which compares according to LC_CTYPE category of the current locale.
|
||||
// On MacOS X, it uses towlower, which also uses LC_CTYPE category of the
|
||||
// current locale.
|
||||
static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs,
|
||||
const wchar_t* rhs);
|
||||
|
||||
// Returns true iff the given string ends with the given suffix, ignoring
|
||||
// case. Any string is considered to end with an empty suffix.
|
||||
static bool EndsWithCaseInsensitive(
|
||||
const std::string& str, const std::string& suffix);
|
||||
|
||||
// Formats an int value as "%02d".
|
||||
static std::string FormatIntWidth2(int value); // "%02d" for width == 2
|
||||
|
||||
// Formats an int value as "%X".
|
||||
static std::string FormatHexInt(int value);
|
||||
|
||||
// Formats a byte as "%02X".
|
||||
static std::string FormatByte(unsigned char value);
|
||||
|
||||
private:
|
||||
String(); // Not meant to be instantiated.
|
||||
}; // class String
|
||||
|
||||
// Gets the content of the stringstream's buffer as an std::string. Each '\0'
|
||||
// character in the buffer is replaced with "\\0".
|
||||
GTEST_API_ std::string StringStreamToString(::std::stringstream* stream);
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
|
||||
// Copyright 2005, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee)
|
||||
//
|
||||
// The Google C++ Testing Framework (Google Test)
|
||||
//
|
||||
// This header file declares the String class and functions used internally by
|
||||
// Google Test. They are subject to change without notice. They should not used
|
||||
// by code external to Google Test.
|
||||
//
|
||||
// This header file is #included by <gtest/internal/gtest-internal.h>.
|
||||
// It should not be #included by other files.
|
||||
|
||||
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
|
||||
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
// string.h is not guaranteed to provide strcpy on C++ Builder.
|
||||
# include <mem.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// String - an abstract class holding static string utilities.
|
||||
class GTEST_API_ String {
|
||||
public:
|
||||
// Static utility methods
|
||||
|
||||
// Clones a 0-terminated C string, allocating memory using new. The
|
||||
// caller is responsible for deleting the return value using
|
||||
// delete[]. Returns the cloned string, or NULL if the input is
|
||||
// NULL.
|
||||
//
|
||||
// This is different from strdup() in string.h, which allocates
|
||||
// memory using malloc().
|
||||
static const char* CloneCString(const char* c_str);
|
||||
|
||||
#if GTEST_OS_WINDOWS_MOBILE
|
||||
// Windows CE does not have the 'ANSI' versions of Win32 APIs. To be
|
||||
// able to pass strings to Win32 APIs on CE we need to convert them
|
||||
// to 'Unicode', UTF-16.
|
||||
|
||||
// Creates a UTF-16 wide string from the given ANSI string, allocating
|
||||
// memory using new. The caller is responsible for deleting the return
|
||||
// value using delete[]. Returns the wide string, or NULL if the
|
||||
// input is NULL.
|
||||
//
|
||||
// The wide string is created using the ANSI codepage (CP_ACP) to
|
||||
// match the behaviour of the ANSI versions of Win32 calls and the
|
||||
// C runtime.
|
||||
static LPCWSTR AnsiToUtf16(const char* c_str);
|
||||
|
||||
// Creates an ANSI string from the given wide string, allocating
|
||||
// memory using new. The caller is responsible for deleting the return
|
||||
// value using delete[]. Returns the ANSI string, or NULL if the
|
||||
// input is NULL.
|
||||
//
|
||||
// The returned string is created using the ANSI codepage (CP_ACP) to
|
||||
// match the behaviour of the ANSI versions of Win32 calls and the
|
||||
// C runtime.
|
||||
static const char* Utf16ToAnsi(LPCWSTR utf16_str);
|
||||
#endif
|
||||
|
||||
// Compares two C strings. Returns true iff they have the same content.
|
||||
//
|
||||
// Unlike strcmp(), this function can handle NULL argument(s). A
|
||||
// NULL C string is considered different to any non-NULL C string,
|
||||
// including the empty string.
|
||||
static bool CStringEquals(const char* lhs, const char* rhs);
|
||||
|
||||
// Converts a wide C string to a String using the UTF-8 encoding.
|
||||
// NULL will be converted to "(null)". If an error occurred during
|
||||
// the conversion, "(failed to convert from wide string)" is
|
||||
// returned.
|
||||
static std::string ShowWideCString(const wchar_t* wide_c_str);
|
||||
|
||||
// Compares two wide C strings. Returns true iff they have the same
|
||||
// content.
|
||||
//
|
||||
// Unlike wcscmp(), this function can handle NULL argument(s). A
|
||||
// NULL C string is considered different to any non-NULL C string,
|
||||
// including the empty string.
|
||||
static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs);
|
||||
|
||||
// Compares two C strings, ignoring case. Returns true iff they
|
||||
// have the same content.
|
||||
//
|
||||
// Unlike strcasecmp(), this function can handle NULL argument(s).
|
||||
// A NULL C string is considered different to any non-NULL C string,
|
||||
// including the empty string.
|
||||
static bool CaseInsensitiveCStringEquals(const char* lhs,
|
||||
const char* rhs);
|
||||
|
||||
// Compares two wide C strings, ignoring case. Returns true iff they
|
||||
// have the same content.
|
||||
//
|
||||
// Unlike wcscasecmp(), this function can handle NULL argument(s).
|
||||
// A NULL C string is considered different to any non-NULL wide C string,
|
||||
// including the empty string.
|
||||
// NB: The implementations on different platforms slightly differ.
|
||||
// On windows, this method uses _wcsicmp which compares according to LC_CTYPE
|
||||
// environment variable. On GNU platform this method uses wcscasecmp
|
||||
// which compares according to LC_CTYPE category of the current locale.
|
||||
// On MacOS X, it uses towlower, which also uses LC_CTYPE category of the
|
||||
// current locale.
|
||||
static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs,
|
||||
const wchar_t* rhs);
|
||||
|
||||
// Returns true iff the given string ends with the given suffix, ignoring
|
||||
// case. Any string is considered to end with an empty suffix.
|
||||
static bool EndsWithCaseInsensitive(
|
||||
const std::string& str, const std::string& suffix);
|
||||
|
||||
// Formats an int value as "%02d".
|
||||
static std::string FormatIntWidth2(int value); // "%02d" for width == 2
|
||||
|
||||
// Formats an int value as "%X".
|
||||
static std::string FormatHexInt(int value);
|
||||
|
||||
// Formats a byte as "%02X".
|
||||
static std::string FormatByte(unsigned char value);
|
||||
|
||||
private:
|
||||
String(); // Not meant to be instantiated.
|
||||
}; // class String
|
||||
|
||||
// Gets the content of the stringstream's buffer as an std::string. Each '\0'
|
||||
// character in the buffer is replaced with "\\0".
|
||||
GTEST_API_ std::string StringStreamToString(::std::stringstream* stream);
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,347 +1,339 @@
|
||||
$$ -*- mode: c++; -*-
|
||||
$var n = 10 $$ Maximum number of tuple fields we want to support.
|
||||
$$ This meta comment fixes auto-indentation in Emacs. }}
|
||||
// Copyright 2009 Google Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Implements a subset of TR1 tuple needed by Google Test and Google Mock.
|
||||
|
||||
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
|
||||
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
|
||||
|
||||
#include <utility> // For ::std::pair.
|
||||
|
||||
// The compiler used in Symbian has a bug that prevents us from declaring the
|
||||
// tuple template as a friend (it complains that tuple is redefined). This
|
||||
// hack bypasses the bug by declaring the members that should otherwise be
|
||||
// private as public.
|
||||
// Sun Studio versions < 12 also have the above bug.
|
||||
#if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590)
|
||||
# define GTEST_DECLARE_TUPLE_AS_FRIEND_ public:
|
||||
#else
|
||||
# define GTEST_DECLARE_TUPLE_AS_FRIEND_ \
|
||||
template <GTEST_$(n)_TYPENAMES_(U)> friend class tuple; \
|
||||
private:
|
||||
#endif
|
||||
|
||||
// Visual Studio 2010, 2012, and 2013 define symbols in std::tr1 that conflict
|
||||
// with our own definitions. Therefore using our own tuple does not work on
|
||||
// those compilers.
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1600 /* 1600 is Visual Studio 2010 */
|
||||
# error "gtest's tuple doesn't compile on Visual Studio 2010 or later. \
|
||||
GTEST_USE_OWN_TR1_TUPLE must be set to 0 on those compilers."
|
||||
#endif
|
||||
|
||||
|
||||
$range i 0..n-1
|
||||
$range j 0..n
|
||||
$range k 1..n
|
||||
// GTEST_n_TUPLE_(T) is the type of an n-tuple.
|
||||
#define GTEST_0_TUPLE_(T) tuple<>
|
||||
|
||||
$for k [[
|
||||
$range m 0..k-1
|
||||
$range m2 k..n-1
|
||||
#define GTEST_$(k)_TUPLE_(T) tuple<$for m, [[T##$m]]$for m2 [[, void]]>
|
||||
|
||||
]]
|
||||
|
||||
// GTEST_n_TYPENAMES_(T) declares a list of n typenames.
|
||||
|
||||
$for j [[
|
||||
$range m 0..j-1
|
||||
#define GTEST_$(j)_TYPENAMES_(T) $for m, [[typename T##$m]]
|
||||
|
||||
|
||||
]]
|
||||
|
||||
// In theory, defining stuff in the ::std namespace is undefined
|
||||
// behavior. We can do this as we are playing the role of a standard
|
||||
// library vendor.
|
||||
namespace std {
|
||||
namespace tr1 {
|
||||
|
||||
template <$for i, [[typename T$i = void]]>
|
||||
class tuple;
|
||||
|
||||
// Anything in namespace gtest_internal is Google Test's INTERNAL
|
||||
// IMPLEMENTATION DETAIL and MUST NOT BE USED DIRECTLY in user code.
|
||||
namespace gtest_internal {
|
||||
|
||||
// ByRef<T>::type is T if T is a reference; otherwise it's const T&.
|
||||
template <typename T>
|
||||
struct ByRef { typedef const T& type; }; // NOLINT
|
||||
template <typename T>
|
||||
struct ByRef<T&> { typedef T& type; }; // NOLINT
|
||||
|
||||
// A handy wrapper for ByRef.
|
||||
#define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef<T>::type
|
||||
|
||||
// AddRef<T>::type is T if T is a reference; otherwise it's T&. This
|
||||
// is the same as tr1::add_reference<T>::type.
|
||||
template <typename T>
|
||||
struct AddRef { typedef T& type; }; // NOLINT
|
||||
template <typename T>
|
||||
struct AddRef<T&> { typedef T& type; }; // NOLINT
|
||||
|
||||
// A handy wrapper for AddRef.
|
||||
#define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef<T>::type
|
||||
|
||||
// A helper for implementing get<k>().
|
||||
template <int k> class Get;
|
||||
|
||||
// A helper for implementing tuple_element<k, T>. kIndexValid is true
|
||||
// iff k < the number of fields in tuple type T.
|
||||
template <bool kIndexValid, int kIndex, class Tuple>
|
||||
struct TupleElement;
|
||||
|
||||
|
||||
$for i [[
|
||||
template <GTEST_$(n)_TYPENAMES_(T)>
|
||||
struct TupleElement<true, $i, GTEST_$(n)_TUPLE_(T) > {
|
||||
typedef T$i type;
|
||||
};
|
||||
|
||||
|
||||
]]
|
||||
} // namespace gtest_internal
|
||||
|
||||
template <>
|
||||
class tuple<> {
|
||||
public:
|
||||
tuple() {}
|
||||
tuple(const tuple& /* t */) {}
|
||||
tuple& operator=(const tuple& /* t */) { return *this; }
|
||||
};
|
||||
|
||||
|
||||
$for k [[
|
||||
$range m 0..k-1
|
||||
template <GTEST_$(k)_TYPENAMES_(T)>
|
||||
class $if k < n [[GTEST_$(k)_TUPLE_(T)]] $else [[tuple]] {
|
||||
public:
|
||||
template <int k> friend class gtest_internal::Get;
|
||||
|
||||
tuple() : $for m, [[f$(m)_()]] {}
|
||||
|
||||
explicit tuple($for m, [[GTEST_BY_REF_(T$m) f$m]]) : [[]]
|
||||
$for m, [[f$(m)_(f$m)]] {}
|
||||
|
||||
tuple(const tuple& t) : $for m, [[f$(m)_(t.f$(m)_)]] {}
|
||||
|
||||
template <GTEST_$(k)_TYPENAMES_(U)>
|
||||
tuple(const GTEST_$(k)_TUPLE_(U)& t) : $for m, [[f$(m)_(t.f$(m)_)]] {}
|
||||
|
||||
$if k == 2 [[
|
||||
template <typename U0, typename U1>
|
||||
tuple(const ::std::pair<U0, U1>& p) : f0_(p.first), f1_(p.second) {}
|
||||
|
||||
]]
|
||||
|
||||
tuple& operator=(const tuple& t) { return CopyFrom(t); }
|
||||
|
||||
template <GTEST_$(k)_TYPENAMES_(U)>
|
||||
tuple& operator=(const GTEST_$(k)_TUPLE_(U)& t) {
|
||||
return CopyFrom(t);
|
||||
}
|
||||
|
||||
$if k == 2 [[
|
||||
template <typename U0, typename U1>
|
||||
tuple& operator=(const ::std::pair<U0, U1>& p) {
|
||||
f0_ = p.first;
|
||||
f1_ = p.second;
|
||||
return *this;
|
||||
}
|
||||
|
||||
]]
|
||||
|
||||
GTEST_DECLARE_TUPLE_AS_FRIEND_
|
||||
|
||||
template <GTEST_$(k)_TYPENAMES_(U)>
|
||||
tuple& CopyFrom(const GTEST_$(k)_TUPLE_(U)& t) {
|
||||
|
||||
$for m [[
|
||||
f$(m)_ = t.f$(m)_;
|
||||
|
||||
]]
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
$for m [[
|
||||
T$m f$(m)_;
|
||||
|
||||
]]
|
||||
};
|
||||
|
||||
|
||||
]]
|
||||
// 6.1.3.2 Tuple creation functions.
|
||||
|
||||
// Known limitations: we don't support passing an
|
||||
// std::tr1::reference_wrapper<T> to make_tuple(). And we don't
|
||||
// implement tie().
|
||||
|
||||
inline tuple<> make_tuple() { return tuple<>(); }
|
||||
|
||||
$for k [[
|
||||
$range m 0..k-1
|
||||
|
||||
template <GTEST_$(k)_TYPENAMES_(T)>
|
||||
inline GTEST_$(k)_TUPLE_(T) make_tuple($for m, [[const T$m& f$m]]) {
|
||||
return GTEST_$(k)_TUPLE_(T)($for m, [[f$m]]);
|
||||
}
|
||||
|
||||
]]
|
||||
|
||||
// 6.1.3.3 Tuple helper classes.
|
||||
|
||||
template <typename Tuple> struct tuple_size;
|
||||
|
||||
|
||||
$for j [[
|
||||
template <GTEST_$(j)_TYPENAMES_(T)>
|
||||
struct tuple_size<GTEST_$(j)_TUPLE_(T) > {
|
||||
static const int value = $j;
|
||||
};
|
||||
|
||||
|
||||
]]
|
||||
template <int k, class Tuple>
|
||||
struct tuple_element {
|
||||
typedef typename gtest_internal::TupleElement<
|
||||
k < (tuple_size<Tuple>::value), k, Tuple>::type type;
|
||||
};
|
||||
|
||||
#define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element<k, Tuple >::type
|
||||
|
||||
// 6.1.3.4 Element access.
|
||||
|
||||
namespace gtest_internal {
|
||||
|
||||
|
||||
$for i [[
|
||||
template <>
|
||||
class Get<$i> {
|
||||
public:
|
||||
template <class Tuple>
|
||||
static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_($i, Tuple))
|
||||
Field(Tuple& t) { return t.f$(i)_; } // NOLINT
|
||||
|
||||
template <class Tuple>
|
||||
static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_($i, Tuple))
|
||||
ConstField(const Tuple& t) { return t.f$(i)_; }
|
||||
};
|
||||
|
||||
|
||||
]]
|
||||
} // namespace gtest_internal
|
||||
|
||||
template <int k, GTEST_$(n)_TYPENAMES_(T)>
|
||||
GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_$(n)_TUPLE_(T)))
|
||||
get(GTEST_$(n)_TUPLE_(T)& t) {
|
||||
return gtest_internal::Get<k>::Field(t);
|
||||
}
|
||||
|
||||
template <int k, GTEST_$(n)_TYPENAMES_(T)>
|
||||
GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_$(n)_TUPLE_(T)))
|
||||
get(const GTEST_$(n)_TUPLE_(T)& t) {
|
||||
return gtest_internal::Get<k>::ConstField(t);
|
||||
}
|
||||
|
||||
// 6.1.3.5 Relational operators
|
||||
|
||||
// We only implement == and !=, as we don't have a need for the rest yet.
|
||||
|
||||
namespace gtest_internal {
|
||||
|
||||
// SameSizeTuplePrefixComparator<k, k>::Eq(t1, t2) returns true if the
|
||||
// first k fields of t1 equals the first k fields of t2.
|
||||
// SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if
|
||||
// k1 != k2.
|
||||
template <int kSize1, int kSize2>
|
||||
struct SameSizeTuplePrefixComparator;
|
||||
|
||||
template <>
|
||||
struct SameSizeTuplePrefixComparator<0, 0> {
|
||||
template <class Tuple1, class Tuple2>
|
||||
static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <int k>
|
||||
struct SameSizeTuplePrefixComparator<k, k> {
|
||||
template <class Tuple1, class Tuple2>
|
||||
static bool Eq(const Tuple1& t1, const Tuple2& t2) {
|
||||
return SameSizeTuplePrefixComparator<k - 1, k - 1>::Eq(t1, t2) &&
|
||||
::std::tr1::get<k - 1>(t1) == ::std::tr1::get<k - 1>(t2);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace gtest_internal
|
||||
|
||||
template <GTEST_$(n)_TYPENAMES_(T), GTEST_$(n)_TYPENAMES_(U)>
|
||||
inline bool operator==(const GTEST_$(n)_TUPLE_(T)& t,
|
||||
const GTEST_$(n)_TUPLE_(U)& u) {
|
||||
return gtest_internal::SameSizeTuplePrefixComparator<
|
||||
tuple_size<GTEST_$(n)_TUPLE_(T) >::value,
|
||||
tuple_size<GTEST_$(n)_TUPLE_(U) >::value>::Eq(t, u);
|
||||
}
|
||||
|
||||
template <GTEST_$(n)_TYPENAMES_(T), GTEST_$(n)_TYPENAMES_(U)>
|
||||
inline bool operator!=(const GTEST_$(n)_TUPLE_(T)& t,
|
||||
const GTEST_$(n)_TUPLE_(U)& u) { return !(t == u); }
|
||||
|
||||
// 6.1.4 Pairs.
|
||||
// Unimplemented.
|
||||
|
||||
} // namespace tr1
|
||||
} // namespace std
|
||||
|
||||
|
||||
$for j [[
|
||||
#undef GTEST_$(j)_TUPLE_
|
||||
|
||||
]]
|
||||
|
||||
|
||||
$for j [[
|
||||
#undef GTEST_$(j)_TYPENAMES_
|
||||
|
||||
]]
|
||||
|
||||
#undef GTEST_DECLARE_TUPLE_AS_FRIEND_
|
||||
#undef GTEST_BY_REF_
|
||||
#undef GTEST_ADD_REF_
|
||||
#undef GTEST_TUPLE_ELEMENT_
|
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
|
||||
$$ -*- mode: c++; -*-
|
||||
$var n = 10 $$ Maximum number of tuple fields we want to support.
|
||||
$$ This meta comment fixes auto-indentation in Emacs. }}
|
||||
// Copyright 2009 Google Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Implements a subset of TR1 tuple needed by Google Test and Google Mock.
|
||||
|
||||
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
|
||||
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
|
||||
|
||||
#include <utility> // For ::std::pair.
|
||||
|
||||
// The compiler used in Symbian has a bug that prevents us from declaring the
|
||||
// tuple template as a friend (it complains that tuple is redefined). This
|
||||
// hack bypasses the bug by declaring the members that should otherwise be
|
||||
// private as public.
|
||||
// Sun Studio versions < 12 also have the above bug.
|
||||
#if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590)
|
||||
# define GTEST_DECLARE_TUPLE_AS_FRIEND_ public:
|
||||
#else
|
||||
# define GTEST_DECLARE_TUPLE_AS_FRIEND_ \
|
||||
template <GTEST_$(n)_TYPENAMES_(U)> friend class tuple; \
|
||||
private:
|
||||
#endif
|
||||
|
||||
|
||||
$range i 0..n-1
|
||||
$range j 0..n
|
||||
$range k 1..n
|
||||
// GTEST_n_TUPLE_(T) is the type of an n-tuple.
|
||||
#define GTEST_0_TUPLE_(T) tuple<>
|
||||
|
||||
$for k [[
|
||||
$range m 0..k-1
|
||||
$range m2 k..n-1
|
||||
#define GTEST_$(k)_TUPLE_(T) tuple<$for m, [[T##$m]]$for m2 [[, void]]>
|
||||
|
||||
]]
|
||||
|
||||
// GTEST_n_TYPENAMES_(T) declares a list of n typenames.
|
||||
|
||||
$for j [[
|
||||
$range m 0..j-1
|
||||
#define GTEST_$(j)_TYPENAMES_(T) $for m, [[typename T##$m]]
|
||||
|
||||
|
||||
]]
|
||||
|
||||
// In theory, defining stuff in the ::std namespace is undefined
|
||||
// behavior. We can do this as we are playing the role of a standard
|
||||
// library vendor.
|
||||
namespace std {
|
||||
namespace tr1 {
|
||||
|
||||
template <$for i, [[typename T$i = void]]>
|
||||
class tuple;
|
||||
|
||||
// Anything in namespace gtest_internal is Google Test's INTERNAL
|
||||
// IMPLEMENTATION DETAIL and MUST NOT BE USED DIRECTLY in user code.
|
||||
namespace gtest_internal {
|
||||
|
||||
// ByRef<T>::type is T if T is a reference; otherwise it's const T&.
|
||||
template <typename T>
|
||||
struct ByRef { typedef const T& type; }; // NOLINT
|
||||
template <typename T>
|
||||
struct ByRef<T&> { typedef T& type; }; // NOLINT
|
||||
|
||||
// A handy wrapper for ByRef.
|
||||
#define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef<T>::type
|
||||
|
||||
// AddRef<T>::type is T if T is a reference; otherwise it's T&. This
|
||||
// is the same as tr1::add_reference<T>::type.
|
||||
template <typename T>
|
||||
struct AddRef { typedef T& type; }; // NOLINT
|
||||
template <typename T>
|
||||
struct AddRef<T&> { typedef T& type; }; // NOLINT
|
||||
|
||||
// A handy wrapper for AddRef.
|
||||
#define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef<T>::type
|
||||
|
||||
// A helper for implementing get<k>().
|
||||
template <int k> class Get;
|
||||
|
||||
// A helper for implementing tuple_element<k, T>. kIndexValid is true
|
||||
// iff k < the number of fields in tuple type T.
|
||||
template <bool kIndexValid, int kIndex, class Tuple>
|
||||
struct TupleElement;
|
||||
|
||||
|
||||
$for i [[
|
||||
template <GTEST_$(n)_TYPENAMES_(T)>
|
||||
struct TupleElement<true, $i, GTEST_$(n)_TUPLE_(T) > {
|
||||
typedef T$i type;
|
||||
};
|
||||
|
||||
|
||||
]]
|
||||
} // namespace gtest_internal
|
||||
|
||||
template <>
|
||||
class tuple<> {
|
||||
public:
|
||||
tuple() {}
|
||||
tuple(const tuple& /* t */) {}
|
||||
tuple& operator=(const tuple& /* t */) { return *this; }
|
||||
};
|
||||
|
||||
|
||||
$for k [[
|
||||
$range m 0..k-1
|
||||
template <GTEST_$(k)_TYPENAMES_(T)>
|
||||
class $if k < n [[GTEST_$(k)_TUPLE_(T)]] $else [[tuple]] {
|
||||
public:
|
||||
template <int k> friend class gtest_internal::Get;
|
||||
|
||||
tuple() : $for m, [[f$(m)_()]] {}
|
||||
|
||||
explicit tuple($for m, [[GTEST_BY_REF_(T$m) f$m]]) : [[]]
|
||||
$for m, [[f$(m)_(f$m)]] {}
|
||||
|
||||
tuple(const tuple& t) : $for m, [[f$(m)_(t.f$(m)_)]] {}
|
||||
|
||||
template <GTEST_$(k)_TYPENAMES_(U)>
|
||||
tuple(const GTEST_$(k)_TUPLE_(U)& t) : $for m, [[f$(m)_(t.f$(m)_)]] {}
|
||||
|
||||
$if k == 2 [[
|
||||
template <typename U0, typename U1>
|
||||
tuple(const ::std::pair<U0, U1>& p) : f0_(p.first), f1_(p.second) {}
|
||||
|
||||
]]
|
||||
|
||||
tuple& operator=(const tuple& t) { return CopyFrom(t); }
|
||||
|
||||
template <GTEST_$(k)_TYPENAMES_(U)>
|
||||
tuple& operator=(const GTEST_$(k)_TUPLE_(U)& t) {
|
||||
return CopyFrom(t);
|
||||
}
|
||||
|
||||
$if k == 2 [[
|
||||
template <typename U0, typename U1>
|
||||
tuple& operator=(const ::std::pair<U0, U1>& p) {
|
||||
f0_ = p.first;
|
||||
f1_ = p.second;
|
||||
return *this;
|
||||
}
|
||||
|
||||
]]
|
||||
|
||||
GTEST_DECLARE_TUPLE_AS_FRIEND_
|
||||
|
||||
template <GTEST_$(k)_TYPENAMES_(U)>
|
||||
tuple& CopyFrom(const GTEST_$(k)_TUPLE_(U)& t) {
|
||||
|
||||
$for m [[
|
||||
f$(m)_ = t.f$(m)_;
|
||||
|
||||
]]
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
$for m [[
|
||||
T$m f$(m)_;
|
||||
|
||||
]]
|
||||
};
|
||||
|
||||
|
||||
]]
|
||||
// 6.1.3.2 Tuple creation functions.
|
||||
|
||||
// Known limitations: we don't support passing an
|
||||
// std::tr1::reference_wrapper<T> to make_tuple(). And we don't
|
||||
// implement tie().
|
||||
|
||||
inline tuple<> make_tuple() { return tuple<>(); }
|
||||
|
||||
$for k [[
|
||||
$range m 0..k-1
|
||||
|
||||
template <GTEST_$(k)_TYPENAMES_(T)>
|
||||
inline GTEST_$(k)_TUPLE_(T) make_tuple($for m, [[const T$m& f$m]]) {
|
||||
return GTEST_$(k)_TUPLE_(T)($for m, [[f$m]]);
|
||||
}
|
||||
|
||||
]]
|
||||
|
||||
// 6.1.3.3 Tuple helper classes.
|
||||
|
||||
template <typename Tuple> struct tuple_size;
|
||||
|
||||
|
||||
$for j [[
|
||||
template <GTEST_$(j)_TYPENAMES_(T)>
|
||||
struct tuple_size<GTEST_$(j)_TUPLE_(T) > {
|
||||
static const int value = $j;
|
||||
};
|
||||
|
||||
|
||||
]]
|
||||
template <int k, class Tuple>
|
||||
struct tuple_element {
|
||||
typedef typename gtest_internal::TupleElement<
|
||||
k < (tuple_size<Tuple>::value), k, Tuple>::type type;
|
||||
};
|
||||
|
||||
#define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element<k, Tuple >::type
|
||||
|
||||
// 6.1.3.4 Element access.
|
||||
|
||||
namespace gtest_internal {
|
||||
|
||||
|
||||
$for i [[
|
||||
template <>
|
||||
class Get<$i> {
|
||||
public:
|
||||
template <class Tuple>
|
||||
static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_($i, Tuple))
|
||||
Field(Tuple& t) { return t.f$(i)_; } // NOLINT
|
||||
|
||||
template <class Tuple>
|
||||
static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_($i, Tuple))
|
||||
ConstField(const Tuple& t) { return t.f$(i)_; }
|
||||
};
|
||||
|
||||
|
||||
]]
|
||||
} // namespace gtest_internal
|
||||
|
||||
template <int k, GTEST_$(n)_TYPENAMES_(T)>
|
||||
GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_$(n)_TUPLE_(T)))
|
||||
get(GTEST_$(n)_TUPLE_(T)& t) {
|
||||
return gtest_internal::Get<k>::Field(t);
|
||||
}
|
||||
|
||||
template <int k, GTEST_$(n)_TYPENAMES_(T)>
|
||||
GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_$(n)_TUPLE_(T)))
|
||||
get(const GTEST_$(n)_TUPLE_(T)& t) {
|
||||
return gtest_internal::Get<k>::ConstField(t);
|
||||
}
|
||||
|
||||
// 6.1.3.5 Relational operators
|
||||
|
||||
// We only implement == and !=, as we don't have a need for the rest yet.
|
||||
|
||||
namespace gtest_internal {
|
||||
|
||||
// SameSizeTuplePrefixComparator<k, k>::Eq(t1, t2) returns true if the
|
||||
// first k fields of t1 equals the first k fields of t2.
|
||||
// SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if
|
||||
// k1 != k2.
|
||||
template <int kSize1, int kSize2>
|
||||
struct SameSizeTuplePrefixComparator;
|
||||
|
||||
template <>
|
||||
struct SameSizeTuplePrefixComparator<0, 0> {
|
||||
template <class Tuple1, class Tuple2>
|
||||
static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <int k>
|
||||
struct SameSizeTuplePrefixComparator<k, k> {
|
||||
template <class Tuple1, class Tuple2>
|
||||
static bool Eq(const Tuple1& t1, const Tuple2& t2) {
|
||||
return SameSizeTuplePrefixComparator<k - 1, k - 1>::Eq(t1, t2) &&
|
||||
::std::tr1::get<k - 1>(t1) == ::std::tr1::get<k - 1>(t2);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace gtest_internal
|
||||
|
||||
template <GTEST_$(n)_TYPENAMES_(T), GTEST_$(n)_TYPENAMES_(U)>
|
||||
inline bool operator==(const GTEST_$(n)_TUPLE_(T)& t,
|
||||
const GTEST_$(n)_TUPLE_(U)& u) {
|
||||
return gtest_internal::SameSizeTuplePrefixComparator<
|
||||
tuple_size<GTEST_$(n)_TUPLE_(T) >::value,
|
||||
tuple_size<GTEST_$(n)_TUPLE_(U) >::value>::Eq(t, u);
|
||||
}
|
||||
|
||||
template <GTEST_$(n)_TYPENAMES_(T), GTEST_$(n)_TYPENAMES_(U)>
|
||||
inline bool operator!=(const GTEST_$(n)_TUPLE_(T)& t,
|
||||
const GTEST_$(n)_TUPLE_(U)& u) { return !(t == u); }
|
||||
|
||||
// 6.1.4 Pairs.
|
||||
// Unimplemented.
|
||||
|
||||
} // namespace tr1
|
||||
} // namespace std
|
||||
|
||||
|
||||
$for j [[
|
||||
#undef GTEST_$(j)_TUPLE_
|
||||
|
||||
]]
|
||||
|
||||
|
||||
$for j [[
|
||||
#undef GTEST_$(j)_TYPENAMES_
|
||||
|
||||
]]
|
||||
|
||||
#undef GTEST_DECLARE_TUPLE_AS_FRIEND_
|
||||
#undef GTEST_BY_REF_
|
||||
#undef GTEST_ADD_REF_
|
||||
#undef GTEST_TUPLE_ELEMENT_
|
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,297 +1,297 @@
|
||||
$$ -*- mode: c++; -*-
|
||||
$var n = 50 $$ Maximum length of type lists we want to support.
|
||||
// Copyright 2008 Google Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Type utilities needed for implementing typed and type-parameterized
|
||||
// tests. This file is generated by a SCRIPT. DO NOT EDIT BY HAND!
|
||||
//
|
||||
// Currently we support at most $n types in a list, and at most $n
|
||||
// type-parameterized tests in one type-parameterized test case.
|
||||
// Please contact googletestframework@googlegroups.com if you need
|
||||
// more.
|
||||
|
||||
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
|
||||
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
|
||||
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
|
||||
// #ifdef __GNUC__ is too general here. It is possible to use gcc without using
|
||||
// libstdc++ (which is where cxxabi.h comes from).
|
||||
# if GTEST_HAS_CXXABI_H_
|
||||
# include <cxxabi.h>
|
||||
# elif defined(__HP_aCC)
|
||||
# include <acxx_demangle.h>
|
||||
# endif // GTEST_HASH_CXXABI_H_
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// GetTypeName<T>() returns a human-readable name of type T.
|
||||
// NB: This function is also used in Google Mock, so don't move it inside of
|
||||
// the typed-test-only section below.
|
||||
template <typename T>
|
||||
std::string GetTypeName() {
|
||||
# if GTEST_HAS_RTTI
|
||||
|
||||
const char* const name = typeid(T).name();
|
||||
# if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC)
|
||||
int status = 0;
|
||||
// gcc's implementation of typeid(T).name() mangles the type name,
|
||||
// so we have to demangle it.
|
||||
# if GTEST_HAS_CXXABI_H_
|
||||
using abi::__cxa_demangle;
|
||||
# endif // GTEST_HAS_CXXABI_H_
|
||||
char* const readable_name = __cxa_demangle(name, 0, 0, &status);
|
||||
const std::string name_str(status == 0 ? readable_name : name);
|
||||
free(readable_name);
|
||||
return name_str;
|
||||
# else
|
||||
return name;
|
||||
# endif // GTEST_HAS_CXXABI_H_ || __HP_aCC
|
||||
|
||||
# else
|
||||
|
||||
return "<type>";
|
||||
|
||||
# endif // GTEST_HAS_RTTI
|
||||
}
|
||||
|
||||
#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
|
||||
|
||||
// AssertyTypeEq<T1, T2>::type is defined iff T1 and T2 are the same
|
||||
// type. This can be used as a compile-time assertion to ensure that
|
||||
// two types are equal.
|
||||
|
||||
template <typename T1, typename T2>
|
||||
struct AssertTypeEq;
|
||||
|
||||
template <typename T>
|
||||
struct AssertTypeEq<T, T> {
|
||||
typedef bool type;
|
||||
};
|
||||
|
||||
// A unique type used as the default value for the arguments of class
|
||||
// template Types. This allows us to simulate variadic templates
|
||||
// (e.g. Types<int>, Type<int, double>, and etc), which C++ doesn't
|
||||
// support directly.
|
||||
struct None {};
|
||||
|
||||
// The following family of struct and struct templates are used to
|
||||
// represent type lists. In particular, TypesN<T1, T2, ..., TN>
|
||||
// represents a type list with N types (T1, T2, ..., and TN) in it.
|
||||
// Except for Types0, every struct in the family has two member types:
|
||||
// Head for the first type in the list, and Tail for the rest of the
|
||||
// list.
|
||||
|
||||
// The empty type list.
|
||||
struct Types0 {};
|
||||
|
||||
// Type lists of length 1, 2, 3, and so on.
|
||||
|
||||
template <typename T1>
|
||||
struct Types1 {
|
||||
typedef T1 Head;
|
||||
typedef Types0 Tail;
|
||||
};
|
||||
|
||||
$range i 2..n
|
||||
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
$range k 2..i
|
||||
template <$for j, [[typename T$j]]>
|
||||
struct Types$i {
|
||||
typedef T1 Head;
|
||||
typedef Types$(i-1)<$for k, [[T$k]]> Tail;
|
||||
};
|
||||
|
||||
|
||||
]]
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// We don't want to require the users to write TypesN<...> directly,
|
||||
// as that would require them to count the length. Types<...> is much
|
||||
// easier to write, but generates horrible messages when there is a
|
||||
// compiler error, as gcc insists on printing out each template
|
||||
// argument, even if it has the default value (this means Types<int>
|
||||
// will appear as Types<int, None, None, ..., None> in the compiler
|
||||
// errors).
|
||||
//
|
||||
// Our solution is to combine the best part of the two approaches: a
|
||||
// user would write Types<T1, ..., TN>, and Google Test will translate
|
||||
// that to TypesN<T1, ..., TN> internally to make error messages
|
||||
// readable. The translation is done by the 'type' member of the
|
||||
// Types template.
|
||||
|
||||
$range i 1..n
|
||||
template <$for i, [[typename T$i = internal::None]]>
|
||||
struct Types {
|
||||
typedef internal::Types$n<$for i, [[T$i]]> type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Types<$for i, [[internal::None]]> {
|
||||
typedef internal::Types0 type;
|
||||
};
|
||||
|
||||
$range i 1..n-1
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
$range k i+1..n
|
||||
template <$for j, [[typename T$j]]>
|
||||
struct Types<$for j, [[T$j]]$for k[[, internal::None]]> {
|
||||
typedef internal::Types$i<$for j, [[T$j]]> type;
|
||||
};
|
||||
|
||||
]]
|
||||
|
||||
namespace internal {
|
||||
|
||||
# define GTEST_TEMPLATE_ template <typename T> class
|
||||
|
||||
// The template "selector" struct TemplateSel<Tmpl> is used to
|
||||
// represent Tmpl, which must be a class template with one type
|
||||
// parameter, as a type. TemplateSel<Tmpl>::Bind<T>::type is defined
|
||||
// as the type Tmpl<T>. This allows us to actually instantiate the
|
||||
// template "selected" by TemplateSel<Tmpl>.
|
||||
//
|
||||
// This trick is necessary for simulating typedef for class templates,
|
||||
// which C++ doesn't support directly.
|
||||
template <GTEST_TEMPLATE_ Tmpl>
|
||||
struct TemplateSel {
|
||||
template <typename T>
|
||||
struct Bind {
|
||||
typedef Tmpl<T> type;
|
||||
};
|
||||
};
|
||||
|
||||
# define GTEST_BIND_(TmplSel, T) \
|
||||
TmplSel::template Bind<T>::type
|
||||
|
||||
// A unique struct template used as the default value for the
|
||||
// arguments of class template Templates. This allows us to simulate
|
||||
// variadic templates (e.g. Templates<int>, Templates<int, double>,
|
||||
// and etc), which C++ doesn't support directly.
|
||||
template <typename T>
|
||||
struct NoneT {};
|
||||
|
||||
// The following family of struct and struct templates are used to
|
||||
// represent template lists. In particular, TemplatesN<T1, T2, ...,
|
||||
// TN> represents a list of N templates (T1, T2, ..., and TN). Except
|
||||
// for Templates0, every struct in the family has two member types:
|
||||
// Head for the selector of the first template in the list, and Tail
|
||||
// for the rest of the list.
|
||||
|
||||
// The empty template list.
|
||||
struct Templates0 {};
|
||||
|
||||
// Template lists of length 1, 2, 3, and so on.
|
||||
|
||||
template <GTEST_TEMPLATE_ T1>
|
||||
struct Templates1 {
|
||||
typedef TemplateSel<T1> Head;
|
||||
typedef Templates0 Tail;
|
||||
};
|
||||
|
||||
$range i 2..n
|
||||
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
$range k 2..i
|
||||
template <$for j, [[GTEST_TEMPLATE_ T$j]]>
|
||||
struct Templates$i {
|
||||
typedef TemplateSel<T1> Head;
|
||||
typedef Templates$(i-1)<$for k, [[T$k]]> Tail;
|
||||
};
|
||||
|
||||
|
||||
]]
|
||||
|
||||
// We don't want to require the users to write TemplatesN<...> directly,
|
||||
// as that would require them to count the length. Templates<...> is much
|
||||
// easier to write, but generates horrible messages when there is a
|
||||
// compiler error, as gcc insists on printing out each template
|
||||
// argument, even if it has the default value (this means Templates<list>
|
||||
// will appear as Templates<list, NoneT, NoneT, ..., NoneT> in the compiler
|
||||
// errors).
|
||||
//
|
||||
// Our solution is to combine the best part of the two approaches: a
|
||||
// user would write Templates<T1, ..., TN>, and Google Test will translate
|
||||
// that to TemplatesN<T1, ..., TN> internally to make error messages
|
||||
// readable. The translation is done by the 'type' member of the
|
||||
// Templates template.
|
||||
|
||||
$range i 1..n
|
||||
template <$for i, [[GTEST_TEMPLATE_ T$i = NoneT]]>
|
||||
struct Templates {
|
||||
typedef Templates$n<$for i, [[T$i]]> type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Templates<$for i, [[NoneT]]> {
|
||||
typedef Templates0 type;
|
||||
};
|
||||
|
||||
$range i 1..n-1
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
$range k i+1..n
|
||||
template <$for j, [[GTEST_TEMPLATE_ T$j]]>
|
||||
struct Templates<$for j, [[T$j]]$for k[[, NoneT]]> {
|
||||
typedef Templates$i<$for j, [[T$j]]> type;
|
||||
};
|
||||
|
||||
]]
|
||||
|
||||
// The TypeList template makes it possible to use either a single type
|
||||
// or a Types<...> list in TYPED_TEST_CASE() and
|
||||
// INSTANTIATE_TYPED_TEST_CASE_P().
|
||||
|
||||
template <typename T>
|
||||
struct TypeList {
|
||||
typedef Types1<T> type;
|
||||
};
|
||||
|
||||
|
||||
$range i 1..n
|
||||
template <$for i, [[typename T$i]]>
|
||||
struct TypeList<Types<$for i, [[T$i]]> > {
|
||||
typedef typename Types<$for i, [[T$i]]>::type type;
|
||||
};
|
||||
|
||||
#endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
|
||||
$$ -*- mode: c++; -*-
|
||||
$var n = 50 $$ Maximum length of type lists we want to support.
|
||||
// Copyright 2008 Google Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Type utilities needed for implementing typed and type-parameterized
|
||||
// tests. This file is generated by a SCRIPT. DO NOT EDIT BY HAND!
|
||||
//
|
||||
// Currently we support at most $n types in a list, and at most $n
|
||||
// type-parameterized tests in one type-parameterized test case.
|
||||
// Please contact googletestframework@googlegroups.com if you need
|
||||
// more.
|
||||
|
||||
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
|
||||
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
|
||||
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
|
||||
// #ifdef __GNUC__ is too general here. It is possible to use gcc without using
|
||||
// libstdc++ (which is where cxxabi.h comes from).
|
||||
# if GTEST_HAS_CXXABI_H_
|
||||
# include <cxxabi.h>
|
||||
# elif defined(__HP_aCC)
|
||||
# include <acxx_demangle.h>
|
||||
# endif // GTEST_HASH_CXXABI_H_
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// GetTypeName<T>() returns a human-readable name of type T.
|
||||
// NB: This function is also used in Google Mock, so don't move it inside of
|
||||
// the typed-test-only section below.
|
||||
template <typename T>
|
||||
std::string GetTypeName() {
|
||||
# if GTEST_HAS_RTTI
|
||||
|
||||
const char* const name = typeid(T).name();
|
||||
# if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC)
|
||||
int status = 0;
|
||||
// gcc's implementation of typeid(T).name() mangles the type name,
|
||||
// so we have to demangle it.
|
||||
# if GTEST_HAS_CXXABI_H_
|
||||
using abi::__cxa_demangle;
|
||||
# endif // GTEST_HAS_CXXABI_H_
|
||||
char* const readable_name = __cxa_demangle(name, 0, 0, &status);
|
||||
const std::string name_str(status == 0 ? readable_name : name);
|
||||
free(readable_name);
|
||||
return name_str;
|
||||
# else
|
||||
return name;
|
||||
# endif // GTEST_HAS_CXXABI_H_ || __HP_aCC
|
||||
|
||||
# else
|
||||
|
||||
return "<type>";
|
||||
|
||||
# endif // GTEST_HAS_RTTI
|
||||
}
|
||||
|
||||
#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
|
||||
|
||||
// AssertyTypeEq<T1, T2>::type is defined iff T1 and T2 are the same
|
||||
// type. This can be used as a compile-time assertion to ensure that
|
||||
// two types are equal.
|
||||
|
||||
template <typename T1, typename T2>
|
||||
struct AssertTypeEq;
|
||||
|
||||
template <typename T>
|
||||
struct AssertTypeEq<T, T> {
|
||||
typedef bool type;
|
||||
};
|
||||
|
||||
// A unique type used as the default value for the arguments of class
|
||||
// template Types. This allows us to simulate variadic templates
|
||||
// (e.g. Types<int>, Type<int, double>, and etc), which C++ doesn't
|
||||
// support directly.
|
||||
struct None {};
|
||||
|
||||
// The following family of struct and struct templates are used to
|
||||
// represent type lists. In particular, TypesN<T1, T2, ..., TN>
|
||||
// represents a type list with N types (T1, T2, ..., and TN) in it.
|
||||
// Except for Types0, every struct in the family has two member types:
|
||||
// Head for the first type in the list, and Tail for the rest of the
|
||||
// list.
|
||||
|
||||
// The empty type list.
|
||||
struct Types0 {};
|
||||
|
||||
// Type lists of length 1, 2, 3, and so on.
|
||||
|
||||
template <typename T1>
|
||||
struct Types1 {
|
||||
typedef T1 Head;
|
||||
typedef Types0 Tail;
|
||||
};
|
||||
|
||||
$range i 2..n
|
||||
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
$range k 2..i
|
||||
template <$for j, [[typename T$j]]>
|
||||
struct Types$i {
|
||||
typedef T1 Head;
|
||||
typedef Types$(i-1)<$for k, [[T$k]]> Tail;
|
||||
};
|
||||
|
||||
|
||||
]]
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// We don't want to require the users to write TypesN<...> directly,
|
||||
// as that would require them to count the length. Types<...> is much
|
||||
// easier to write, but generates horrible messages when there is a
|
||||
// compiler error, as gcc insists on printing out each template
|
||||
// argument, even if it has the default value (this means Types<int>
|
||||
// will appear as Types<int, None, None, ..., None> in the compiler
|
||||
// errors).
|
||||
//
|
||||
// Our solution is to combine the best part of the two approaches: a
|
||||
// user would write Types<T1, ..., TN>, and Google Test will translate
|
||||
// that to TypesN<T1, ..., TN> internally to make error messages
|
||||
// readable. The translation is done by the 'type' member of the
|
||||
// Types template.
|
||||
|
||||
$range i 1..n
|
||||
template <$for i, [[typename T$i = internal::None]]>
|
||||
struct Types {
|
||||
typedef internal::Types$n<$for i, [[T$i]]> type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Types<$for i, [[internal::None]]> {
|
||||
typedef internal::Types0 type;
|
||||
};
|
||||
|
||||
$range i 1..n-1
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
$range k i+1..n
|
||||
template <$for j, [[typename T$j]]>
|
||||
struct Types<$for j, [[T$j]]$for k[[, internal::None]]> {
|
||||
typedef internal::Types$i<$for j, [[T$j]]> type;
|
||||
};
|
||||
|
||||
]]
|
||||
|
||||
namespace internal {
|
||||
|
||||
# define GTEST_TEMPLATE_ template <typename T> class
|
||||
|
||||
// The template "selector" struct TemplateSel<Tmpl> is used to
|
||||
// represent Tmpl, which must be a class template with one type
|
||||
// parameter, as a type. TemplateSel<Tmpl>::Bind<T>::type is defined
|
||||
// as the type Tmpl<T>. This allows us to actually instantiate the
|
||||
// template "selected" by TemplateSel<Tmpl>.
|
||||
//
|
||||
// This trick is necessary for simulating typedef for class templates,
|
||||
// which C++ doesn't support directly.
|
||||
template <GTEST_TEMPLATE_ Tmpl>
|
||||
struct TemplateSel {
|
||||
template <typename T>
|
||||
struct Bind {
|
||||
typedef Tmpl<T> type;
|
||||
};
|
||||
};
|
||||
|
||||
# define GTEST_BIND_(TmplSel, T) \
|
||||
TmplSel::template Bind<T>::type
|
||||
|
||||
// A unique struct template used as the default value for the
|
||||
// arguments of class template Templates. This allows us to simulate
|
||||
// variadic templates (e.g. Templates<int>, Templates<int, double>,
|
||||
// and etc), which C++ doesn't support directly.
|
||||
template <typename T>
|
||||
struct NoneT {};
|
||||
|
||||
// The following family of struct and struct templates are used to
|
||||
// represent template lists. In particular, TemplatesN<T1, T2, ...,
|
||||
// TN> represents a list of N templates (T1, T2, ..., and TN). Except
|
||||
// for Templates0, every struct in the family has two member types:
|
||||
// Head for the selector of the first template in the list, and Tail
|
||||
// for the rest of the list.
|
||||
|
||||
// The empty template list.
|
||||
struct Templates0 {};
|
||||
|
||||
// Template lists of length 1, 2, 3, and so on.
|
||||
|
||||
template <GTEST_TEMPLATE_ T1>
|
||||
struct Templates1 {
|
||||
typedef TemplateSel<T1> Head;
|
||||
typedef Templates0 Tail;
|
||||
};
|
||||
|
||||
$range i 2..n
|
||||
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
$range k 2..i
|
||||
template <$for j, [[GTEST_TEMPLATE_ T$j]]>
|
||||
struct Templates$i {
|
||||
typedef TemplateSel<T1> Head;
|
||||
typedef Templates$(i-1)<$for k, [[T$k]]> Tail;
|
||||
};
|
||||
|
||||
|
||||
]]
|
||||
|
||||
// We don't want to require the users to write TemplatesN<...> directly,
|
||||
// as that would require them to count the length. Templates<...> is much
|
||||
// easier to write, but generates horrible messages when there is a
|
||||
// compiler error, as gcc insists on printing out each template
|
||||
// argument, even if it has the default value (this means Templates<list>
|
||||
// will appear as Templates<list, NoneT, NoneT, ..., NoneT> in the compiler
|
||||
// errors).
|
||||
//
|
||||
// Our solution is to combine the best part of the two approaches: a
|
||||
// user would write Templates<T1, ..., TN>, and Google Test will translate
|
||||
// that to TemplatesN<T1, ..., TN> internally to make error messages
|
||||
// readable. The translation is done by the 'type' member of the
|
||||
// Templates template.
|
||||
|
||||
$range i 1..n
|
||||
template <$for i, [[GTEST_TEMPLATE_ T$i = NoneT]]>
|
||||
struct Templates {
|
||||
typedef Templates$n<$for i, [[T$i]]> type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Templates<$for i, [[NoneT]]> {
|
||||
typedef Templates0 type;
|
||||
};
|
||||
|
||||
$range i 1..n-1
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
$range k i+1..n
|
||||
template <$for j, [[GTEST_TEMPLATE_ T$j]]>
|
||||
struct Templates<$for j, [[T$j]]$for k[[, NoneT]]> {
|
||||
typedef Templates$i<$for j, [[T$j]]> type;
|
||||
};
|
||||
|
||||
]]
|
||||
|
||||
// The TypeList template makes it possible to use either a single type
|
||||
// or a Types<...> list in TYPED_TEST_CASE() and
|
||||
// INSTANTIATE_TYPED_TEST_CASE_P().
|
||||
|
||||
template <typename T>
|
||||
struct TypeList {
|
||||
typedef Types1<T> type;
|
||||
};
|
||||
|
||||
|
||||
$range i 1..n
|
||||
template <$for i, [[typename T$i]]>
|
||||
struct TypeList<Types<$for i, [[T$i]]> > {
|
||||
typedef typename Types<$for i, [[T$i]]>::type type;
|
||||
};
|
||||
|
||||
#endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
|
||||
@@ -1,48 +1,48 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: mheule@google.com (Markus Heule)
|
||||
//
|
||||
// Google C++ Testing Framework (Google Test)
|
||||
//
|
||||
// Sometimes it's desirable to build Google Test by compiling a single file.
|
||||
// This file serves this purpose.
|
||||
|
||||
// This line ensures that gtest.h can be compiled on its own, even
|
||||
// when it's fused.
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
// The following lines pull in the real gtest *.cc files.
|
||||
#include "src/gtest.cc"
|
||||
#include "src/gtest-death-test.cc"
|
||||
#include "src/gtest-filepath.cc"
|
||||
#include "src/gtest-port.cc"
|
||||
#include "src/gtest-printers.cc"
|
||||
#include "src/gtest-test-part.cc"
|
||||
#include "src/gtest-typed-test.cc"
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: mheule@google.com (Markus Heule)
|
||||
//
|
||||
// Google C++ Testing Framework (Google Test)
|
||||
//
|
||||
// Sometimes it's desirable to build Google Test by compiling a single file.
|
||||
// This file serves this purpose.
|
||||
|
||||
// This line ensures that gtest.h can be compiled on its own, even
|
||||
// when it's fused.
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
// The following lines pull in the real gtest *.cc files.
|
||||
#include "src/gtest.cc"
|
||||
#include "src/gtest-death-test.cc"
|
||||
#include "src/gtest-filepath.cc"
|
||||
#include "src/gtest-port.cc"
|
||||
#include "src/gtest-printers.cc"
|
||||
#include "src/gtest-test-part.cc"
|
||||
#include "src/gtest-typed-test.cc"
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,380 +1,382 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Authors: keith.ray@gmail.com (Keith Ray)
|
||||
|
||||
#include "gtest/gtest-message.h"
|
||||
#include "gtest/internal/gtest-filepath.h"
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#if GTEST_OS_WINDOWS_MOBILE
|
||||
# include <windows.h>
|
||||
#elif GTEST_OS_WINDOWS
|
||||
# include <direct.h>
|
||||
# include <io.h>
|
||||
#elif GTEST_OS_SYMBIAN
|
||||
// Symbian OpenC has PATH_MAX in sys/syslimits.h
|
||||
# include <sys/syslimits.h>
|
||||
#else
|
||||
# include <limits.h>
|
||||
# include <climits> // Some Linux distributions define PATH_MAX here.
|
||||
#endif // GTEST_OS_WINDOWS_MOBILE
|
||||
|
||||
#if GTEST_OS_WINDOWS
|
||||
# define GTEST_PATH_MAX_ _MAX_PATH
|
||||
#elif defined(PATH_MAX)
|
||||
# define GTEST_PATH_MAX_ PATH_MAX
|
||||
#elif defined(_XOPEN_PATH_MAX)
|
||||
# define GTEST_PATH_MAX_ _XOPEN_PATH_MAX
|
||||
#else
|
||||
# define GTEST_PATH_MAX_ _POSIX_PATH_MAX
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
|
||||
#include "gtest/internal/gtest-string.h"
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
#if GTEST_OS_WINDOWS
|
||||
// On Windows, '\\' is the standard path separator, but many tools and the
|
||||
// Windows API also accept '/' as an alternate path separator. Unless otherwise
|
||||
// noted, a file path can contain either kind of path separators, or a mixture
|
||||
// of them.
|
||||
const char kPathSeparator = '\\';
|
||||
const char kAlternatePathSeparator = '/';
|
||||
const char kAlternatePathSeparatorString[] = "/";
|
||||
# if GTEST_OS_WINDOWS_MOBILE
|
||||
// Windows CE doesn't have a current directory. You should not use
|
||||
// the current directory in tests on Windows CE, but this at least
|
||||
// provides a reasonable fallback.
|
||||
const char kCurrentDirectoryString[] = "\\";
|
||||
// Windows CE doesn't define INVALID_FILE_ATTRIBUTES
|
||||
const DWORD kInvalidFileAttributes = 0xffffffff;
|
||||
# else
|
||||
const char kCurrentDirectoryString[] = ".\\";
|
||||
# endif // GTEST_OS_WINDOWS_MOBILE
|
||||
#else
|
||||
const char kPathSeparator = '/';
|
||||
const char kCurrentDirectoryString[] = "./";
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
|
||||
// Returns whether the given character is a valid path separator.
|
||||
static bool IsPathSeparator(char c) {
|
||||
#if GTEST_HAS_ALT_PATH_SEP_
|
||||
return (c == kPathSeparator) || (c == kAlternatePathSeparator);
|
||||
#else
|
||||
return c == kPathSeparator;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Returns the current working directory, or "" if unsuccessful.
|
||||
FilePath FilePath::GetCurrentDir() {
|
||||
#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT
|
||||
// Windows CE doesn't have a current directory, so we just return
|
||||
// something reasonable.
|
||||
return FilePath(kCurrentDirectoryString);
|
||||
#elif GTEST_OS_WINDOWS
|
||||
char cwd[GTEST_PATH_MAX_ + 1] = { '\0' };
|
||||
return FilePath(_getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd);
|
||||
#else
|
||||
char cwd[GTEST_PATH_MAX_ + 1] = { '\0' };
|
||||
return FilePath(getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd);
|
||||
#endif // GTEST_OS_WINDOWS_MOBILE
|
||||
}
|
||||
|
||||
// Returns a copy of the FilePath with the case-insensitive extension removed.
|
||||
// Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns
|
||||
// FilePath("dir/file"). If a case-insensitive extension is not
|
||||
// found, returns a copy of the original FilePath.
|
||||
FilePath FilePath::RemoveExtension(const char* extension) const {
|
||||
const std::string dot_extension = std::string(".") + extension;
|
||||
if (String::EndsWithCaseInsensitive(pathname_, dot_extension)) {
|
||||
return FilePath(pathname_.substr(
|
||||
0, pathname_.length() - dot_extension.length()));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Returns a pointer to the last occurence of a valid path separator in
|
||||
// the FilePath. On Windows, for example, both '/' and '\' are valid path
|
||||
// separators. Returns NULL if no path separator was found.
|
||||
const char* FilePath::FindLastPathSeparator() const {
|
||||
const char* const last_sep = strrchr(c_str(), kPathSeparator);
|
||||
#if GTEST_HAS_ALT_PATH_SEP_
|
||||
const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator);
|
||||
// Comparing two pointers of which only one is NULL is undefined.
|
||||
if (last_alt_sep != NULL &&
|
||||
(last_sep == NULL || last_alt_sep > last_sep)) {
|
||||
return last_alt_sep;
|
||||
}
|
||||
#endif
|
||||
return last_sep;
|
||||
}
|
||||
|
||||
// Returns a copy of the FilePath with the directory part removed.
|
||||
// Example: FilePath("path/to/file").RemoveDirectoryName() returns
|
||||
// FilePath("file"). If there is no directory part ("just_a_file"), it returns
|
||||
// the FilePath unmodified. If there is no file part ("just_a_dir/") it
|
||||
// returns an empty FilePath ("").
|
||||
// On Windows platform, '\' is the path separator, otherwise it is '/'.
|
||||
FilePath FilePath::RemoveDirectoryName() const {
|
||||
const char* const last_sep = FindLastPathSeparator();
|
||||
return last_sep ? FilePath(last_sep + 1) : *this;
|
||||
}
|
||||
|
||||
// RemoveFileName returns the directory path with the filename removed.
|
||||
// Example: FilePath("path/to/file").RemoveFileName() returns "path/to/".
|
||||
// If the FilePath is "a_file" or "/a_file", RemoveFileName returns
|
||||
// FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does
|
||||
// not have a file, like "just/a/dir/", it returns the FilePath unmodified.
|
||||
// On Windows platform, '\' is the path separator, otherwise it is '/'.
|
||||
FilePath FilePath::RemoveFileName() const {
|
||||
const char* const last_sep = FindLastPathSeparator();
|
||||
std::string dir;
|
||||
if (last_sep) {
|
||||
dir = std::string(c_str(), last_sep + 1 - c_str());
|
||||
} else {
|
||||
dir = kCurrentDirectoryString;
|
||||
}
|
||||
return FilePath(dir);
|
||||
}
|
||||
|
||||
// Helper functions for naming files in a directory for xml output.
|
||||
|
||||
// Given directory = "dir", base_name = "test", number = 0,
|
||||
// extension = "xml", returns "dir/test.xml". If number is greater
|
||||
// than zero (e.g., 12), returns "dir/test_12.xml".
|
||||
// On Windows platform, uses \ as the separator rather than /.
|
||||
FilePath FilePath::MakeFileName(const FilePath& directory,
|
||||
const FilePath& base_name,
|
||||
int number,
|
||||
const char* extension) {
|
||||
std::string file;
|
||||
if (number == 0) {
|
||||
file = base_name.string() + "." + extension;
|
||||
} else {
|
||||
file = base_name.string() + "_" + StreamableToString(number)
|
||||
+ "." + extension;
|
||||
}
|
||||
return ConcatPaths(directory, FilePath(file));
|
||||
}
|
||||
|
||||
// Given directory = "dir", relative_path = "test.xml", returns "dir/test.xml".
|
||||
// On Windows, uses \ as the separator rather than /.
|
||||
FilePath FilePath::ConcatPaths(const FilePath& directory,
|
||||
const FilePath& relative_path) {
|
||||
if (directory.IsEmpty())
|
||||
return relative_path;
|
||||
const FilePath dir(directory.RemoveTrailingPathSeparator());
|
||||
return FilePath(dir.string() + kPathSeparator + relative_path.string());
|
||||
}
|
||||
|
||||
// Returns true if pathname describes something findable in the file-system,
|
||||
// either a file, directory, or whatever.
|
||||
bool FilePath::FileOrDirectoryExists() const {
|
||||
#if GTEST_OS_WINDOWS_MOBILE
|
||||
LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str());
|
||||
const DWORD attributes = GetFileAttributes(unicode);
|
||||
delete [] unicode;
|
||||
return attributes != kInvalidFileAttributes;
|
||||
#else
|
||||
posix::StatStruct file_stat;
|
||||
return posix::Stat(pathname_.c_str(), &file_stat) == 0;
|
||||
#endif // GTEST_OS_WINDOWS_MOBILE
|
||||
}
|
||||
|
||||
// Returns true if pathname describes a directory in the file-system
|
||||
// that exists.
|
||||
bool FilePath::DirectoryExists() const {
|
||||
bool result = false;
|
||||
#if GTEST_OS_WINDOWS
|
||||
// Don't strip off trailing separator if path is a root directory on
|
||||
// Windows (like "C:\\").
|
||||
const FilePath& path(IsRootDirectory() ? *this :
|
||||
RemoveTrailingPathSeparator());
|
||||
#else
|
||||
const FilePath& path(*this);
|
||||
#endif
|
||||
|
||||
#if GTEST_OS_WINDOWS_MOBILE
|
||||
LPCWSTR unicode = String::AnsiToUtf16(path.c_str());
|
||||
const DWORD attributes = GetFileAttributes(unicode);
|
||||
delete [] unicode;
|
||||
if ((attributes != kInvalidFileAttributes) &&
|
||||
(attributes & FILE_ATTRIBUTE_DIRECTORY)) {
|
||||
result = true;
|
||||
}
|
||||
#else
|
||||
posix::StatStruct file_stat;
|
||||
result = posix::Stat(path.c_str(), &file_stat) == 0 &&
|
||||
posix::IsDir(file_stat);
|
||||
#endif // GTEST_OS_WINDOWS_MOBILE
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Returns true if pathname describes a root directory. (Windows has one
|
||||
// root directory per disk drive.)
|
||||
bool FilePath::IsRootDirectory() const {
|
||||
#if GTEST_OS_WINDOWS
|
||||
// TODO(wan@google.com): on Windows a network share like
|
||||
// \\server\share can be a root directory, although it cannot be the
|
||||
// current directory. Handle this properly.
|
||||
return pathname_.length() == 3 && IsAbsolutePath();
|
||||
#else
|
||||
return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Returns true if pathname describes an absolute path.
|
||||
bool FilePath::IsAbsolutePath() const {
|
||||
const char* const name = pathname_.c_str();
|
||||
#if GTEST_OS_WINDOWS
|
||||
return pathname_.length() >= 3 &&
|
||||
((name[0] >= 'a' && name[0] <= 'z') ||
|
||||
(name[0] >= 'A' && name[0] <= 'Z')) &&
|
||||
name[1] == ':' &&
|
||||
IsPathSeparator(name[2]);
|
||||
#else
|
||||
return IsPathSeparator(name[0]);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Returns a pathname for a file that does not currently exist. The pathname
|
||||
// will be directory/base_name.extension or
|
||||
// directory/base_name_<number>.extension if directory/base_name.extension
|
||||
// already exists. The number will be incremented until a pathname is found
|
||||
// that does not already exist.
|
||||
// Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'.
|
||||
// There could be a race condition if two or more processes are calling this
|
||||
// function at the same time -- they could both pick the same filename.
|
||||
FilePath FilePath::GenerateUniqueFileName(const FilePath& directory,
|
||||
const FilePath& base_name,
|
||||
const char* extension) {
|
||||
FilePath full_pathname;
|
||||
int number = 0;
|
||||
do {
|
||||
full_pathname.Set(MakeFileName(directory, base_name, number++, extension));
|
||||
} while (full_pathname.FileOrDirectoryExists());
|
||||
return full_pathname;
|
||||
}
|
||||
|
||||
// Returns true if FilePath ends with a path separator, which indicates that
|
||||
// it is intended to represent a directory. Returns false otherwise.
|
||||
// This does NOT check that a directory (or file) actually exists.
|
||||
bool FilePath::IsDirectory() const {
|
||||
return !pathname_.empty() &&
|
||||
IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]);
|
||||
}
|
||||
|
||||
// Create directories so that path exists. Returns true if successful or if
|
||||
// the directories already exist; returns false if unable to create directories
|
||||
// for any reason.
|
||||
bool FilePath::CreateDirectoriesRecursively() const {
|
||||
if (!this->IsDirectory()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pathname_.length() == 0 || this->DirectoryExists()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const FilePath parent(this->RemoveTrailingPathSeparator().RemoveFileName());
|
||||
return parent.CreateDirectoriesRecursively() && this->CreateFolder();
|
||||
}
|
||||
|
||||
// Create the directory so that path exists. Returns true if successful or
|
||||
// if the directory already exists; returns false if unable to create the
|
||||
// directory for any reason, including if the parent directory does not
|
||||
// exist. Not named "CreateDirectory" because that's a macro on Windows.
|
||||
bool FilePath::CreateFolder() const {
|
||||
#if GTEST_OS_WINDOWS_MOBILE
|
||||
FilePath removed_sep(this->RemoveTrailingPathSeparator());
|
||||
LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str());
|
||||
int result = CreateDirectory(unicode, NULL) ? 0 : -1;
|
||||
delete [] unicode;
|
||||
#elif GTEST_OS_WINDOWS
|
||||
int result = _mkdir(pathname_.c_str());
|
||||
#else
|
||||
int result = mkdir(pathname_.c_str(), 0777);
|
||||
#endif // GTEST_OS_WINDOWS_MOBILE
|
||||
|
||||
if (result == -1) {
|
||||
return this->DirectoryExists(); // An error is OK if the directory exists.
|
||||
}
|
||||
return true; // No error.
|
||||
}
|
||||
|
||||
// If input name has a trailing separator character, remove it and return the
|
||||
// name, otherwise return the name string unmodified.
|
||||
// On Windows platform, uses \ as the separator, other platforms use /.
|
||||
FilePath FilePath::RemoveTrailingPathSeparator() const {
|
||||
return IsDirectory()
|
||||
? FilePath(pathname_.substr(0, pathname_.length() - 1))
|
||||
: *this;
|
||||
}
|
||||
|
||||
// Removes any redundant separators that might be in the pathname.
|
||||
// For example, "bar///foo" becomes "bar/foo". Does not eliminate other
|
||||
// redundancies that might be in a pathname involving "." or "..".
|
||||
// TODO(wan@google.com): handle Windows network shares (e.g. \\server\share).
|
||||
void FilePath::Normalize() {
|
||||
if (pathname_.c_str() == NULL) {
|
||||
pathname_ = "";
|
||||
return;
|
||||
}
|
||||
const char* src = pathname_.c_str();
|
||||
char* const dest = new char[pathname_.length() + 1];
|
||||
char* dest_ptr = dest;
|
||||
memset(dest_ptr, 0, pathname_.length() + 1);
|
||||
|
||||
while (*src != '\0') {
|
||||
*dest_ptr = *src;
|
||||
if (!IsPathSeparator(*src)) {
|
||||
src++;
|
||||
} else {
|
||||
#if GTEST_HAS_ALT_PATH_SEP_
|
||||
if (*dest_ptr == kAlternatePathSeparator) {
|
||||
*dest_ptr = kPathSeparator;
|
||||
}
|
||||
#endif
|
||||
while (IsPathSeparator(*src))
|
||||
src++;
|
||||
}
|
||||
dest_ptr++;
|
||||
}
|
||||
*dest_ptr = '\0';
|
||||
pathname_ = dest;
|
||||
delete[] dest;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Authors: keith.ray@gmail.com (Keith Ray)
|
||||
|
||||
#include "gtest/gtest-message.h"
|
||||
#include "gtest/internal/gtest-filepath.h"
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#if GTEST_OS_WINDOWS_MOBILE
|
||||
# include <windows.h>
|
||||
#elif GTEST_OS_WINDOWS
|
||||
# include <direct.h>
|
||||
# include <io.h>
|
||||
#elif GTEST_OS_SYMBIAN
|
||||
// Symbian OpenC has PATH_MAX in sys/syslimits.h
|
||||
# include <sys/syslimits.h>
|
||||
#else
|
||||
# include <limits.h>
|
||||
# include <climits> // Some Linux distributions define PATH_MAX here.
|
||||
#endif // GTEST_OS_WINDOWS_MOBILE
|
||||
|
||||
#if GTEST_OS_WINDOWS
|
||||
# define GTEST_PATH_MAX_ _MAX_PATH
|
||||
#elif defined(PATH_MAX)
|
||||
# define GTEST_PATH_MAX_ PATH_MAX
|
||||
#elif defined(_XOPEN_PATH_MAX)
|
||||
# define GTEST_PATH_MAX_ _XOPEN_PATH_MAX
|
||||
#else
|
||||
# define GTEST_PATH_MAX_ _POSIX_PATH_MAX
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
|
||||
#include "gtest/internal/gtest-string.h"
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
#if GTEST_OS_WINDOWS
|
||||
// On Windows, '\\' is the standard path separator, but many tools and the
|
||||
// Windows API also accept '/' as an alternate path separator. Unless otherwise
|
||||
// noted, a file path can contain either kind of path separators, or a mixture
|
||||
// of them.
|
||||
const char kPathSeparator = '\\';
|
||||
const char kAlternatePathSeparator = '/';
|
||||
const char kPathSeparatorString[] = "\\";
|
||||
const char kAlternatePathSeparatorString[] = "/";
|
||||
# if GTEST_OS_WINDOWS_MOBILE
|
||||
// Windows CE doesn't have a current directory. You should not use
|
||||
// the current directory in tests on Windows CE, but this at least
|
||||
// provides a reasonable fallback.
|
||||
const char kCurrentDirectoryString[] = "\\";
|
||||
// Windows CE doesn't define INVALID_FILE_ATTRIBUTES
|
||||
const DWORD kInvalidFileAttributes = 0xffffffff;
|
||||
# else
|
||||
const char kCurrentDirectoryString[] = ".\\";
|
||||
# endif // GTEST_OS_WINDOWS_MOBILE
|
||||
#else
|
||||
const char kPathSeparator = '/';
|
||||
const char kPathSeparatorString[] = "/";
|
||||
const char kCurrentDirectoryString[] = "./";
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
|
||||
// Returns whether the given character is a valid path separator.
|
||||
static bool IsPathSeparator(char c) {
|
||||
#if GTEST_HAS_ALT_PATH_SEP_
|
||||
return (c == kPathSeparator) || (c == kAlternatePathSeparator);
|
||||
#else
|
||||
return c == kPathSeparator;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Returns the current working directory, or "" if unsuccessful.
|
||||
FilePath FilePath::GetCurrentDir() {
|
||||
#if GTEST_OS_WINDOWS_MOBILE
|
||||
// Windows CE doesn't have a current directory, so we just return
|
||||
// something reasonable.
|
||||
return FilePath(kCurrentDirectoryString);
|
||||
#elif GTEST_OS_WINDOWS
|
||||
char cwd[GTEST_PATH_MAX_ + 1] = { '\0' };
|
||||
return FilePath(_getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd);
|
||||
#else
|
||||
char cwd[GTEST_PATH_MAX_ + 1] = { '\0' };
|
||||
return FilePath(getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd);
|
||||
#endif // GTEST_OS_WINDOWS_MOBILE
|
||||
}
|
||||
|
||||
// Returns a copy of the FilePath with the case-insensitive extension removed.
|
||||
// Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns
|
||||
// FilePath("dir/file"). If a case-insensitive extension is not
|
||||
// found, returns a copy of the original FilePath.
|
||||
FilePath FilePath::RemoveExtension(const char* extension) const {
|
||||
const std::string dot_extension = std::string(".") + extension;
|
||||
if (String::EndsWithCaseInsensitive(pathname_, dot_extension)) {
|
||||
return FilePath(pathname_.substr(
|
||||
0, pathname_.length() - dot_extension.length()));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Returns a pointer to the last occurence of a valid path separator in
|
||||
// the FilePath. On Windows, for example, both '/' and '\' are valid path
|
||||
// separators. Returns NULL if no path separator was found.
|
||||
const char* FilePath::FindLastPathSeparator() const {
|
||||
const char* const last_sep = strrchr(c_str(), kPathSeparator);
|
||||
#if GTEST_HAS_ALT_PATH_SEP_
|
||||
const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator);
|
||||
// Comparing two pointers of which only one is NULL is undefined.
|
||||
if (last_alt_sep != NULL &&
|
||||
(last_sep == NULL || last_alt_sep > last_sep)) {
|
||||
return last_alt_sep;
|
||||
}
|
||||
#endif
|
||||
return last_sep;
|
||||
}
|
||||
|
||||
// Returns a copy of the FilePath with the directory part removed.
|
||||
// Example: FilePath("path/to/file").RemoveDirectoryName() returns
|
||||
// FilePath("file"). If there is no directory part ("just_a_file"), it returns
|
||||
// the FilePath unmodified. If there is no file part ("just_a_dir/") it
|
||||
// returns an empty FilePath ("").
|
||||
// On Windows platform, '\' is the path separator, otherwise it is '/'.
|
||||
FilePath FilePath::RemoveDirectoryName() const {
|
||||
const char* const last_sep = FindLastPathSeparator();
|
||||
return last_sep ? FilePath(last_sep + 1) : *this;
|
||||
}
|
||||
|
||||
// RemoveFileName returns the directory path with the filename removed.
|
||||
// Example: FilePath("path/to/file").RemoveFileName() returns "path/to/".
|
||||
// If the FilePath is "a_file" or "/a_file", RemoveFileName returns
|
||||
// FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does
|
||||
// not have a file, like "just/a/dir/", it returns the FilePath unmodified.
|
||||
// On Windows platform, '\' is the path separator, otherwise it is '/'.
|
||||
FilePath FilePath::RemoveFileName() const {
|
||||
const char* const last_sep = FindLastPathSeparator();
|
||||
std::string dir;
|
||||
if (last_sep) {
|
||||
dir = std::string(c_str(), last_sep + 1 - c_str());
|
||||
} else {
|
||||
dir = kCurrentDirectoryString;
|
||||
}
|
||||
return FilePath(dir);
|
||||
}
|
||||
|
||||
// Helper functions for naming files in a directory for xml output.
|
||||
|
||||
// Given directory = "dir", base_name = "test", number = 0,
|
||||
// extension = "xml", returns "dir/test.xml". If number is greater
|
||||
// than zero (e.g., 12), returns "dir/test_12.xml".
|
||||
// On Windows platform, uses \ as the separator rather than /.
|
||||
FilePath FilePath::MakeFileName(const FilePath& directory,
|
||||
const FilePath& base_name,
|
||||
int number,
|
||||
const char* extension) {
|
||||
std::string file;
|
||||
if (number == 0) {
|
||||
file = base_name.string() + "." + extension;
|
||||
} else {
|
||||
file = base_name.string() + "_" + StreamableToString(number)
|
||||
+ "." + extension;
|
||||
}
|
||||
return ConcatPaths(directory, FilePath(file));
|
||||
}
|
||||
|
||||
// Given directory = "dir", relative_path = "test.xml", returns "dir/test.xml".
|
||||
// On Windows, uses \ as the separator rather than /.
|
||||
FilePath FilePath::ConcatPaths(const FilePath& directory,
|
||||
const FilePath& relative_path) {
|
||||
if (directory.IsEmpty())
|
||||
return relative_path;
|
||||
const FilePath dir(directory.RemoveTrailingPathSeparator());
|
||||
return FilePath(dir.string() + kPathSeparator + relative_path.string());
|
||||
}
|
||||
|
||||
// Returns true if pathname describes something findable in the file-system,
|
||||
// either a file, directory, or whatever.
|
||||
bool FilePath::FileOrDirectoryExists() const {
|
||||
#if GTEST_OS_WINDOWS_MOBILE
|
||||
LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str());
|
||||
const DWORD attributes = GetFileAttributes(unicode);
|
||||
delete [] unicode;
|
||||
return attributes != kInvalidFileAttributes;
|
||||
#else
|
||||
posix::StatStruct file_stat;
|
||||
return posix::Stat(pathname_.c_str(), &file_stat) == 0;
|
||||
#endif // GTEST_OS_WINDOWS_MOBILE
|
||||
}
|
||||
|
||||
// Returns true if pathname describes a directory in the file-system
|
||||
// that exists.
|
||||
bool FilePath::DirectoryExists() const {
|
||||
bool result = false;
|
||||
#if GTEST_OS_WINDOWS
|
||||
// Don't strip off trailing separator if path is a root directory on
|
||||
// Windows (like "C:\\").
|
||||
const FilePath& path(IsRootDirectory() ? *this :
|
||||
RemoveTrailingPathSeparator());
|
||||
#else
|
||||
const FilePath& path(*this);
|
||||
#endif
|
||||
|
||||
#if GTEST_OS_WINDOWS_MOBILE
|
||||
LPCWSTR unicode = String::AnsiToUtf16(path.c_str());
|
||||
const DWORD attributes = GetFileAttributes(unicode);
|
||||
delete [] unicode;
|
||||
if ((attributes != kInvalidFileAttributes) &&
|
||||
(attributes & FILE_ATTRIBUTE_DIRECTORY)) {
|
||||
result = true;
|
||||
}
|
||||
#else
|
||||
posix::StatStruct file_stat;
|
||||
result = posix::Stat(path.c_str(), &file_stat) == 0 &&
|
||||
posix::IsDir(file_stat);
|
||||
#endif // GTEST_OS_WINDOWS_MOBILE
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Returns true if pathname describes a root directory. (Windows has one
|
||||
// root directory per disk drive.)
|
||||
bool FilePath::IsRootDirectory() const {
|
||||
#if GTEST_OS_WINDOWS
|
||||
// TODO(wan@google.com): on Windows a network share like
|
||||
// \\server\share can be a root directory, although it cannot be the
|
||||
// current directory. Handle this properly.
|
||||
return pathname_.length() == 3 && IsAbsolutePath();
|
||||
#else
|
||||
return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Returns true if pathname describes an absolute path.
|
||||
bool FilePath::IsAbsolutePath() const {
|
||||
const char* const name = pathname_.c_str();
|
||||
#if GTEST_OS_WINDOWS
|
||||
return pathname_.length() >= 3 &&
|
||||
((name[0] >= 'a' && name[0] <= 'z') ||
|
||||
(name[0] >= 'A' && name[0] <= 'Z')) &&
|
||||
name[1] == ':' &&
|
||||
IsPathSeparator(name[2]);
|
||||
#else
|
||||
return IsPathSeparator(name[0]);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Returns a pathname for a file that does not currently exist. The pathname
|
||||
// will be directory/base_name.extension or
|
||||
// directory/base_name_<number>.extension if directory/base_name.extension
|
||||
// already exists. The number will be incremented until a pathname is found
|
||||
// that does not already exist.
|
||||
// Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'.
|
||||
// There could be a race condition if two or more processes are calling this
|
||||
// function at the same time -- they could both pick the same filename.
|
||||
FilePath FilePath::GenerateUniqueFileName(const FilePath& directory,
|
||||
const FilePath& base_name,
|
||||
const char* extension) {
|
||||
FilePath full_pathname;
|
||||
int number = 0;
|
||||
do {
|
||||
full_pathname.Set(MakeFileName(directory, base_name, number++, extension));
|
||||
} while (full_pathname.FileOrDirectoryExists());
|
||||
return full_pathname;
|
||||
}
|
||||
|
||||
// Returns true if FilePath ends with a path separator, which indicates that
|
||||
// it is intended to represent a directory. Returns false otherwise.
|
||||
// This does NOT check that a directory (or file) actually exists.
|
||||
bool FilePath::IsDirectory() const {
|
||||
return !pathname_.empty() &&
|
||||
IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]);
|
||||
}
|
||||
|
||||
// Create directories so that path exists. Returns true if successful or if
|
||||
// the directories already exist; returns false if unable to create directories
|
||||
// for any reason.
|
||||
bool FilePath::CreateDirectoriesRecursively() const {
|
||||
if (!this->IsDirectory()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pathname_.length() == 0 || this->DirectoryExists()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const FilePath parent(this->RemoveTrailingPathSeparator().RemoveFileName());
|
||||
return parent.CreateDirectoriesRecursively() && this->CreateFolder();
|
||||
}
|
||||
|
||||
// Create the directory so that path exists. Returns true if successful or
|
||||
// if the directory already exists; returns false if unable to create the
|
||||
// directory for any reason, including if the parent directory does not
|
||||
// exist. Not named "CreateDirectory" because that's a macro on Windows.
|
||||
bool FilePath::CreateFolder() const {
|
||||
#if GTEST_OS_WINDOWS_MOBILE
|
||||
FilePath removed_sep(this->RemoveTrailingPathSeparator());
|
||||
LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str());
|
||||
int result = CreateDirectory(unicode, NULL) ? 0 : -1;
|
||||
delete [] unicode;
|
||||
#elif GTEST_OS_WINDOWS
|
||||
int result = _mkdir(pathname_.c_str());
|
||||
#else
|
||||
int result = mkdir(pathname_.c_str(), 0777);
|
||||
#endif // GTEST_OS_WINDOWS_MOBILE
|
||||
|
||||
if (result == -1) {
|
||||
return this->DirectoryExists(); // An error is OK if the directory exists.
|
||||
}
|
||||
return true; // No error.
|
||||
}
|
||||
|
||||
// If input name has a trailing separator character, remove it and return the
|
||||
// name, otherwise return the name string unmodified.
|
||||
// On Windows platform, uses \ as the separator, other platforms use /.
|
||||
FilePath FilePath::RemoveTrailingPathSeparator() const {
|
||||
return IsDirectory()
|
||||
? FilePath(pathname_.substr(0, pathname_.length() - 1))
|
||||
: *this;
|
||||
}
|
||||
|
||||
// Removes any redundant separators that might be in the pathname.
|
||||
// For example, "bar///foo" becomes "bar/foo". Does not eliminate other
|
||||
// redundancies that might be in a pathname involving "." or "..".
|
||||
// TODO(wan@google.com): handle Windows network shares (e.g. \\server\share).
|
||||
void FilePath::Normalize() {
|
||||
if (pathname_.c_str() == NULL) {
|
||||
pathname_ = "";
|
||||
return;
|
||||
}
|
||||
const char* src = pathname_.c_str();
|
||||
char* const dest = new char[pathname_.length() + 1];
|
||||
char* dest_ptr = dest;
|
||||
memset(dest_ptr, 0, pathname_.length() + 1);
|
||||
|
||||
while (*src != '\0') {
|
||||
*dest_ptr = *src;
|
||||
if (!IsPathSeparator(*src)) {
|
||||
src++;
|
||||
} else {
|
||||
#if GTEST_HAS_ALT_PATH_SEP_
|
||||
if (*dest_ptr == kAlternatePathSeparator) {
|
||||
*dest_ptr = kPathSeparator;
|
||||
}
|
||||
#endif
|
||||
while (IsPathSeparator(*src))
|
||||
src++;
|
||||
}
|
||||
dest_ptr++;
|
||||
}
|
||||
*dest_ptr = '\0';
|
||||
pathname_ = dest;
|
||||
delete[] dest;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,373 +1,363 @@
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Google Test - The Google C++ Testing Framework
|
||||
//
|
||||
// This file implements a universal value printer that can print a
|
||||
// value of any type T:
|
||||
//
|
||||
// void ::testing::internal::UniversalPrinter<T>::Print(value, ostream_ptr);
|
||||
//
|
||||
// It uses the << operator when possible, and prints the bytes in the
|
||||
// object otherwise. A user can override its behavior for a class
|
||||
// type Foo by defining either operator<<(::std::ostream&, const Foo&)
|
||||
// or void PrintTo(const Foo&, ::std::ostream*) in the namespace that
|
||||
// defines Foo.
|
||||
|
||||
#include "gtest/gtest-printers.h"
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <cwchar>
|
||||
#include <ostream> // NOLINT
|
||||
#include <string>
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
|
||||
namespace testing {
|
||||
|
||||
namespace {
|
||||
|
||||
using ::std::ostream;
|
||||
|
||||
// Prints a segment of bytes in the given object.
|
||||
GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_
|
||||
GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
|
||||
GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_
|
||||
void PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start,
|
||||
size_t count, ostream* os) {
|
||||
char text[5] = "";
|
||||
for (size_t i = 0; i != count; i++) {
|
||||
const size_t j = start + i;
|
||||
if (i != 0) {
|
||||
// Organizes the bytes into groups of 2 for easy parsing by
|
||||
// human.
|
||||
if ((j % 2) == 0)
|
||||
*os << ' ';
|
||||
else
|
||||
*os << '-';
|
||||
}
|
||||
GTEST_SNPRINTF_(text, sizeof(text), "%02X", obj_bytes[j]);
|
||||
*os << text;
|
||||
}
|
||||
}
|
||||
|
||||
// Prints the bytes in the given value to the given ostream.
|
||||
void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count,
|
||||
ostream* os) {
|
||||
// Tells the user how big the object is.
|
||||
*os << count << "-byte object <";
|
||||
|
||||
const size_t kThreshold = 132;
|
||||
const size_t kChunkSize = 64;
|
||||
// If the object size is bigger than kThreshold, we'll have to omit
|
||||
// some details by printing only the first and the last kChunkSize
|
||||
// bytes.
|
||||
// TODO(wan): let the user control the threshold using a flag.
|
||||
if (count < kThreshold) {
|
||||
PrintByteSegmentInObjectTo(obj_bytes, 0, count, os);
|
||||
} else {
|
||||
PrintByteSegmentInObjectTo(obj_bytes, 0, kChunkSize, os);
|
||||
*os << " ... ";
|
||||
// Rounds up to 2-byte boundary.
|
||||
const size_t resume_pos = (count - kChunkSize + 1)/2*2;
|
||||
PrintByteSegmentInObjectTo(obj_bytes, resume_pos, count - resume_pos, os);
|
||||
}
|
||||
*os << ">";
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace internal2 {
|
||||
|
||||
// Delegates to PrintBytesInObjectToImpl() to print the bytes in the
|
||||
// given object. The delegation simplifies the implementation, which
|
||||
// uses the << operator and thus is easier done outside of the
|
||||
// ::testing::internal namespace, which contains a << operator that
|
||||
// sometimes conflicts with the one in STL.
|
||||
void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count,
|
||||
ostream* os) {
|
||||
PrintBytesInObjectToImpl(obj_bytes, count, os);
|
||||
}
|
||||
|
||||
} // namespace internal2
|
||||
|
||||
namespace internal {
|
||||
|
||||
// Depending on the value of a char (or wchar_t), we print it in one
|
||||
// of three formats:
|
||||
// - as is if it's a printable ASCII (e.g. 'a', '2', ' '),
|
||||
// - as a hexidecimal escape sequence (e.g. '\x7F'), or
|
||||
// - as a special escape sequence (e.g. '\r', '\n').
|
||||
enum CharFormat {
|
||||
kAsIs,
|
||||
kHexEscape,
|
||||
kSpecialEscape
|
||||
};
|
||||
|
||||
// Returns true if c is a printable ASCII character. We test the
|
||||
// value of c directly instead of calling isprint(), which is buggy on
|
||||
// Windows Mobile.
|
||||
inline bool IsPrintableAscii(wchar_t c) {
|
||||
return 0x20 <= c && c <= 0x7E;
|
||||
}
|
||||
|
||||
// Prints a wide or narrow char c as a character literal without the
|
||||
// quotes, escaping it when necessary; returns how c was formatted.
|
||||
// The template argument UnsignedChar is the unsigned version of Char,
|
||||
// which is the type of c.
|
||||
template <typename UnsignedChar, typename Char>
|
||||
static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) {
|
||||
switch (static_cast<wchar_t>(c)) {
|
||||
case L'\0':
|
||||
*os << "\\0";
|
||||
break;
|
||||
case L'\'':
|
||||
*os << "\\'";
|
||||
break;
|
||||
case L'\\':
|
||||
*os << "\\\\";
|
||||
break;
|
||||
case L'\a':
|
||||
*os << "\\a";
|
||||
break;
|
||||
case L'\b':
|
||||
*os << "\\b";
|
||||
break;
|
||||
case L'\f':
|
||||
*os << "\\f";
|
||||
break;
|
||||
case L'\n':
|
||||
*os << "\\n";
|
||||
break;
|
||||
case L'\r':
|
||||
*os << "\\r";
|
||||
break;
|
||||
case L'\t':
|
||||
*os << "\\t";
|
||||
break;
|
||||
case L'\v':
|
||||
*os << "\\v";
|
||||
break;
|
||||
default:
|
||||
if (IsPrintableAscii(c)) {
|
||||
*os << static_cast<char>(c);
|
||||
return kAsIs;
|
||||
} else {
|
||||
*os << "\\x" + String::FormatHexInt(static_cast<UnsignedChar>(c));
|
||||
return kHexEscape;
|
||||
}
|
||||
}
|
||||
return kSpecialEscape;
|
||||
}
|
||||
|
||||
// Prints a wchar_t c as if it's part of a string literal, escaping it when
|
||||
// necessary; returns how c was formatted.
|
||||
static CharFormat PrintAsStringLiteralTo(wchar_t c, ostream* os) {
|
||||
switch (c) {
|
||||
case L'\'':
|
||||
*os << "'";
|
||||
return kAsIs;
|
||||
case L'"':
|
||||
*os << "\\\"";
|
||||
return kSpecialEscape;
|
||||
default:
|
||||
return PrintAsCharLiteralTo<wchar_t>(c, os);
|
||||
}
|
||||
}
|
||||
|
||||
// Prints a char c as if it's part of a string literal, escaping it when
|
||||
// necessary; returns how c was formatted.
|
||||
static CharFormat PrintAsStringLiteralTo(char c, ostream* os) {
|
||||
return PrintAsStringLiteralTo(
|
||||
static_cast<wchar_t>(static_cast<unsigned char>(c)), os);
|
||||
}
|
||||
|
||||
// Prints a wide or narrow character c and its code. '\0' is printed
|
||||
// as "'\\0'", other unprintable characters are also properly escaped
|
||||
// using the standard C++ escape sequence. The template argument
|
||||
// UnsignedChar is the unsigned version of Char, which is the type of c.
|
||||
template <typename UnsignedChar, typename Char>
|
||||
void PrintCharAndCodeTo(Char c, ostream* os) {
|
||||
// First, print c as a literal in the most readable form we can find.
|
||||
*os << ((sizeof(c) > 1) ? "L'" : "'");
|
||||
const CharFormat format = PrintAsCharLiteralTo<UnsignedChar>(c, os);
|
||||
*os << "'";
|
||||
|
||||
// To aid user debugging, we also print c's code in decimal, unless
|
||||
// it's 0 (in which case c was printed as '\\0', making the code
|
||||
// obvious).
|
||||
if (c == 0)
|
||||
return;
|
||||
*os << " (" << static_cast<int>(c);
|
||||
|
||||
// For more convenience, we print c's code again in hexidecimal,
|
||||
// unless c was already printed in the form '\x##' or the code is in
|
||||
// [1, 9].
|
||||
if (format == kHexEscape || (1 <= c && c <= 9)) {
|
||||
// Do nothing.
|
||||
} else {
|
||||
*os << ", 0x" << String::FormatHexInt(static_cast<UnsignedChar>(c));
|
||||
}
|
||||
*os << ")";
|
||||
}
|
||||
|
||||
void PrintTo(unsigned char c, ::std::ostream* os) {
|
||||
PrintCharAndCodeTo<unsigned char>(c, os);
|
||||
}
|
||||
void PrintTo(signed char c, ::std::ostream* os) {
|
||||
PrintCharAndCodeTo<unsigned char>(c, os);
|
||||
}
|
||||
|
||||
// Prints a wchar_t as a symbol if it is printable or as its internal
|
||||
// code otherwise and also as its code. L'\0' is printed as "L'\\0'".
|
||||
void PrintTo(wchar_t wc, ostream* os) {
|
||||
PrintCharAndCodeTo<wchar_t>(wc, os);
|
||||
}
|
||||
|
||||
// Prints the given array of characters to the ostream. CharType must be either
|
||||
// char or wchar_t.
|
||||
// The array starts at begin, the length is len, it may include '\0' characters
|
||||
// and may not be NUL-terminated.
|
||||
template <typename CharType>
|
||||
GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_
|
||||
GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
|
||||
GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_
|
||||
static void PrintCharsAsStringTo(
|
||||
const CharType* begin, size_t len, ostream* os) {
|
||||
const char* const kQuoteBegin = sizeof(CharType) == 1 ? "\"" : "L\"";
|
||||
*os << kQuoteBegin;
|
||||
bool is_previous_hex = false;
|
||||
for (size_t index = 0; index < len; ++index) {
|
||||
const CharType cur = begin[index];
|
||||
if (is_previous_hex && IsXDigit(cur)) {
|
||||
// Previous character is of '\x..' form and this character can be
|
||||
// interpreted as another hexadecimal digit in its number. Break string to
|
||||
// disambiguate.
|
||||
*os << "\" " << kQuoteBegin;
|
||||
}
|
||||
is_previous_hex = PrintAsStringLiteralTo(cur, os) == kHexEscape;
|
||||
}
|
||||
*os << "\"";
|
||||
}
|
||||
|
||||
// Prints a (const) char/wchar_t array of 'len' elements, starting at address
|
||||
// 'begin'. CharType must be either char or wchar_t.
|
||||
template <typename CharType>
|
||||
GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_
|
||||
GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
|
||||
GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_
|
||||
static void UniversalPrintCharArray(
|
||||
const CharType* begin, size_t len, ostream* os) {
|
||||
// The code
|
||||
// const char kFoo[] = "foo";
|
||||
// generates an array of 4, not 3, elements, with the last one being '\0'.
|
||||
//
|
||||
// Therefore when printing a char array, we don't print the last element if
|
||||
// it's '\0', such that the output matches the string literal as it's
|
||||
// written in the source code.
|
||||
if (len > 0 && begin[len - 1] == '\0') {
|
||||
PrintCharsAsStringTo(begin, len - 1, os);
|
||||
return;
|
||||
}
|
||||
|
||||
// If, however, the last element in the array is not '\0', e.g.
|
||||
// const char kFoo[] = { 'f', 'o', 'o' };
|
||||
// we must print the entire array. We also print a message to indicate
|
||||
// that the array is not NUL-terminated.
|
||||
PrintCharsAsStringTo(begin, len, os);
|
||||
*os << " (no terminating NUL)";
|
||||
}
|
||||
|
||||
// Prints a (const) char array of 'len' elements, starting at address 'begin'.
|
||||
void UniversalPrintArray(const char* begin, size_t len, ostream* os) {
|
||||
UniversalPrintCharArray(begin, len, os);
|
||||
}
|
||||
|
||||
// Prints a (const) wchar_t array of 'len' elements, starting at address
|
||||
// 'begin'.
|
||||
void UniversalPrintArray(const wchar_t* begin, size_t len, ostream* os) {
|
||||
UniversalPrintCharArray(begin, len, os);
|
||||
}
|
||||
|
||||
// Prints the given C string to the ostream.
|
||||
void PrintTo(const char* s, ostream* os) {
|
||||
if (s == NULL) {
|
||||
*os << "NULL";
|
||||
} else {
|
||||
*os << ImplicitCast_<const void*>(s) << " pointing to ";
|
||||
PrintCharsAsStringTo(s, strlen(s), os);
|
||||
}
|
||||
}
|
||||
|
||||
// MSVC compiler can be configured to define whar_t as a typedef
|
||||
// of unsigned short. Defining an overload for const wchar_t* in that case
|
||||
// would cause pointers to unsigned shorts be printed as wide strings,
|
||||
// possibly accessing more memory than intended and causing invalid
|
||||
// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when
|
||||
// wchar_t is implemented as a native type.
|
||||
#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
|
||||
// Prints the given wide C string to the ostream.
|
||||
void PrintTo(const wchar_t* s, ostream* os) {
|
||||
if (s == NULL) {
|
||||
*os << "NULL";
|
||||
} else {
|
||||
*os << ImplicitCast_<const void*>(s) << " pointing to ";
|
||||
PrintCharsAsStringTo(s, std::wcslen(s), os);
|
||||
}
|
||||
}
|
||||
#endif // wchar_t is native
|
||||
|
||||
// Prints a ::string object.
|
||||
#if GTEST_HAS_GLOBAL_STRING
|
||||
void PrintStringTo(const ::string& s, ostream* os) {
|
||||
PrintCharsAsStringTo(s.data(), s.size(), os);
|
||||
}
|
||||
#endif // GTEST_HAS_GLOBAL_STRING
|
||||
|
||||
void PrintStringTo(const ::std::string& s, ostream* os) {
|
||||
PrintCharsAsStringTo(s.data(), s.size(), os);
|
||||
}
|
||||
|
||||
// Prints a ::wstring object.
|
||||
#if GTEST_HAS_GLOBAL_WSTRING
|
||||
void PrintWideStringTo(const ::wstring& s, ostream* os) {
|
||||
PrintCharsAsStringTo(s.data(), s.size(), os);
|
||||
}
|
||||
#endif // GTEST_HAS_GLOBAL_WSTRING
|
||||
|
||||
#if GTEST_HAS_STD_WSTRING
|
||||
void PrintWideStringTo(const ::std::wstring& s, ostream* os) {
|
||||
PrintCharsAsStringTo(s.data(), s.size(), os);
|
||||
}
|
||||
#endif // GTEST_HAS_STD_WSTRING
|
||||
|
||||
} // namespace internal
|
||||
|
||||
} // namespace testing
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Google Test - The Google C++ Testing Framework
|
||||
//
|
||||
// This file implements a universal value printer that can print a
|
||||
// value of any type T:
|
||||
//
|
||||
// void ::testing::internal::UniversalPrinter<T>::Print(value, ostream_ptr);
|
||||
//
|
||||
// It uses the << operator when possible, and prints the bytes in the
|
||||
// object otherwise. A user can override its behavior for a class
|
||||
// type Foo by defining either operator<<(::std::ostream&, const Foo&)
|
||||
// or void PrintTo(const Foo&, ::std::ostream*) in the namespace that
|
||||
// defines Foo.
|
||||
|
||||
#include "gtest/gtest-printers.h"
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <ostream> // NOLINT
|
||||
#include <string>
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
|
||||
namespace testing {
|
||||
|
||||
namespace {
|
||||
|
||||
using ::std::ostream;
|
||||
|
||||
// Prints a segment of bytes in the given object.
|
||||
void PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start,
|
||||
size_t count, ostream* os) {
|
||||
char text[5] = "";
|
||||
for (size_t i = 0; i != count; i++) {
|
||||
const size_t j = start + i;
|
||||
if (i != 0) {
|
||||
// Organizes the bytes into groups of 2 for easy parsing by
|
||||
// human.
|
||||
if ((j % 2) == 0)
|
||||
*os << ' ';
|
||||
else
|
||||
*os << '-';
|
||||
}
|
||||
GTEST_SNPRINTF_(text, sizeof(text), "%02X", obj_bytes[j]);
|
||||
*os << text;
|
||||
}
|
||||
}
|
||||
|
||||
// Prints the bytes in the given value to the given ostream.
|
||||
void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count,
|
||||
ostream* os) {
|
||||
// Tells the user how big the object is.
|
||||
*os << count << "-byte object <";
|
||||
|
||||
const size_t kThreshold = 132;
|
||||
const size_t kChunkSize = 64;
|
||||
// If the object size is bigger than kThreshold, we'll have to omit
|
||||
// some details by printing only the first and the last kChunkSize
|
||||
// bytes.
|
||||
// TODO(wan): let the user control the threshold using a flag.
|
||||
if (count < kThreshold) {
|
||||
PrintByteSegmentInObjectTo(obj_bytes, 0, count, os);
|
||||
} else {
|
||||
PrintByteSegmentInObjectTo(obj_bytes, 0, kChunkSize, os);
|
||||
*os << " ... ";
|
||||
// Rounds up to 2-byte boundary.
|
||||
const size_t resume_pos = (count - kChunkSize + 1)/2*2;
|
||||
PrintByteSegmentInObjectTo(obj_bytes, resume_pos, count - resume_pos, os);
|
||||
}
|
||||
*os << ">";
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace internal2 {
|
||||
|
||||
// Delegates to PrintBytesInObjectToImpl() to print the bytes in the
|
||||
// given object. The delegation simplifies the implementation, which
|
||||
// uses the << operator and thus is easier done outside of the
|
||||
// ::testing::internal namespace, which contains a << operator that
|
||||
// sometimes conflicts with the one in STL.
|
||||
void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count,
|
||||
ostream* os) {
|
||||
PrintBytesInObjectToImpl(obj_bytes, count, os);
|
||||
}
|
||||
|
||||
} // namespace internal2
|
||||
|
||||
namespace internal {
|
||||
|
||||
// Depending on the value of a char (or wchar_t), we print it in one
|
||||
// of three formats:
|
||||
// - as is if it's a printable ASCII (e.g. 'a', '2', ' '),
|
||||
// - as a hexidecimal escape sequence (e.g. '\x7F'), or
|
||||
// - as a special escape sequence (e.g. '\r', '\n').
|
||||
enum CharFormat {
|
||||
kAsIs,
|
||||
kHexEscape,
|
||||
kSpecialEscape
|
||||
};
|
||||
|
||||
// Returns true if c is a printable ASCII character. We test the
|
||||
// value of c directly instead of calling isprint(), which is buggy on
|
||||
// Windows Mobile.
|
||||
inline bool IsPrintableAscii(wchar_t c) {
|
||||
return 0x20 <= c && c <= 0x7E;
|
||||
}
|
||||
|
||||
// Prints a wide or narrow char c as a character literal without the
|
||||
// quotes, escaping it when necessary; returns how c was formatted.
|
||||
// The template argument UnsignedChar is the unsigned version of Char,
|
||||
// which is the type of c.
|
||||
template <typename UnsignedChar, typename Char>
|
||||
static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) {
|
||||
switch (static_cast<wchar_t>(c)) {
|
||||
case L'\0':
|
||||
*os << "\\0";
|
||||
break;
|
||||
case L'\'':
|
||||
*os << "\\'";
|
||||
break;
|
||||
case L'\\':
|
||||
*os << "\\\\";
|
||||
break;
|
||||
case L'\a':
|
||||
*os << "\\a";
|
||||
break;
|
||||
case L'\b':
|
||||
*os << "\\b";
|
||||
break;
|
||||
case L'\f':
|
||||
*os << "\\f";
|
||||
break;
|
||||
case L'\n':
|
||||
*os << "\\n";
|
||||
break;
|
||||
case L'\r':
|
||||
*os << "\\r";
|
||||
break;
|
||||
case L'\t':
|
||||
*os << "\\t";
|
||||
break;
|
||||
case L'\v':
|
||||
*os << "\\v";
|
||||
break;
|
||||
default:
|
||||
if (IsPrintableAscii(c)) {
|
||||
*os << static_cast<char>(c);
|
||||
return kAsIs;
|
||||
} else {
|
||||
*os << "\\x" + String::FormatHexInt(static_cast<UnsignedChar>(c));
|
||||
return kHexEscape;
|
||||
}
|
||||
}
|
||||
return kSpecialEscape;
|
||||
}
|
||||
|
||||
// Prints a wchar_t c as if it's part of a string literal, escaping it when
|
||||
// necessary; returns how c was formatted.
|
||||
static CharFormat PrintAsStringLiteralTo(wchar_t c, ostream* os) {
|
||||
switch (c) {
|
||||
case L'\'':
|
||||
*os << "'";
|
||||
return kAsIs;
|
||||
case L'"':
|
||||
*os << "\\\"";
|
||||
return kSpecialEscape;
|
||||
default:
|
||||
return PrintAsCharLiteralTo<wchar_t>(c, os);
|
||||
}
|
||||
}
|
||||
|
||||
// Prints a char c as if it's part of a string literal, escaping it when
|
||||
// necessary; returns how c was formatted.
|
||||
static CharFormat PrintAsStringLiteralTo(char c, ostream* os) {
|
||||
return PrintAsStringLiteralTo(
|
||||
static_cast<wchar_t>(static_cast<unsigned char>(c)), os);
|
||||
}
|
||||
|
||||
// Prints a wide or narrow character c and its code. '\0' is printed
|
||||
// as "'\\0'", other unprintable characters are also properly escaped
|
||||
// using the standard C++ escape sequence. The template argument
|
||||
// UnsignedChar is the unsigned version of Char, which is the type of c.
|
||||
template <typename UnsignedChar, typename Char>
|
||||
void PrintCharAndCodeTo(Char c, ostream* os) {
|
||||
// First, print c as a literal in the most readable form we can find.
|
||||
*os << ((sizeof(c) > 1) ? "L'" : "'");
|
||||
const CharFormat format = PrintAsCharLiteralTo<UnsignedChar>(c, os);
|
||||
*os << "'";
|
||||
|
||||
// To aid user debugging, we also print c's code in decimal, unless
|
||||
// it's 0 (in which case c was printed as '\\0', making the code
|
||||
// obvious).
|
||||
if (c == 0)
|
||||
return;
|
||||
*os << " (" << static_cast<int>(c);
|
||||
|
||||
// For more convenience, we print c's code again in hexidecimal,
|
||||
// unless c was already printed in the form '\x##' or the code is in
|
||||
// [1, 9].
|
||||
if (format == kHexEscape || (1 <= c && c <= 9)) {
|
||||
// Do nothing.
|
||||
} else {
|
||||
*os << ", 0x" << String::FormatHexInt(static_cast<UnsignedChar>(c));
|
||||
}
|
||||
*os << ")";
|
||||
}
|
||||
|
||||
void PrintTo(unsigned char c, ::std::ostream* os) {
|
||||
PrintCharAndCodeTo<unsigned char>(c, os);
|
||||
}
|
||||
void PrintTo(signed char c, ::std::ostream* os) {
|
||||
PrintCharAndCodeTo<unsigned char>(c, os);
|
||||
}
|
||||
|
||||
// Prints a wchar_t as a symbol if it is printable or as its internal
|
||||
// code otherwise and also as its code. L'\0' is printed as "L'\\0'".
|
||||
void PrintTo(wchar_t wc, ostream* os) {
|
||||
PrintCharAndCodeTo<wchar_t>(wc, os);
|
||||
}
|
||||
|
||||
// Prints the given array of characters to the ostream. CharType must be either
|
||||
// char or wchar_t.
|
||||
// The array starts at begin, the length is len, it may include '\0' characters
|
||||
// and may not be NUL-terminated.
|
||||
template <typename CharType>
|
||||
static void PrintCharsAsStringTo(
|
||||
const CharType* begin, size_t len, ostream* os) {
|
||||
const char* const kQuoteBegin = sizeof(CharType) == 1 ? "\"" : "L\"";
|
||||
*os << kQuoteBegin;
|
||||
bool is_previous_hex = false;
|
||||
for (size_t index = 0; index < len; ++index) {
|
||||
const CharType cur = begin[index];
|
||||
if (is_previous_hex && IsXDigit(cur)) {
|
||||
// Previous character is of '\x..' form and this character can be
|
||||
// interpreted as another hexadecimal digit in its number. Break string to
|
||||
// disambiguate.
|
||||
*os << "\" " << kQuoteBegin;
|
||||
}
|
||||
is_previous_hex = PrintAsStringLiteralTo(cur, os) == kHexEscape;
|
||||
}
|
||||
*os << "\"";
|
||||
}
|
||||
|
||||
// Prints a (const) char/wchar_t array of 'len' elements, starting at address
|
||||
// 'begin'. CharType must be either char or wchar_t.
|
||||
template <typename CharType>
|
||||
static void UniversalPrintCharArray(
|
||||
const CharType* begin, size_t len, ostream* os) {
|
||||
// The code
|
||||
// const char kFoo[] = "foo";
|
||||
// generates an array of 4, not 3, elements, with the last one being '\0'.
|
||||
//
|
||||
// Therefore when printing a char array, we don't print the last element if
|
||||
// it's '\0', such that the output matches the string literal as it's
|
||||
// written in the source code.
|
||||
if (len > 0 && begin[len - 1] == '\0') {
|
||||
PrintCharsAsStringTo(begin, len - 1, os);
|
||||
return;
|
||||
}
|
||||
|
||||
// If, however, the last element in the array is not '\0', e.g.
|
||||
// const char kFoo[] = { 'f', 'o', 'o' };
|
||||
// we must print the entire array. We also print a message to indicate
|
||||
// that the array is not NUL-terminated.
|
||||
PrintCharsAsStringTo(begin, len, os);
|
||||
*os << " (no terminating NUL)";
|
||||
}
|
||||
|
||||
// Prints a (const) char array of 'len' elements, starting at address 'begin'.
|
||||
void UniversalPrintArray(const char* begin, size_t len, ostream* os) {
|
||||
UniversalPrintCharArray(begin, len, os);
|
||||
}
|
||||
|
||||
// Prints a (const) wchar_t array of 'len' elements, starting at address
|
||||
// 'begin'.
|
||||
void UniversalPrintArray(const wchar_t* begin, size_t len, ostream* os) {
|
||||
UniversalPrintCharArray(begin, len, os);
|
||||
}
|
||||
|
||||
// Prints the given C string to the ostream.
|
||||
void PrintTo(const char* s, ostream* os) {
|
||||
if (s == NULL) {
|
||||
*os << "NULL";
|
||||
} else {
|
||||
*os << ImplicitCast_<const void*>(s) << " pointing to ";
|
||||
PrintCharsAsStringTo(s, strlen(s), os);
|
||||
}
|
||||
}
|
||||
|
||||
// MSVC compiler can be configured to define whar_t as a typedef
|
||||
// of unsigned short. Defining an overload for const wchar_t* in that case
|
||||
// would cause pointers to unsigned shorts be printed as wide strings,
|
||||
// possibly accessing more memory than intended and causing invalid
|
||||
// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when
|
||||
// wchar_t is implemented as a native type.
|
||||
#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
|
||||
// Prints the given wide C string to the ostream.
|
||||
void PrintTo(const wchar_t* s, ostream* os) {
|
||||
if (s == NULL) {
|
||||
*os << "NULL";
|
||||
} else {
|
||||
*os << ImplicitCast_<const void*>(s) << " pointing to ";
|
||||
PrintCharsAsStringTo(s, wcslen(s), os);
|
||||
}
|
||||
}
|
||||
#endif // wchar_t is native
|
||||
|
||||
// Prints a ::string object.
|
||||
#if GTEST_HAS_GLOBAL_STRING
|
||||
void PrintStringTo(const ::string& s, ostream* os) {
|
||||
PrintCharsAsStringTo(s.data(), s.size(), os);
|
||||
}
|
||||
#endif // GTEST_HAS_GLOBAL_STRING
|
||||
|
||||
void PrintStringTo(const ::std::string& s, ostream* os) {
|
||||
PrintCharsAsStringTo(s.data(), s.size(), os);
|
||||
}
|
||||
|
||||
// Prints a ::wstring object.
|
||||
#if GTEST_HAS_GLOBAL_WSTRING
|
||||
void PrintWideStringTo(const ::wstring& s, ostream* os) {
|
||||
PrintCharsAsStringTo(s.data(), s.size(), os);
|
||||
}
|
||||
#endif // GTEST_HAS_GLOBAL_WSTRING
|
||||
|
||||
#if GTEST_HAS_STD_WSTRING
|
||||
void PrintWideStringTo(const ::std::wstring& s, ostream* os) {
|
||||
PrintCharsAsStringTo(s.data(), s.size(), os);
|
||||
}
|
||||
#endif // GTEST_HAS_STD_WSTRING
|
||||
|
||||
} // namespace internal
|
||||
|
||||
} // namespace testing
|
||||
@@ -1,110 +1,110 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: mheule@google.com (Markus Heule)
|
||||
//
|
||||
// The Google C++ Testing Framework (Google Test)
|
||||
|
||||
#include "gtest/gtest-test-part.h"
|
||||
|
||||
// Indicates that this translation unit is part of Google Test's
|
||||
// implementation. It must come before gtest-internal-inl.h is
|
||||
// included, or there will be a compiler error. This trick is to
|
||||
// prevent a user from accidentally including gtest-internal-inl.h in
|
||||
// his code.
|
||||
#define GTEST_IMPLEMENTATION_ 1
|
||||
#include "src/gtest-internal-inl.h"
|
||||
#undef GTEST_IMPLEMENTATION_
|
||||
|
||||
namespace testing {
|
||||
|
||||
using internal::GetUnitTestImpl;
|
||||
|
||||
// Gets the summary of the failure message by omitting the stack trace
|
||||
// in it.
|
||||
std::string TestPartResult::ExtractSummary(const char* message) {
|
||||
const char* const stack_trace = strstr(message, internal::kStackTraceMarker);
|
||||
return stack_trace == NULL ? message :
|
||||
std::string(message, stack_trace);
|
||||
}
|
||||
|
||||
// Prints a TestPartResult object.
|
||||
std::ostream& operator<<(std::ostream& os, const TestPartResult& result) {
|
||||
return os
|
||||
<< result.file_name() << ":" << result.line_number() << ": "
|
||||
<< (result.type() == TestPartResult::kSuccess ? "Success" :
|
||||
result.type() == TestPartResult::kFatalFailure ? "Fatal failure" :
|
||||
"Non-fatal failure") << ":\n"
|
||||
<< result.message() << std::endl;
|
||||
}
|
||||
|
||||
// Appends a TestPartResult to the array.
|
||||
void TestPartResultArray::Append(const TestPartResult& result) {
|
||||
array_.push_back(result);
|
||||
}
|
||||
|
||||
// Returns the TestPartResult at the given index (0-based).
|
||||
const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const {
|
||||
if (index < 0 || index >= size()) {
|
||||
printf("\nInvalid index (%d) into TestPartResultArray.\n", index);
|
||||
internal::posix::Abort();
|
||||
}
|
||||
|
||||
return array_[index];
|
||||
}
|
||||
|
||||
// Returns the number of TestPartResult objects in the array.
|
||||
int TestPartResultArray::size() const {
|
||||
return static_cast<int>(array_.size());
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
|
||||
HasNewFatalFailureHelper::HasNewFatalFailureHelper()
|
||||
: has_new_fatal_failure_(false),
|
||||
original_reporter_(GetUnitTestImpl()->
|
||||
GetTestPartResultReporterForCurrentThread()) {
|
||||
GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this);
|
||||
}
|
||||
|
||||
HasNewFatalFailureHelper::~HasNewFatalFailureHelper() {
|
||||
GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(
|
||||
original_reporter_);
|
||||
}
|
||||
|
||||
void HasNewFatalFailureHelper::ReportTestPartResult(
|
||||
const TestPartResult& result) {
|
||||
if (result.fatally_failed())
|
||||
has_new_fatal_failure_ = true;
|
||||
original_reporter_->ReportTestPartResult(result);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
} // namespace testing
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: mheule@google.com (Markus Heule)
|
||||
//
|
||||
// The Google C++ Testing Framework (Google Test)
|
||||
|
||||
#include "gtest/gtest-test-part.h"
|
||||
|
||||
// Indicates that this translation unit is part of Google Test's
|
||||
// implementation. It must come before gtest-internal-inl.h is
|
||||
// included, or there will be a compiler error. This trick is to
|
||||
// prevent a user from accidentally including gtest-internal-inl.h in
|
||||
// his code.
|
||||
#define GTEST_IMPLEMENTATION_ 1
|
||||
#include "src/gtest-internal-inl.h"
|
||||
#undef GTEST_IMPLEMENTATION_
|
||||
|
||||
namespace testing {
|
||||
|
||||
using internal::GetUnitTestImpl;
|
||||
|
||||
// Gets the summary of the failure message by omitting the stack trace
|
||||
// in it.
|
||||
std::string TestPartResult::ExtractSummary(const char* message) {
|
||||
const char* const stack_trace = strstr(message, internal::kStackTraceMarker);
|
||||
return stack_trace == NULL ? message :
|
||||
std::string(message, stack_trace);
|
||||
}
|
||||
|
||||
// Prints a TestPartResult object.
|
||||
std::ostream& operator<<(std::ostream& os, const TestPartResult& result) {
|
||||
return os
|
||||
<< result.file_name() << ":" << result.line_number() << ": "
|
||||
<< (result.type() == TestPartResult::kSuccess ? "Success" :
|
||||
result.type() == TestPartResult::kFatalFailure ? "Fatal failure" :
|
||||
"Non-fatal failure") << ":\n"
|
||||
<< result.message() << std::endl;
|
||||
}
|
||||
|
||||
// Appends a TestPartResult to the array.
|
||||
void TestPartResultArray::Append(const TestPartResult& result) {
|
||||
array_.push_back(result);
|
||||
}
|
||||
|
||||
// Returns the TestPartResult at the given index (0-based).
|
||||
const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const {
|
||||
if (index < 0 || index >= size()) {
|
||||
printf("\nInvalid index (%d) into TestPartResultArray.\n", index);
|
||||
internal::posix::Abort();
|
||||
}
|
||||
|
||||
return array_[index];
|
||||
}
|
||||
|
||||
// Returns the number of TestPartResult objects in the array.
|
||||
int TestPartResultArray::size() const {
|
||||
return static_cast<int>(array_.size());
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
|
||||
HasNewFatalFailureHelper::HasNewFatalFailureHelper()
|
||||
: has_new_fatal_failure_(false),
|
||||
original_reporter_(GetUnitTestImpl()->
|
||||
GetTestPartResultReporterForCurrentThread()) {
|
||||
GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this);
|
||||
}
|
||||
|
||||
HasNewFatalFailureHelper::~HasNewFatalFailureHelper() {
|
||||
GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(
|
||||
original_reporter_);
|
||||
}
|
||||
|
||||
void HasNewFatalFailureHelper::ReportTestPartResult(
|
||||
const TestPartResult& result) {
|
||||
if (result.fatally_failed())
|
||||
has_new_fatal_failure_ = true;
|
||||
original_reporter_->ReportTestPartResult(result);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
} // namespace testing
|
||||
@@ -1,110 +1,110 @@
|
||||
// Copyright 2008 Google Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
#include "gtest/gtest-typed-test.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
#if GTEST_HAS_TYPED_TEST_P
|
||||
|
||||
// Skips to the first non-space char in str. Returns an empty string if str
|
||||
// contains only whitespace characters.
|
||||
static const char* SkipSpaces(const char* str) {
|
||||
while (IsSpace(*str))
|
||||
str++;
|
||||
return str;
|
||||
}
|
||||
|
||||
// Verifies that registered_tests match the test names in
|
||||
// defined_test_names_; returns registered_tests if successful, or
|
||||
// aborts the program otherwise.
|
||||
const char* TypedTestCasePState::VerifyRegisteredTestNames(
|
||||
const char* file, int line, const char* registered_tests) {
|
||||
typedef ::std::set<const char*>::const_iterator DefinedTestIter;
|
||||
registered_ = true;
|
||||
|
||||
// Skip initial whitespace in registered_tests since some
|
||||
// preprocessors prefix stringizied literals with whitespace.
|
||||
registered_tests = SkipSpaces(registered_tests);
|
||||
|
||||
Message errors;
|
||||
::std::set<std::string> tests;
|
||||
for (const char* names = registered_tests; names != NULL;
|
||||
names = SkipComma(names)) {
|
||||
const std::string name = GetPrefixUntilComma(names);
|
||||
if (tests.count(name) != 0) {
|
||||
errors << "Test " << name << " is listed more than once.\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
for (DefinedTestIter it = defined_test_names_.begin();
|
||||
it != defined_test_names_.end();
|
||||
++it) {
|
||||
if (name == *it) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
tests.insert(name);
|
||||
} else {
|
||||
errors << "No test named " << name
|
||||
<< " can be found in this test case.\n";
|
||||
}
|
||||
}
|
||||
|
||||
for (DefinedTestIter it = defined_test_names_.begin();
|
||||
it != defined_test_names_.end();
|
||||
++it) {
|
||||
if (tests.count(*it) == 0) {
|
||||
errors << "You forgot to list test " << *it << ".\n";
|
||||
}
|
||||
}
|
||||
|
||||
const std::string& errors_str = errors.GetString();
|
||||
if (errors_str != "") {
|
||||
fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(),
|
||||
errors_str.c_str());
|
||||
fflush(stderr);
|
||||
posix::Abort();
|
||||
}
|
||||
|
||||
return registered_tests;
|
||||
}
|
||||
|
||||
#endif // GTEST_HAS_TYPED_TEST_P
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
// Copyright 2008 Google Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
#include "gtest/gtest-typed-test.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
#if GTEST_HAS_TYPED_TEST_P
|
||||
|
||||
// Skips to the first non-space char in str. Returns an empty string if str
|
||||
// contains only whitespace characters.
|
||||
static const char* SkipSpaces(const char* str) {
|
||||
while (IsSpace(*str))
|
||||
str++;
|
||||
return str;
|
||||
}
|
||||
|
||||
// Verifies that registered_tests match the test names in
|
||||
// defined_test_names_; returns registered_tests if successful, or
|
||||
// aborts the program otherwise.
|
||||
const char* TypedTestCasePState::VerifyRegisteredTestNames(
|
||||
const char* file, int line, const char* registered_tests) {
|
||||
typedef ::std::set<const char*>::const_iterator DefinedTestIter;
|
||||
registered_ = true;
|
||||
|
||||
// Skip initial whitespace in registered_tests since some
|
||||
// preprocessors prefix stringizied literals with whitespace.
|
||||
registered_tests = SkipSpaces(registered_tests);
|
||||
|
||||
Message errors;
|
||||
::std::set<std::string> tests;
|
||||
for (const char* names = registered_tests; names != NULL;
|
||||
names = SkipComma(names)) {
|
||||
const std::string name = GetPrefixUntilComma(names);
|
||||
if (tests.count(name) != 0) {
|
||||
errors << "Test " << name << " is listed more than once.\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
for (DefinedTestIter it = defined_test_names_.begin();
|
||||
it != defined_test_names_.end();
|
||||
++it) {
|
||||
if (name == *it) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
tests.insert(name);
|
||||
} else {
|
||||
errors << "No test named " << name
|
||||
<< " can be found in this test case.\n";
|
||||
}
|
||||
}
|
||||
|
||||
for (DefinedTestIter it = defined_test_names_.begin();
|
||||
it != defined_test_names_.end();
|
||||
++it) {
|
||||
if (tests.count(*it) == 0) {
|
||||
errors << "You forgot to list test " << *it << ".\n";
|
||||
}
|
||||
}
|
||||
|
||||
const std::string& errors_str = errors.GetString();
|
||||
if (errors_str != "") {
|
||||
fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(),
|
||||
errors_str.c_str());
|
||||
fflush(stderr);
|
||||
posix::Abort();
|
||||
}
|
||||
|
||||
return registered_tests;
|
||||
}
|
||||
|
||||
#endif // GTEST_HAS_TYPED_TEST_P
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,38 +1,38 @@
|
||||
// Copyright 2006, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
GTEST_API_ int main(int argc, char **argv) {
|
||||
printf("Running main() from gtest_main.cc\n");
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
// Copyright 2006, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
GTEST_API_ int main(int argc, char **argv) {
|
||||
printf("Running main() from gtest_main.cc\n");
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
1078
gmock/include/gmock/gmock-actions.h
Normal file
1078
gmock/include/gmock/gmock-actions.h
Normal file
File diff suppressed because it is too large
Load Diff
147
gmock/include/gmock/gmock-cardinalities.h
Normal file
147
gmock/include/gmock/gmock-cardinalities.h
Normal file
@@ -0,0 +1,147 @@
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file implements some commonly used cardinalities. More
|
||||
// cardinalities can be defined by the user implementing the
|
||||
// CardinalityInterface interface if necessary.
|
||||
|
||||
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
|
||||
#define GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
|
||||
|
||||
#include <limits.h>
|
||||
#include <ostream> // NOLINT
|
||||
#include "gmock/internal/gmock-port.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace testing {
|
||||
|
||||
// To implement a cardinality Foo, define:
|
||||
// 1. a class FooCardinality that implements the
|
||||
// CardinalityInterface interface, and
|
||||
// 2. a factory function that creates a Cardinality object from a
|
||||
// const FooCardinality*.
|
||||
//
|
||||
// The two-level delegation design follows that of Matcher, providing
|
||||
// consistency for extension developers. It also eases ownership
|
||||
// management as Cardinality objects can now be copied like plain values.
|
||||
|
||||
// The implementation of a cardinality.
|
||||
class CardinalityInterface {
|
||||
public:
|
||||
virtual ~CardinalityInterface() {}
|
||||
|
||||
// Conservative estimate on the lower/upper bound of the number of
|
||||
// calls allowed.
|
||||
virtual int ConservativeLowerBound() const { return 0; }
|
||||
virtual int ConservativeUpperBound() const { return INT_MAX; }
|
||||
|
||||
// Returns true iff call_count calls will satisfy this cardinality.
|
||||
virtual bool IsSatisfiedByCallCount(int call_count) const = 0;
|
||||
|
||||
// Returns true iff call_count calls will saturate this cardinality.
|
||||
virtual bool IsSaturatedByCallCount(int call_count) const = 0;
|
||||
|
||||
// Describes self to an ostream.
|
||||
virtual void DescribeTo(::std::ostream* os) const = 0;
|
||||
};
|
||||
|
||||
// A Cardinality is a copyable and IMMUTABLE (except by assignment)
|
||||
// object that specifies how many times a mock function is expected to
|
||||
// be called. The implementation of Cardinality is just a linked_ptr
|
||||
// to const CardinalityInterface, so copying is fairly cheap.
|
||||
// Don't inherit from Cardinality!
|
||||
class GTEST_API_ Cardinality {
|
||||
public:
|
||||
// Constructs a null cardinality. Needed for storing Cardinality
|
||||
// objects in STL containers.
|
||||
Cardinality() {}
|
||||
|
||||
// Constructs a Cardinality from its implementation.
|
||||
explicit Cardinality(const CardinalityInterface* impl) : impl_(impl) {}
|
||||
|
||||
// Conservative estimate on the lower/upper bound of the number of
|
||||
// calls allowed.
|
||||
int ConservativeLowerBound() const { return impl_->ConservativeLowerBound(); }
|
||||
int ConservativeUpperBound() const { return impl_->ConservativeUpperBound(); }
|
||||
|
||||
// Returns true iff call_count calls will satisfy this cardinality.
|
||||
bool IsSatisfiedByCallCount(int call_count) const {
|
||||
return impl_->IsSatisfiedByCallCount(call_count);
|
||||
}
|
||||
|
||||
// Returns true iff call_count calls will saturate this cardinality.
|
||||
bool IsSaturatedByCallCount(int call_count) const {
|
||||
return impl_->IsSaturatedByCallCount(call_count);
|
||||
}
|
||||
|
||||
// Returns true iff call_count calls will over-saturate this
|
||||
// cardinality, i.e. exceed the maximum number of allowed calls.
|
||||
bool IsOverSaturatedByCallCount(int call_count) const {
|
||||
return impl_->IsSaturatedByCallCount(call_count) &&
|
||||
!impl_->IsSatisfiedByCallCount(call_count);
|
||||
}
|
||||
|
||||
// Describes self to an ostream
|
||||
void DescribeTo(::std::ostream* os) const { impl_->DescribeTo(os); }
|
||||
|
||||
// Describes the given actual call count to an ostream.
|
||||
static void DescribeActualCallCountTo(int actual_call_count,
|
||||
::std::ostream* os);
|
||||
|
||||
private:
|
||||
internal::linked_ptr<const CardinalityInterface> impl_;
|
||||
};
|
||||
|
||||
// Creates a cardinality that allows at least n calls.
|
||||
GTEST_API_ Cardinality AtLeast(int n);
|
||||
|
||||
// Creates a cardinality that allows at most n calls.
|
||||
GTEST_API_ Cardinality AtMost(int n);
|
||||
|
||||
// Creates a cardinality that allows any number of calls.
|
||||
GTEST_API_ Cardinality AnyNumber();
|
||||
|
||||
// Creates a cardinality that allows between min and max calls.
|
||||
GTEST_API_ Cardinality Between(int min, int max);
|
||||
|
||||
// Creates a cardinality that allows exactly n calls.
|
||||
GTEST_API_ Cardinality Exactly(int n);
|
||||
|
||||
// Creates a cardinality from its implementation.
|
||||
inline Cardinality MakeCardinality(const CardinalityInterface* c) {
|
||||
return Cardinality(c);
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
|
||||
2415
gmock/include/gmock/gmock-generated-actions.h
Normal file
2415
gmock/include/gmock/gmock-generated-actions.h
Normal file
File diff suppressed because it is too large
Load Diff
821
gmock/include/gmock/gmock-generated-actions.h.pump
Normal file
821
gmock/include/gmock/gmock-generated-actions.h.pump
Normal file
@@ -0,0 +1,821 @@
|
||||
$$ -*- mode: c++; -*-
|
||||
$$ This is a Pump source file. Please use Pump to convert it to
|
||||
$$ gmock-generated-actions.h.
|
||||
$$
|
||||
$var n = 10 $$ The maximum arity we support.
|
||||
$$}} This meta comment fixes auto-indentation in editors.
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file implements some commonly used variadic actions.
|
||||
|
||||
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
|
||||
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
|
||||
|
||||
#include "gmock/gmock-actions.h"
|
||||
#include "gmock/internal/gmock-port.h"
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// InvokeHelper<F> knows how to unpack an N-tuple and invoke an N-ary
|
||||
// function or method with the unpacked values, where F is a function
|
||||
// type that takes N arguments.
|
||||
template <typename Result, typename ArgumentTuple>
|
||||
class InvokeHelper;
|
||||
|
||||
|
||||
$range i 0..n
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
$var types = [[$for j [[, typename A$j]]]]
|
||||
$var as = [[$for j, [[A$j]]]]
|
||||
$var args = [[$if i==0 [[]] $else [[ args]]]]
|
||||
$var import = [[$if i==0 [[]] $else [[
|
||||
using ::std::tr1::get;
|
||||
|
||||
]]]]
|
||||
$var gets = [[$for j, [[get<$(j - 1)>(args)]]]]
|
||||
template <typename R$types>
|
||||
class InvokeHelper<R, ::std::tr1::tuple<$as> > {
|
||||
public:
|
||||
template <typename Function>
|
||||
static R Invoke(Function function, const ::std::tr1::tuple<$as>&$args) {
|
||||
$import return function($gets);
|
||||
}
|
||||
|
||||
template <class Class, typename MethodPtr>
|
||||
static R InvokeMethod(Class* obj_ptr,
|
||||
MethodPtr method_ptr,
|
||||
const ::std::tr1::tuple<$as>&$args) {
|
||||
$import return (obj_ptr->*method_ptr)($gets);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
]]
|
||||
// CallableHelper has static methods for invoking "callables",
|
||||
// i.e. function pointers and functors. It uses overloading to
|
||||
// provide a uniform interface for invoking different kinds of
|
||||
// callables. In particular, you can use:
|
||||
//
|
||||
// CallableHelper<R>::Call(callable, a1, a2, ..., an)
|
||||
//
|
||||
// to invoke an n-ary callable, where R is its return type. If an
|
||||
// argument, say a2, needs to be passed by reference, you should write
|
||||
// ByRef(a2) instead of a2 in the above expression.
|
||||
template <typename R>
|
||||
class CallableHelper {
|
||||
public:
|
||||
// Calls a nullary callable.
|
||||
template <typename Function>
|
||||
static R Call(Function function) { return function(); }
|
||||
|
||||
// Calls a unary callable.
|
||||
|
||||
// We deliberately pass a1 by value instead of const reference here
|
||||
// in case it is a C-string literal. If we had declared the
|
||||
// parameter as 'const A1& a1' and write Call(function, "Hi"), the
|
||||
// compiler would've thought A1 is 'char[3]', which causes trouble
|
||||
// when you need to copy a value of type A1. By declaring the
|
||||
// parameter as 'A1 a1', the compiler will correctly infer that A1
|
||||
// is 'const char*' when it sees Call(function, "Hi").
|
||||
//
|
||||
// Since this function is defined inline, the compiler can get rid
|
||||
// of the copying of the arguments. Therefore the performance won't
|
||||
// be hurt.
|
||||
template <typename Function, typename A1>
|
||||
static R Call(Function function, A1 a1) { return function(a1); }
|
||||
|
||||
$range i 2..n
|
||||
$for i
|
||||
[[
|
||||
$var arity = [[$if i==2 [[binary]] $elif i==3 [[ternary]] $else [[$i-ary]]]]
|
||||
|
||||
// Calls a $arity callable.
|
||||
|
||||
$range j 1..i
|
||||
$var typename_As = [[$for j, [[typename A$j]]]]
|
||||
$var Aas = [[$for j, [[A$j a$j]]]]
|
||||
$var as = [[$for j, [[a$j]]]]
|
||||
$var typename_Ts = [[$for j, [[typename T$j]]]]
|
||||
$var Ts = [[$for j, [[T$j]]]]
|
||||
template <typename Function, $typename_As>
|
||||
static R Call(Function function, $Aas) {
|
||||
return function($as);
|
||||
}
|
||||
|
||||
]]
|
||||
}; // class CallableHelper
|
||||
|
||||
// An INTERNAL macro for extracting the type of a tuple field. It's
|
||||
// subject to change without notice - DO NOT USE IN USER CODE!
|
||||
#define GMOCK_FIELD_(Tuple, N) \
|
||||
typename ::std::tr1::tuple_element<N, Tuple>::type
|
||||
|
||||
$range i 1..n
|
||||
|
||||
// SelectArgs<Result, ArgumentTuple, k1, k2, ..., k_n>::type is the
|
||||
// type of an n-ary function whose i-th (1-based) argument type is the
|
||||
// k{i}-th (0-based) field of ArgumentTuple, which must be a tuple
|
||||
// type, and whose return type is Result. For example,
|
||||
// SelectArgs<int, ::std::tr1::tuple<bool, char, double, long>, 0, 3>::type
|
||||
// is int(bool, long).
|
||||
//
|
||||
// SelectArgs<Result, ArgumentTuple, k1, k2, ..., k_n>::Select(args)
|
||||
// returns the selected fields (k1, k2, ..., k_n) of args as a tuple.
|
||||
// For example,
|
||||
// SelectArgs<int, ::std::tr1::tuple<bool, char, double>, 2, 0>::Select(
|
||||
// ::std::tr1::make_tuple(true, 'a', 2.5))
|
||||
// returns ::std::tr1::tuple (2.5, true).
|
||||
//
|
||||
// The numbers in list k1, k2, ..., k_n must be >= 0, where n can be
|
||||
// in the range [0, $n]. Duplicates are allowed and they don't have
|
||||
// to be in an ascending or descending order.
|
||||
|
||||
template <typename Result, typename ArgumentTuple, $for i, [[int k$i]]>
|
||||
class SelectArgs {
|
||||
public:
|
||||
typedef Result type($for i, [[GMOCK_FIELD_(ArgumentTuple, k$i)]]);
|
||||
typedef typename Function<type>::ArgumentTuple SelectedArgs;
|
||||
static SelectedArgs Select(const ArgumentTuple& args) {
|
||||
using ::std::tr1::get;
|
||||
return SelectedArgs($for i, [[get<k$i>(args)]]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$for i [[
|
||||
$range j 1..n
|
||||
$range j1 1..i-1
|
||||
template <typename Result, typename ArgumentTuple$for j1[[, int k$j1]]>
|
||||
class SelectArgs<Result, ArgumentTuple,
|
||||
$for j, [[$if j <= i-1 [[k$j]] $else [[-1]]]]> {
|
||||
public:
|
||||
typedef Result type($for j1, [[GMOCK_FIELD_(ArgumentTuple, k$j1)]]);
|
||||
typedef typename Function<type>::ArgumentTuple SelectedArgs;
|
||||
static SelectedArgs Select(const ArgumentTuple& [[]]
|
||||
$if i == 1 [[/* args */]] $else [[args]]) {
|
||||
using ::std::tr1::get;
|
||||
return SelectedArgs($for j1, [[get<k$j1>(args)]]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
]]
|
||||
#undef GMOCK_FIELD_
|
||||
|
||||
$var ks = [[$for i, [[k$i]]]]
|
||||
|
||||
// Implements the WithArgs action.
|
||||
template <typename InnerAction, $for i, [[int k$i = -1]]>
|
||||
class WithArgsAction {
|
||||
public:
|
||||
explicit WithArgsAction(const InnerAction& action) : action_(action) {}
|
||||
|
||||
template <typename F>
|
||||
operator Action<F>() const { return MakeAction(new Impl<F>(action_)); }
|
||||
|
||||
private:
|
||||
template <typename F>
|
||||
class Impl : public ActionInterface<F> {
|
||||
public:
|
||||
typedef typename Function<F>::Result Result;
|
||||
typedef typename Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
explicit Impl(const InnerAction& action) : action_(action) {}
|
||||
|
||||
virtual Result Perform(const ArgumentTuple& args) {
|
||||
return action_.Perform(SelectArgs<Result, ArgumentTuple, $ks>::Select(args));
|
||||
}
|
||||
|
||||
private:
|
||||
typedef typename SelectArgs<Result, ArgumentTuple,
|
||||
$ks>::type InnerFunctionType;
|
||||
|
||||
Action<InnerFunctionType> action_;
|
||||
};
|
||||
|
||||
const InnerAction action_;
|
||||
|
||||
GTEST_DISALLOW_ASSIGN_(WithArgsAction);
|
||||
};
|
||||
|
||||
// A macro from the ACTION* family (defined later in this file)
|
||||
// defines an action that can be used in a mock function. Typically,
|
||||
// these actions only care about a subset of the arguments of the mock
|
||||
// function. For example, if such an action only uses the second
|
||||
// argument, it can be used in any mock function that takes >= 2
|
||||
// arguments where the type of the second argument is compatible.
|
||||
//
|
||||
// Therefore, the action implementation must be prepared to take more
|
||||
// arguments than it needs. The ExcessiveArg type is used to
|
||||
// represent those excessive arguments. In order to keep the compiler
|
||||
// error messages tractable, we define it in the testing namespace
|
||||
// instead of testing::internal. However, this is an INTERNAL TYPE
|
||||
// and subject to change without notice, so a user MUST NOT USE THIS
|
||||
// TYPE DIRECTLY.
|
||||
struct ExcessiveArg {};
|
||||
|
||||
// A helper class needed for implementing the ACTION* macros.
|
||||
template <typename Result, class Impl>
|
||||
class ActionHelper {
|
||||
public:
|
||||
$range i 0..n
|
||||
$for i
|
||||
|
||||
[[
|
||||
$var template = [[$if i==0 [[]] $else [[
|
||||
$range j 0..i-1
|
||||
template <$for j, [[typename A$j]]>
|
||||
]]]]
|
||||
$range j 0..i-1
|
||||
$var As = [[$for j, [[A$j]]]]
|
||||
$var as = [[$for j, [[get<$j>(args)]]]]
|
||||
$range k 1..n-i
|
||||
$var eas = [[$for k, [[ExcessiveArg()]]]]
|
||||
$var arg_list = [[$if (i==0) | (i==n) [[$as$eas]] $else [[$as, $eas]]]]
|
||||
$template
|
||||
static Result Perform(Impl* impl, const ::std::tr1::tuple<$As>& args) {
|
||||
using ::std::tr1::get;
|
||||
return impl->template gmock_PerformImpl<$As>(args, $arg_list);
|
||||
}
|
||||
|
||||
]]
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// Various overloads for Invoke().
|
||||
|
||||
// WithArgs<N1, N2, ..., Nk>(an_action) creates an action that passes
|
||||
// the selected arguments of the mock function to an_action and
|
||||
// performs it. It serves as an adaptor between actions with
|
||||
// different argument lists. C++ doesn't support default arguments for
|
||||
// function templates, so we have to overload it.
|
||||
|
||||
$range i 1..n
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
template <$for j [[int k$j, ]]typename InnerAction>
|
||||
inline internal::WithArgsAction<InnerAction$for j [[, k$j]]>
|
||||
WithArgs(const InnerAction& action) {
|
||||
return internal::WithArgsAction<InnerAction$for j [[, k$j]]>(action);
|
||||
}
|
||||
|
||||
|
||||
]]
|
||||
// Creates an action that does actions a1, a2, ..., sequentially in
|
||||
// each invocation.
|
||||
$range i 2..n
|
||||
$for i [[
|
||||
$range j 2..i
|
||||
$var types = [[$for j, [[typename Action$j]]]]
|
||||
$var Aas = [[$for j [[, Action$j a$j]]]]
|
||||
|
||||
template <typename Action1, $types>
|
||||
$range k 1..i-1
|
||||
|
||||
inline $for k [[internal::DoBothAction<Action$k, ]]Action$i$for k [[>]]
|
||||
|
||||
DoAll(Action1 a1$Aas) {
|
||||
$if i==2 [[
|
||||
|
||||
return internal::DoBothAction<Action1, Action2>(a1, a2);
|
||||
]] $else [[
|
||||
$range j2 2..i
|
||||
|
||||
return DoAll(a1, DoAll($for j2, [[a$j2]]));
|
||||
]]
|
||||
|
||||
}
|
||||
|
||||
]]
|
||||
|
||||
} // namespace testing
|
||||
|
||||
// The ACTION* family of macros can be used in a namespace scope to
|
||||
// define custom actions easily. The syntax:
|
||||
//
|
||||
// ACTION(name) { statements; }
|
||||
//
|
||||
// will define an action with the given name that executes the
|
||||
// statements. The value returned by the statements will be used as
|
||||
// the return value of the action. Inside the statements, you can
|
||||
// refer to the K-th (0-based) argument of the mock function by
|
||||
// 'argK', and refer to its type by 'argK_type'. For example:
|
||||
//
|
||||
// ACTION(IncrementArg1) {
|
||||
// arg1_type temp = arg1;
|
||||
// return ++(*temp);
|
||||
// }
|
||||
//
|
||||
// allows you to write
|
||||
//
|
||||
// ...WillOnce(IncrementArg1());
|
||||
//
|
||||
// You can also refer to the entire argument tuple and its type by
|
||||
// 'args' and 'args_type', and refer to the mock function type and its
|
||||
// return type by 'function_type' and 'return_type'.
|
||||
//
|
||||
// Note that you don't need to specify the types of the mock function
|
||||
// arguments. However rest assured that your code is still type-safe:
|
||||
// you'll get a compiler error if *arg1 doesn't support the ++
|
||||
// operator, or if the type of ++(*arg1) isn't compatible with the
|
||||
// mock function's return type, for example.
|
||||
//
|
||||
// Sometimes you'll want to parameterize the action. For that you can use
|
||||
// another macro:
|
||||
//
|
||||
// ACTION_P(name, param_name) { statements; }
|
||||
//
|
||||
// For example:
|
||||
//
|
||||
// ACTION_P(Add, n) { return arg0 + n; }
|
||||
//
|
||||
// will allow you to write:
|
||||
//
|
||||
// ...WillOnce(Add(5));
|
||||
//
|
||||
// Note that you don't need to provide the type of the parameter
|
||||
// either. If you need to reference the type of a parameter named
|
||||
// 'foo', you can write 'foo_type'. For example, in the body of
|
||||
// ACTION_P(Add, n) above, you can write 'n_type' to refer to the type
|
||||
// of 'n'.
|
||||
//
|
||||
// We also provide ACTION_P2, ACTION_P3, ..., up to ACTION_P$n to support
|
||||
// multi-parameter actions.
|
||||
//
|
||||
// For the purpose of typing, you can view
|
||||
//
|
||||
// ACTION_Pk(Foo, p1, ..., pk) { ... }
|
||||
//
|
||||
// as shorthand for
|
||||
//
|
||||
// template <typename p1_type, ..., typename pk_type>
|
||||
// FooActionPk<p1_type, ..., pk_type> Foo(p1_type p1, ..., pk_type pk) { ... }
|
||||
//
|
||||
// In particular, you can provide the template type arguments
|
||||
// explicitly when invoking Foo(), as in Foo<long, bool>(5, false);
|
||||
// although usually you can rely on the compiler to infer the types
|
||||
// for you automatically. You can assign the result of expression
|
||||
// Foo(p1, ..., pk) to a variable of type FooActionPk<p1_type, ...,
|
||||
// pk_type>. This can be useful when composing actions.
|
||||
//
|
||||
// You can also overload actions with different numbers of parameters:
|
||||
//
|
||||
// ACTION_P(Plus, a) { ... }
|
||||
// ACTION_P2(Plus, a, b) { ... }
|
||||
//
|
||||
// While it's tempting to always use the ACTION* macros when defining
|
||||
// a new action, you should also consider implementing ActionInterface
|
||||
// or using MakePolymorphicAction() instead, especially if you need to
|
||||
// use the action a lot. While these approaches require more work,
|
||||
// they give you more control on the types of the mock function
|
||||
// arguments and the action parameters, which in general leads to
|
||||
// better compiler error messages that pay off in the long run. They
|
||||
// also allow overloading actions based on parameter types (as opposed
|
||||
// to just based on the number of parameters).
|
||||
//
|
||||
// CAVEAT:
|
||||
//
|
||||
// ACTION*() can only be used in a namespace scope. The reason is
|
||||
// that C++ doesn't yet allow function-local types to be used to
|
||||
// instantiate templates. The up-coming C++0x standard will fix this.
|
||||
// Once that's done, we'll consider supporting using ACTION*() inside
|
||||
// a function.
|
||||
//
|
||||
// MORE INFORMATION:
|
||||
//
|
||||
// To learn more about using these macros, please search for 'ACTION'
|
||||
// on http://code.google.com/p/googlemock/wiki/CookBook.
|
||||
|
||||
$range i 0..n
|
||||
$range k 0..n-1
|
||||
|
||||
// An internal macro needed for implementing ACTION*().
|
||||
#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_\
|
||||
const args_type& args GTEST_ATTRIBUTE_UNUSED_
|
||||
$for k [[, \
|
||||
arg$k[[]]_type arg$k GTEST_ATTRIBUTE_UNUSED_]]
|
||||
|
||||
|
||||
// Sometimes you want to give an action explicit template parameters
|
||||
// that cannot be inferred from its value parameters. ACTION() and
|
||||
// ACTION_P*() don't support that. ACTION_TEMPLATE() remedies that
|
||||
// and can be viewed as an extension to ACTION() and ACTION_P*().
|
||||
//
|
||||
// The syntax:
|
||||
//
|
||||
// ACTION_TEMPLATE(ActionName,
|
||||
// HAS_m_TEMPLATE_PARAMS(kind1, name1, ..., kind_m, name_m),
|
||||
// AND_n_VALUE_PARAMS(p1, ..., p_n)) { statements; }
|
||||
//
|
||||
// defines an action template that takes m explicit template
|
||||
// parameters and n value parameters. name_i is the name of the i-th
|
||||
// template parameter, and kind_i specifies whether it's a typename,
|
||||
// an integral constant, or a template. p_i is the name of the i-th
|
||||
// value parameter.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // DuplicateArg<k, T>(output) converts the k-th argument of the mock
|
||||
// // function to type T and copies it to *output.
|
||||
// ACTION_TEMPLATE(DuplicateArg,
|
||||
// HAS_2_TEMPLATE_PARAMS(int, k, typename, T),
|
||||
// AND_1_VALUE_PARAMS(output)) {
|
||||
// *output = T(std::tr1::get<k>(args));
|
||||
// }
|
||||
// ...
|
||||
// int n;
|
||||
// EXPECT_CALL(mock, Foo(_, _))
|
||||
// .WillOnce(DuplicateArg<1, unsigned char>(&n));
|
||||
//
|
||||
// To create an instance of an action template, write:
|
||||
//
|
||||
// ActionName<t1, ..., t_m>(v1, ..., v_n)
|
||||
//
|
||||
// where the ts are the template arguments and the vs are the value
|
||||
// arguments. The value argument types are inferred by the compiler.
|
||||
// If you want to explicitly specify the value argument types, you can
|
||||
// provide additional template arguments:
|
||||
//
|
||||
// ActionName<t1, ..., t_m, u1, ..., u_k>(v1, ..., v_n)
|
||||
//
|
||||
// where u_i is the desired type of v_i.
|
||||
//
|
||||
// ACTION_TEMPLATE and ACTION/ACTION_P* can be overloaded on the
|
||||
// number of value parameters, but not on the number of template
|
||||
// parameters. Without the restriction, the meaning of the following
|
||||
// is unclear:
|
||||
//
|
||||
// OverloadedAction<int, bool>(x);
|
||||
//
|
||||
// Are we using a single-template-parameter action where 'bool' refers
|
||||
// to the type of x, or are we using a two-template-parameter action
|
||||
// where the compiler is asked to infer the type of x?
|
||||
//
|
||||
// Implementation notes:
|
||||
//
|
||||
// GMOCK_INTERNAL_*_HAS_m_TEMPLATE_PARAMS and
|
||||
// GMOCK_INTERNAL_*_AND_n_VALUE_PARAMS are internal macros for
|
||||
// implementing ACTION_TEMPLATE. The main trick we use is to create
|
||||
// new macro invocations when expanding a macro. For example, we have
|
||||
//
|
||||
// #define ACTION_TEMPLATE(name, template_params, value_params)
|
||||
// ... GMOCK_INTERNAL_DECL_##template_params ...
|
||||
//
|
||||
// which causes ACTION_TEMPLATE(..., HAS_1_TEMPLATE_PARAMS(typename, T), ...)
|
||||
// to expand to
|
||||
//
|
||||
// ... GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS(typename, T) ...
|
||||
//
|
||||
// Since GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS is a macro, the
|
||||
// preprocessor will continue to expand it to
|
||||
//
|
||||
// ... typename T ...
|
||||
//
|
||||
// This technique conforms to the C++ standard and is portable. It
|
||||
// allows us to implement action templates using O(N) code, where N is
|
||||
// the maximum number of template/value parameters supported. Without
|
||||
// using it, we'd have to devote O(N^2) amount of code to implement all
|
||||
// combinations of m and n.
|
||||
|
||||
// Declares the template parameters.
|
||||
|
||||
$range j 1..n
|
||||
$for j [[
|
||||
$range m 0..j-1
|
||||
#define GMOCK_INTERNAL_DECL_HAS_$j[[]]
|
||||
_TEMPLATE_PARAMS($for m, [[kind$m, name$m]]) $for m, [[kind$m name$m]]
|
||||
|
||||
|
||||
]]
|
||||
|
||||
// Lists the template parameters.
|
||||
|
||||
$for j [[
|
||||
$range m 0..j-1
|
||||
#define GMOCK_INTERNAL_LIST_HAS_$j[[]]
|
||||
_TEMPLATE_PARAMS($for m, [[kind$m, name$m]]) $for m, [[name$m]]
|
||||
|
||||
|
||||
]]
|
||||
|
||||
// Declares the types of value parameters.
|
||||
|
||||
$for i [[
|
||||
$range j 0..i-1
|
||||
#define GMOCK_INTERNAL_DECL_TYPE_AND_$i[[]]
|
||||
_VALUE_PARAMS($for j, [[p$j]]) $for j [[, typename p$j##_type]]
|
||||
|
||||
|
||||
]]
|
||||
|
||||
// Initializes the value parameters.
|
||||
|
||||
$for i [[
|
||||
$range j 0..i-1
|
||||
#define GMOCK_INTERNAL_INIT_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]])\
|
||||
($for j, [[p$j##_type gmock_p$j]])$if i>0 [[ : ]]$for j, [[p$j(gmock_p$j)]]
|
||||
|
||||
|
||||
]]
|
||||
|
||||
// Declares the fields for storing the value parameters.
|
||||
|
||||
$for i [[
|
||||
$range j 0..i-1
|
||||
#define GMOCK_INTERNAL_DEFN_AND_$i[[]]
|
||||
_VALUE_PARAMS($for j, [[p$j]]) $for j [[p$j##_type p$j; ]]
|
||||
|
||||
|
||||
]]
|
||||
|
||||
// Lists the value parameters.
|
||||
|
||||
$for i [[
|
||||
$range j 0..i-1
|
||||
#define GMOCK_INTERNAL_LIST_AND_$i[[]]
|
||||
_VALUE_PARAMS($for j, [[p$j]]) $for j, [[p$j]]
|
||||
|
||||
|
||||
]]
|
||||
|
||||
// Lists the value parameter types.
|
||||
|
||||
$for i [[
|
||||
$range j 0..i-1
|
||||
#define GMOCK_INTERNAL_LIST_TYPE_AND_$i[[]]
|
||||
_VALUE_PARAMS($for j, [[p$j]]) $for j [[, p$j##_type]]
|
||||
|
||||
|
||||
]]
|
||||
|
||||
// Declares the value parameters.
|
||||
|
||||
$for i [[
|
||||
$range j 0..i-1
|
||||
#define GMOCK_INTERNAL_DECL_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]]) [[]]
|
||||
$for j, [[p$j##_type p$j]]
|
||||
|
||||
|
||||
]]
|
||||
|
||||
// The suffix of the class template implementing the action template.
|
||||
$for i [[
|
||||
|
||||
|
||||
$range j 0..i-1
|
||||
#define GMOCK_INTERNAL_COUNT_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]]) [[]]
|
||||
$if i==1 [[P]] $elif i>=2 [[P$i]]
|
||||
]]
|
||||
|
||||
|
||||
// The name of the class template implementing the action template.
|
||||
#define GMOCK_ACTION_CLASS_(name, value_params)\
|
||||
GTEST_CONCAT_TOKEN_(name##Action, GMOCK_INTERNAL_COUNT_##value_params)
|
||||
|
||||
$range k 0..n-1
|
||||
|
||||
#define ACTION_TEMPLATE(name, template_params, value_params)\
|
||||
template <GMOCK_INTERNAL_DECL_##template_params\
|
||||
GMOCK_INTERNAL_DECL_TYPE_##value_params>\
|
||||
class GMOCK_ACTION_CLASS_(name, value_params) {\
|
||||
public:\
|
||||
GMOCK_ACTION_CLASS_(name, value_params)\
|
||||
GMOCK_INTERNAL_INIT_##value_params {}\
|
||||
template <typename F>\
|
||||
class gmock_Impl : public ::testing::ActionInterface<F> {\
|
||||
public:\
|
||||
typedef F function_type;\
|
||||
typedef typename ::testing::internal::Function<F>::Result return_type;\
|
||||
typedef typename ::testing::internal::Function<F>::ArgumentTuple\
|
||||
args_type;\
|
||||
explicit gmock_Impl GMOCK_INTERNAL_INIT_##value_params {}\
|
||||
virtual return_type Perform(const args_type& args) {\
|
||||
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
|
||||
Perform(this, args);\
|
||||
}\
|
||||
template <$for k, [[typename arg$k[[]]_type]]>\
|
||||
return_type gmock_PerformImpl(const args_type& args[[]]
|
||||
$for k [[, arg$k[[]]_type arg$k]]) const;\
|
||||
GMOCK_INTERNAL_DEFN_##value_params\
|
||||
private:\
|
||||
GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
|
||||
};\
|
||||
template <typename F> operator ::testing::Action<F>() const {\
|
||||
return ::testing::Action<F>(\
|
||||
new gmock_Impl<F>(GMOCK_INTERNAL_LIST_##value_params));\
|
||||
}\
|
||||
GMOCK_INTERNAL_DEFN_##value_params\
|
||||
private:\
|
||||
GTEST_DISALLOW_ASSIGN_(GMOCK_ACTION_CLASS_(name, value_params));\
|
||||
};\
|
||||
template <GMOCK_INTERNAL_DECL_##template_params\
|
||||
GMOCK_INTERNAL_DECL_TYPE_##value_params>\
|
||||
inline GMOCK_ACTION_CLASS_(name, value_params)<\
|
||||
GMOCK_INTERNAL_LIST_##template_params\
|
||||
GMOCK_INTERNAL_LIST_TYPE_##value_params> name(\
|
||||
GMOCK_INTERNAL_DECL_##value_params) {\
|
||||
return GMOCK_ACTION_CLASS_(name, value_params)<\
|
||||
GMOCK_INTERNAL_LIST_##template_params\
|
||||
GMOCK_INTERNAL_LIST_TYPE_##value_params>(\
|
||||
GMOCK_INTERNAL_LIST_##value_params);\
|
||||
}\
|
||||
template <GMOCK_INTERNAL_DECL_##template_params\
|
||||
GMOCK_INTERNAL_DECL_TYPE_##value_params>\
|
||||
template <typename F>\
|
||||
template <typename arg0_type, typename arg1_type, typename arg2_type, \
|
||||
typename arg3_type, typename arg4_type, typename arg5_type, \
|
||||
typename arg6_type, typename arg7_type, typename arg8_type, \
|
||||
typename arg9_type>\
|
||||
typename ::testing::internal::Function<F>::Result\
|
||||
GMOCK_ACTION_CLASS_(name, value_params)<\
|
||||
GMOCK_INTERNAL_LIST_##template_params\
|
||||
GMOCK_INTERNAL_LIST_TYPE_##value_params>::gmock_Impl<F>::\
|
||||
gmock_PerformImpl(\
|
||||
GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
|
||||
|
||||
$for i
|
||||
|
||||
[[
|
||||
$var template = [[$if i==0 [[]] $else [[
|
||||
$range j 0..i-1
|
||||
|
||||
template <$for j, [[typename p$j##_type]]>\
|
||||
]]]]
|
||||
$var class_name = [[name##Action[[$if i==0 [[]] $elif i==1 [[P]]
|
||||
$else [[P$i]]]]]]
|
||||
$range j 0..i-1
|
||||
$var ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]]
|
||||
$var param_types_and_names = [[$for j, [[p$j##_type p$j]]]]
|
||||
$var inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(gmock_p$j)]]]]]]
|
||||
$var param_field_decls = [[$for j
|
||||
[[
|
||||
|
||||
p$j##_type p$j;\
|
||||
]]]]
|
||||
$var param_field_decls2 = [[$for j
|
||||
[[
|
||||
|
||||
p$j##_type p$j;\
|
||||
]]]]
|
||||
$var params = [[$for j, [[p$j]]]]
|
||||
$var param_types = [[$if i==0 [[]] $else [[<$for j, [[p$j##_type]]>]]]]
|
||||
$var typename_arg_types = [[$for k, [[typename arg$k[[]]_type]]]]
|
||||
$var arg_types_and_names = [[$for k, [[arg$k[[]]_type arg$k]]]]
|
||||
$var macro_name = [[$if i==0 [[ACTION]] $elif i==1 [[ACTION_P]]
|
||||
$else [[ACTION_P$i]]]]
|
||||
|
||||
#define $macro_name(name$for j [[, p$j]])\$template
|
||||
class $class_name {\
|
||||
public:\
|
||||
$class_name($ctor_param_list)$inits {}\
|
||||
template <typename F>\
|
||||
class gmock_Impl : public ::testing::ActionInterface<F> {\
|
||||
public:\
|
||||
typedef F function_type;\
|
||||
typedef typename ::testing::internal::Function<F>::Result return_type;\
|
||||
typedef typename ::testing::internal::Function<F>::ArgumentTuple\
|
||||
args_type;\
|
||||
[[$if i==1 [[explicit ]]]]gmock_Impl($ctor_param_list)$inits {}\
|
||||
virtual return_type Perform(const args_type& args) {\
|
||||
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
|
||||
Perform(this, args);\
|
||||
}\
|
||||
template <$typename_arg_types>\
|
||||
return_type gmock_PerformImpl(const args_type& args, [[]]
|
||||
$arg_types_and_names) const;\$param_field_decls
|
||||
private:\
|
||||
GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
|
||||
};\
|
||||
template <typename F> operator ::testing::Action<F>() const {\
|
||||
return ::testing::Action<F>(new gmock_Impl<F>($params));\
|
||||
}\$param_field_decls2
|
||||
private:\
|
||||
GTEST_DISALLOW_ASSIGN_($class_name);\
|
||||
};\$template
|
||||
inline $class_name$param_types name($param_types_and_names) {\
|
||||
return $class_name$param_types($params);\
|
||||
}\$template
|
||||
template <typename F>\
|
||||
template <$typename_arg_types>\
|
||||
typename ::testing::internal::Function<F>::Result\
|
||||
$class_name$param_types::gmock_Impl<F>::gmock_PerformImpl(\
|
||||
GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
|
||||
]]
|
||||
$$ } // This meta comment fixes auto-indentation in Emacs. It won't
|
||||
$$ // show up in the generated code.
|
||||
|
||||
|
||||
namespace testing {
|
||||
|
||||
// The ACTION*() macros trigger warning C4100 (unreferenced formal
|
||||
// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in
|
||||
// the macro definition, as the warnings are generated when the macro
|
||||
// is expanded and macro expansion cannot contain #pragma. Therefore
|
||||
// we suppress them here.
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable:4100)
|
||||
#endif
|
||||
|
||||
// Various overloads for InvokeArgument<N>().
|
||||
//
|
||||
// The InvokeArgument<N>(a1, a2, ..., a_k) action invokes the N-th
|
||||
// (0-based) argument, which must be a k-ary callable, of the mock
|
||||
// function, with arguments a1, a2, ..., a_k.
|
||||
//
|
||||
// Notes:
|
||||
//
|
||||
// 1. The arguments are passed by value by default. If you need to
|
||||
// pass an argument by reference, wrap it inside ByRef(). For
|
||||
// example,
|
||||
//
|
||||
// InvokeArgument<1>(5, string("Hello"), ByRef(foo))
|
||||
//
|
||||
// passes 5 and string("Hello") by value, and passes foo by
|
||||
// reference.
|
||||
//
|
||||
// 2. If the callable takes an argument by reference but ByRef() is
|
||||
// not used, it will receive the reference to a copy of the value,
|
||||
// instead of the original value. For example, when the 0-th
|
||||
// argument of the mock function takes a const string&, the action
|
||||
//
|
||||
// InvokeArgument<0>(string("Hello"))
|
||||
//
|
||||
// makes a copy of the temporary string("Hello") object and passes a
|
||||
// reference of the copy, instead of the original temporary object,
|
||||
// to the callable. This makes it easy for a user to define an
|
||||
// InvokeArgument action from temporary values and have it performed
|
||||
// later.
|
||||
|
||||
$range i 0..n
|
||||
$for i [[
|
||||
$range j 0..i-1
|
||||
|
||||
ACTION_TEMPLATE(InvokeArgument,
|
||||
HAS_1_TEMPLATE_PARAMS(int, k),
|
||||
AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]])) {
|
||||
return internal::CallableHelper<return_type>::Call(
|
||||
::std::tr1::get<k>(args)$for j [[, p$j]]);
|
||||
}
|
||||
|
||||
]]
|
||||
|
||||
// Various overloads for ReturnNew<T>().
|
||||
//
|
||||
// The ReturnNew<T>(a1, a2, ..., a_k) action returns a pointer to a new
|
||||
// instance of type T, constructed on the heap with constructor arguments
|
||||
// a1, a2, ..., and a_k. The caller assumes ownership of the returned value.
|
||||
$range i 0..n
|
||||
$for i [[
|
||||
$range j 0..i-1
|
||||
$var ps = [[$for j, [[p$j]]]]
|
||||
|
||||
ACTION_TEMPLATE(ReturnNew,
|
||||
HAS_1_TEMPLATE_PARAMS(typename, T),
|
||||
AND_$i[[]]_VALUE_PARAMS($ps)) {
|
||||
return new T($ps);
|
||||
}
|
||||
|
||||
]]
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
|
||||
991
gmock/include/gmock/gmock-generated-function-mockers.h
Normal file
991
gmock/include/gmock/gmock-generated-function-mockers.h
Normal file
@@ -0,0 +1,991 @@
|
||||
// This file was GENERATED by command:
|
||||
// pump.py gmock-generated-function-mockers.h.pump
|
||||
// DO NOT EDIT BY HAND!!!
|
||||
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file implements function mockers of various arities.
|
||||
|
||||
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
|
||||
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
|
||||
|
||||
#include "gmock/gmock-spec-builders.h"
|
||||
#include "gmock/internal/gmock-internal-utils.h"
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
template <typename F>
|
||||
class FunctionMockerBase;
|
||||
|
||||
// Note: class FunctionMocker really belongs to the ::testing
|
||||
// namespace. However if we define it in ::testing, MSVC will
|
||||
// complain when classes in ::testing::internal declare it as a
|
||||
// friend class template. To workaround this compiler bug, we define
|
||||
// FunctionMocker in ::testing::internal and import it into ::testing.
|
||||
template <typename F>
|
||||
class FunctionMocker;
|
||||
|
||||
template <typename R>
|
||||
class FunctionMocker<R()> : public
|
||||
internal::FunctionMockerBase<R()> {
|
||||
public:
|
||||
typedef R F();
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F>& With() {
|
||||
return this->current_spec();
|
||||
}
|
||||
|
||||
R Invoke() {
|
||||
// Even though gcc and MSVC don't enforce it, 'this->' is required
|
||||
// by the C++ standard [14.6.4] here, as the base class type is
|
||||
// dependent on the template argument (and thus shouldn't be
|
||||
// looked into when resolving InvokeWith).
|
||||
return this->InvokeWith(ArgumentTuple());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename R, typename A1>
|
||||
class FunctionMocker<R(A1)> : public
|
||||
internal::FunctionMockerBase<R(A1)> {
|
||||
public:
|
||||
typedef R F(A1);
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F>& With(const Matcher<A1>& m1) {
|
||||
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1));
|
||||
return this->current_spec();
|
||||
}
|
||||
|
||||
R Invoke(A1 a1) {
|
||||
// Even though gcc and MSVC don't enforce it, 'this->' is required
|
||||
// by the C++ standard [14.6.4] here, as the base class type is
|
||||
// dependent on the template argument (and thus shouldn't be
|
||||
// looked into when resolving InvokeWith).
|
||||
return this->InvokeWith(ArgumentTuple(a1));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2>
|
||||
class FunctionMocker<R(A1, A2)> : public
|
||||
internal::FunctionMockerBase<R(A1, A2)> {
|
||||
public:
|
||||
typedef R F(A1, A2);
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2) {
|
||||
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2));
|
||||
return this->current_spec();
|
||||
}
|
||||
|
||||
R Invoke(A1 a1, A2 a2) {
|
||||
// Even though gcc and MSVC don't enforce it, 'this->' is required
|
||||
// by the C++ standard [14.6.4] here, as the base class type is
|
||||
// dependent on the template argument (and thus shouldn't be
|
||||
// looked into when resolving InvokeWith).
|
||||
return this->InvokeWith(ArgumentTuple(a1, a2));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3>
|
||||
class FunctionMocker<R(A1, A2, A3)> : public
|
||||
internal::FunctionMockerBase<R(A1, A2, A3)> {
|
||||
public:
|
||||
typedef R F(A1, A2, A3);
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
|
||||
const Matcher<A3>& m3) {
|
||||
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3));
|
||||
return this->current_spec();
|
||||
}
|
||||
|
||||
R Invoke(A1 a1, A2 a2, A3 a3) {
|
||||
// Even though gcc and MSVC don't enforce it, 'this->' is required
|
||||
// by the C++ standard [14.6.4] here, as the base class type is
|
||||
// dependent on the template argument (and thus shouldn't be
|
||||
// looked into when resolving InvokeWith).
|
||||
return this->InvokeWith(ArgumentTuple(a1, a2, a3));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4>
|
||||
class FunctionMocker<R(A1, A2, A3, A4)> : public
|
||||
internal::FunctionMockerBase<R(A1, A2, A3, A4)> {
|
||||
public:
|
||||
typedef R F(A1, A2, A3, A4);
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
|
||||
const Matcher<A3>& m3, const Matcher<A4>& m4) {
|
||||
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4));
|
||||
return this->current_spec();
|
||||
}
|
||||
|
||||
R Invoke(A1 a1, A2 a2, A3 a3, A4 a4) {
|
||||
// Even though gcc and MSVC don't enforce it, 'this->' is required
|
||||
// by the C++ standard [14.6.4] here, as the base class type is
|
||||
// dependent on the template argument (and thus shouldn't be
|
||||
// looked into when resolving InvokeWith).
|
||||
return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
typename A5>
|
||||
class FunctionMocker<R(A1, A2, A3, A4, A5)> : public
|
||||
internal::FunctionMockerBase<R(A1, A2, A3, A4, A5)> {
|
||||
public:
|
||||
typedef R F(A1, A2, A3, A4, A5);
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
|
||||
const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5) {
|
||||
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4,
|
||||
m5));
|
||||
return this->current_spec();
|
||||
}
|
||||
|
||||
R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) {
|
||||
// Even though gcc and MSVC don't enforce it, 'this->' is required
|
||||
// by the C++ standard [14.6.4] here, as the base class type is
|
||||
// dependent on the template argument (and thus shouldn't be
|
||||
// looked into when resolving InvokeWith).
|
||||
return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
typename A5, typename A6>
|
||||
class FunctionMocker<R(A1, A2, A3, A4, A5, A6)> : public
|
||||
internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6)> {
|
||||
public:
|
||||
typedef R F(A1, A2, A3, A4, A5, A6);
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
|
||||
const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5,
|
||||
const Matcher<A6>& m6) {
|
||||
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4, m5,
|
||||
m6));
|
||||
return this->current_spec();
|
||||
}
|
||||
|
||||
R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) {
|
||||
// Even though gcc and MSVC don't enforce it, 'this->' is required
|
||||
// by the C++ standard [14.6.4] here, as the base class type is
|
||||
// dependent on the template argument (and thus shouldn't be
|
||||
// looked into when resolving InvokeWith).
|
||||
return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
typename A5, typename A6, typename A7>
|
||||
class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7)> : public
|
||||
internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6, A7)> {
|
||||
public:
|
||||
typedef R F(A1, A2, A3, A4, A5, A6, A7);
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
|
||||
const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5,
|
||||
const Matcher<A6>& m6, const Matcher<A7>& m7) {
|
||||
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4, m5,
|
||||
m6, m7));
|
||||
return this->current_spec();
|
||||
}
|
||||
|
||||
R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) {
|
||||
// Even though gcc and MSVC don't enforce it, 'this->' is required
|
||||
// by the C++ standard [14.6.4] here, as the base class type is
|
||||
// dependent on the template argument (and thus shouldn't be
|
||||
// looked into when resolving InvokeWith).
|
||||
return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6, a7));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
typename A5, typename A6, typename A7, typename A8>
|
||||
class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7, A8)> : public
|
||||
internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6, A7, A8)> {
|
||||
public:
|
||||
typedef R F(A1, A2, A3, A4, A5, A6, A7, A8);
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
|
||||
const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5,
|
||||
const Matcher<A6>& m6, const Matcher<A7>& m7, const Matcher<A8>& m8) {
|
||||
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4, m5,
|
||||
m6, m7, m8));
|
||||
return this->current_spec();
|
||||
}
|
||||
|
||||
R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) {
|
||||
// Even though gcc and MSVC don't enforce it, 'this->' is required
|
||||
// by the C++ standard [14.6.4] here, as the base class type is
|
||||
// dependent on the template argument (and thus shouldn't be
|
||||
// looked into when resolving InvokeWith).
|
||||
return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6, a7, a8));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
typename A5, typename A6, typename A7, typename A8, typename A9>
|
||||
class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)> : public
|
||||
internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)> {
|
||||
public:
|
||||
typedef R F(A1, A2, A3, A4, A5, A6, A7, A8, A9);
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
|
||||
const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5,
|
||||
const Matcher<A6>& m6, const Matcher<A7>& m7, const Matcher<A8>& m8,
|
||||
const Matcher<A9>& m9) {
|
||||
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4, m5,
|
||||
m6, m7, m8, m9));
|
||||
return this->current_spec();
|
||||
}
|
||||
|
||||
R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) {
|
||||
// Even though gcc and MSVC don't enforce it, 'this->' is required
|
||||
// by the C++ standard [14.6.4] here, as the base class type is
|
||||
// dependent on the template argument (and thus shouldn't be
|
||||
// looked into when resolving InvokeWith).
|
||||
return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6, a7, a8, a9));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
typename A5, typename A6, typename A7, typename A8, typename A9,
|
||||
typename A10>
|
||||
class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)> : public
|
||||
internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)> {
|
||||
public:
|
||||
typedef R F(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10);
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
|
||||
const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5,
|
||||
const Matcher<A6>& m6, const Matcher<A7>& m7, const Matcher<A8>& m8,
|
||||
const Matcher<A9>& m9, const Matcher<A10>& m10) {
|
||||
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4, m5,
|
||||
m6, m7, m8, m9, m10));
|
||||
return this->current_spec();
|
||||
}
|
||||
|
||||
R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9,
|
||||
A10 a10) {
|
||||
// Even though gcc and MSVC don't enforce it, 'this->' is required
|
||||
// by the C++ standard [14.6.4] here, as the base class type is
|
||||
// dependent on the template argument (and thus shouldn't be
|
||||
// looked into when resolving InvokeWith).
|
||||
return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6, a7, a8, a9,
|
||||
a10));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// The style guide prohibits "using" statements in a namespace scope
|
||||
// inside a header file. However, the FunctionMocker class template
|
||||
// is meant to be defined in the ::testing namespace. The following
|
||||
// line is just a trick for working around a bug in MSVC 8.0, which
|
||||
// cannot handle it if we define FunctionMocker in ::testing.
|
||||
using internal::FunctionMocker;
|
||||
|
||||
// GMOCK_RESULT_(tn, F) expands to the result type of function type F.
|
||||
// We define this as a variadic macro in case F contains unprotected
|
||||
// commas (the same reason that we use variadic macros in other places
|
||||
// in this file).
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_RESULT_(tn, ...) \
|
||||
tn ::testing::internal::Function<__VA_ARGS__>::Result
|
||||
|
||||
// The type of argument N of the given function type.
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_ARG_(tn, N, ...) \
|
||||
tn ::testing::internal::Function<__VA_ARGS__>::Argument##N
|
||||
|
||||
// The matcher type for argument N of the given function type.
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_MATCHER_(tn, N, ...) \
|
||||
const ::testing::Matcher<GMOCK_ARG_(tn, N, __VA_ARGS__)>&
|
||||
|
||||
// The variable for mocking the given method.
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_MOCKER_(arity, constness, Method) \
|
||||
GTEST_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__)
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_METHOD0_(tn, constness, ct, Method, ...) \
|
||||
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
|
||||
) constness { \
|
||||
GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
|
||||
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
|
||||
== 0), \
|
||||
this_method_does_not_take_0_arguments); \
|
||||
GMOCK_MOCKER_(0, constness, Method).SetOwnerAndName(this, #Method); \
|
||||
return GMOCK_MOCKER_(0, constness, Method).Invoke(); \
|
||||
} \
|
||||
::testing::MockSpec<__VA_ARGS__>& \
|
||||
gmock_##Method() constness { \
|
||||
GMOCK_MOCKER_(0, constness, Method).RegisterOwner(this); \
|
||||
return GMOCK_MOCKER_(0, constness, Method).With(); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(0, constness, \
|
||||
Method)
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_METHOD1_(tn, constness, ct, Method, ...) \
|
||||
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
|
||||
GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1) constness { \
|
||||
GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
|
||||
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
|
||||
== 1), \
|
||||
this_method_does_not_take_1_argument); \
|
||||
GMOCK_MOCKER_(1, constness, Method).SetOwnerAndName(this, #Method); \
|
||||
return GMOCK_MOCKER_(1, constness, Method).Invoke(gmock_a1); \
|
||||
} \
|
||||
::testing::MockSpec<__VA_ARGS__>& \
|
||||
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1) constness { \
|
||||
GMOCK_MOCKER_(1, constness, Method).RegisterOwner(this); \
|
||||
return GMOCK_MOCKER_(1, constness, Method).With(gmock_a1); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(1, constness, \
|
||||
Method)
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_METHOD2_(tn, constness, ct, Method, ...) \
|
||||
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
|
||||
GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
|
||||
GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2) constness { \
|
||||
GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
|
||||
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
|
||||
== 2), \
|
||||
this_method_does_not_take_2_arguments); \
|
||||
GMOCK_MOCKER_(2, constness, Method).SetOwnerAndName(this, #Method); \
|
||||
return GMOCK_MOCKER_(2, constness, Method).Invoke(gmock_a1, gmock_a2); \
|
||||
} \
|
||||
::testing::MockSpec<__VA_ARGS__>& \
|
||||
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
|
||||
GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2) constness { \
|
||||
GMOCK_MOCKER_(2, constness, Method).RegisterOwner(this); \
|
||||
return GMOCK_MOCKER_(2, constness, Method).With(gmock_a1, gmock_a2); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(2, constness, \
|
||||
Method)
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_METHOD3_(tn, constness, ct, Method, ...) \
|
||||
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
|
||||
GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
|
||||
GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
|
||||
GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3) constness { \
|
||||
GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
|
||||
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
|
||||
== 3), \
|
||||
this_method_does_not_take_3_arguments); \
|
||||
GMOCK_MOCKER_(3, constness, Method).SetOwnerAndName(this, #Method); \
|
||||
return GMOCK_MOCKER_(3, constness, Method).Invoke(gmock_a1, gmock_a2, \
|
||||
gmock_a3); \
|
||||
} \
|
||||
::testing::MockSpec<__VA_ARGS__>& \
|
||||
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
|
||||
GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
|
||||
GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3) constness { \
|
||||
GMOCK_MOCKER_(3, constness, Method).RegisterOwner(this); \
|
||||
return GMOCK_MOCKER_(3, constness, Method).With(gmock_a1, gmock_a2, \
|
||||
gmock_a3); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(3, constness, \
|
||||
Method)
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_METHOD4_(tn, constness, ct, Method, ...) \
|
||||
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
|
||||
GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
|
||||
GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
|
||||
GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
|
||||
GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4) constness { \
|
||||
GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
|
||||
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
|
||||
== 4), \
|
||||
this_method_does_not_take_4_arguments); \
|
||||
GMOCK_MOCKER_(4, constness, Method).SetOwnerAndName(this, #Method); \
|
||||
return GMOCK_MOCKER_(4, constness, Method).Invoke(gmock_a1, gmock_a2, \
|
||||
gmock_a3, gmock_a4); \
|
||||
} \
|
||||
::testing::MockSpec<__VA_ARGS__>& \
|
||||
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
|
||||
GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
|
||||
GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
|
||||
GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4) constness { \
|
||||
GMOCK_MOCKER_(4, constness, Method).RegisterOwner(this); \
|
||||
return GMOCK_MOCKER_(4, constness, Method).With(gmock_a1, gmock_a2, \
|
||||
gmock_a3, gmock_a4); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(4, constness, \
|
||||
Method)
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_METHOD5_(tn, constness, ct, Method, ...) \
|
||||
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
|
||||
GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
|
||||
GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
|
||||
GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
|
||||
GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \
|
||||
GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5) constness { \
|
||||
GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
|
||||
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
|
||||
== 5), \
|
||||
this_method_does_not_take_5_arguments); \
|
||||
GMOCK_MOCKER_(5, constness, Method).SetOwnerAndName(this, #Method); \
|
||||
return GMOCK_MOCKER_(5, constness, Method).Invoke(gmock_a1, gmock_a2, \
|
||||
gmock_a3, gmock_a4, gmock_a5); \
|
||||
} \
|
||||
::testing::MockSpec<__VA_ARGS__>& \
|
||||
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
|
||||
GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
|
||||
GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
|
||||
GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \
|
||||
GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5) constness { \
|
||||
GMOCK_MOCKER_(5, constness, Method).RegisterOwner(this); \
|
||||
return GMOCK_MOCKER_(5, constness, Method).With(gmock_a1, gmock_a2, \
|
||||
gmock_a3, gmock_a4, gmock_a5); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(5, constness, \
|
||||
Method)
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_METHOD6_(tn, constness, ct, Method, ...) \
|
||||
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
|
||||
GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
|
||||
GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
|
||||
GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
|
||||
GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \
|
||||
GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5, \
|
||||
GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6) constness { \
|
||||
GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
|
||||
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
|
||||
== 6), \
|
||||
this_method_does_not_take_6_arguments); \
|
||||
GMOCK_MOCKER_(6, constness, Method).SetOwnerAndName(this, #Method); \
|
||||
return GMOCK_MOCKER_(6, constness, Method).Invoke(gmock_a1, gmock_a2, \
|
||||
gmock_a3, gmock_a4, gmock_a5, gmock_a6); \
|
||||
} \
|
||||
::testing::MockSpec<__VA_ARGS__>& \
|
||||
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
|
||||
GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
|
||||
GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
|
||||
GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \
|
||||
GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \
|
||||
GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6) constness { \
|
||||
GMOCK_MOCKER_(6, constness, Method).RegisterOwner(this); \
|
||||
return GMOCK_MOCKER_(6, constness, Method).With(gmock_a1, gmock_a2, \
|
||||
gmock_a3, gmock_a4, gmock_a5, gmock_a6); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(6, constness, \
|
||||
Method)
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_METHOD7_(tn, constness, ct, Method, ...) \
|
||||
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
|
||||
GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
|
||||
GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
|
||||
GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
|
||||
GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \
|
||||
GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5, \
|
||||
GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \
|
||||
GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7) constness { \
|
||||
GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
|
||||
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
|
||||
== 7), \
|
||||
this_method_does_not_take_7_arguments); \
|
||||
GMOCK_MOCKER_(7, constness, Method).SetOwnerAndName(this, #Method); \
|
||||
return GMOCK_MOCKER_(7, constness, Method).Invoke(gmock_a1, gmock_a2, \
|
||||
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7); \
|
||||
} \
|
||||
::testing::MockSpec<__VA_ARGS__>& \
|
||||
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
|
||||
GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
|
||||
GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
|
||||
GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \
|
||||
GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \
|
||||
GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \
|
||||
GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7) constness { \
|
||||
GMOCK_MOCKER_(7, constness, Method).RegisterOwner(this); \
|
||||
return GMOCK_MOCKER_(7, constness, Method).With(gmock_a1, gmock_a2, \
|
||||
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(7, constness, \
|
||||
Method)
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_METHOD8_(tn, constness, ct, Method, ...) \
|
||||
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
|
||||
GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
|
||||
GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
|
||||
GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
|
||||
GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \
|
||||
GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5, \
|
||||
GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \
|
||||
GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7, \
|
||||
GMOCK_ARG_(tn, 8, __VA_ARGS__) gmock_a8) constness { \
|
||||
GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
|
||||
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
|
||||
== 8), \
|
||||
this_method_does_not_take_8_arguments); \
|
||||
GMOCK_MOCKER_(8, constness, Method).SetOwnerAndName(this, #Method); \
|
||||
return GMOCK_MOCKER_(8, constness, Method).Invoke(gmock_a1, gmock_a2, \
|
||||
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8); \
|
||||
} \
|
||||
::testing::MockSpec<__VA_ARGS__>& \
|
||||
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
|
||||
GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
|
||||
GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
|
||||
GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \
|
||||
GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \
|
||||
GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \
|
||||
GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7, \
|
||||
GMOCK_MATCHER_(tn, 8, __VA_ARGS__) gmock_a8) constness { \
|
||||
GMOCK_MOCKER_(8, constness, Method).RegisterOwner(this); \
|
||||
return GMOCK_MOCKER_(8, constness, Method).With(gmock_a1, gmock_a2, \
|
||||
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(8, constness, \
|
||||
Method)
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_METHOD9_(tn, constness, ct, Method, ...) \
|
||||
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
|
||||
GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
|
||||
GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
|
||||
GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
|
||||
GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \
|
||||
GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5, \
|
||||
GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \
|
||||
GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7, \
|
||||
GMOCK_ARG_(tn, 8, __VA_ARGS__) gmock_a8, \
|
||||
GMOCK_ARG_(tn, 9, __VA_ARGS__) gmock_a9) constness { \
|
||||
GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
|
||||
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
|
||||
== 9), \
|
||||
this_method_does_not_take_9_arguments); \
|
||||
GMOCK_MOCKER_(9, constness, Method).SetOwnerAndName(this, #Method); \
|
||||
return GMOCK_MOCKER_(9, constness, Method).Invoke(gmock_a1, gmock_a2, \
|
||||
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, \
|
||||
gmock_a9); \
|
||||
} \
|
||||
::testing::MockSpec<__VA_ARGS__>& \
|
||||
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
|
||||
GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
|
||||
GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
|
||||
GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \
|
||||
GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \
|
||||
GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \
|
||||
GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7, \
|
||||
GMOCK_MATCHER_(tn, 8, __VA_ARGS__) gmock_a8, \
|
||||
GMOCK_MATCHER_(tn, 9, __VA_ARGS__) gmock_a9) constness { \
|
||||
GMOCK_MOCKER_(9, constness, Method).RegisterOwner(this); \
|
||||
return GMOCK_MOCKER_(9, constness, Method).With(gmock_a1, gmock_a2, \
|
||||
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, \
|
||||
gmock_a9); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(9, constness, \
|
||||
Method)
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_METHOD10_(tn, constness, ct, Method, ...) \
|
||||
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
|
||||
GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
|
||||
GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
|
||||
GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
|
||||
GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \
|
||||
GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5, \
|
||||
GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \
|
||||
GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7, \
|
||||
GMOCK_ARG_(tn, 8, __VA_ARGS__) gmock_a8, \
|
||||
GMOCK_ARG_(tn, 9, __VA_ARGS__) gmock_a9, \
|
||||
GMOCK_ARG_(tn, 10, __VA_ARGS__) gmock_a10) constness { \
|
||||
GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
|
||||
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
|
||||
== 10), \
|
||||
this_method_does_not_take_10_arguments); \
|
||||
GMOCK_MOCKER_(10, constness, Method).SetOwnerAndName(this, #Method); \
|
||||
return GMOCK_MOCKER_(10, constness, Method).Invoke(gmock_a1, gmock_a2, \
|
||||
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, gmock_a9, \
|
||||
gmock_a10); \
|
||||
} \
|
||||
::testing::MockSpec<__VA_ARGS__>& \
|
||||
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
|
||||
GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
|
||||
GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
|
||||
GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \
|
||||
GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \
|
||||
GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \
|
||||
GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7, \
|
||||
GMOCK_MATCHER_(tn, 8, __VA_ARGS__) gmock_a8, \
|
||||
GMOCK_MATCHER_(tn, 9, __VA_ARGS__) gmock_a9, \
|
||||
GMOCK_MATCHER_(tn, 10, \
|
||||
__VA_ARGS__) gmock_a10) constness { \
|
||||
GMOCK_MOCKER_(10, constness, Method).RegisterOwner(this); \
|
||||
return GMOCK_MOCKER_(10, constness, Method).With(gmock_a1, gmock_a2, \
|
||||
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, gmock_a9, \
|
||||
gmock_a10); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(10, constness, \
|
||||
Method)
|
||||
|
||||
#define MOCK_METHOD0(m, ...) GMOCK_METHOD0_(, , , m, __VA_ARGS__)
|
||||
#define MOCK_METHOD1(m, ...) GMOCK_METHOD1_(, , , m, __VA_ARGS__)
|
||||
#define MOCK_METHOD2(m, ...) GMOCK_METHOD2_(, , , m, __VA_ARGS__)
|
||||
#define MOCK_METHOD3(m, ...) GMOCK_METHOD3_(, , , m, __VA_ARGS__)
|
||||
#define MOCK_METHOD4(m, ...) GMOCK_METHOD4_(, , , m, __VA_ARGS__)
|
||||
#define MOCK_METHOD5(m, ...) GMOCK_METHOD5_(, , , m, __VA_ARGS__)
|
||||
#define MOCK_METHOD6(m, ...) GMOCK_METHOD6_(, , , m, __VA_ARGS__)
|
||||
#define MOCK_METHOD7(m, ...) GMOCK_METHOD7_(, , , m, __VA_ARGS__)
|
||||
#define MOCK_METHOD8(m, ...) GMOCK_METHOD8_(, , , m, __VA_ARGS__)
|
||||
#define MOCK_METHOD9(m, ...) GMOCK_METHOD9_(, , , m, __VA_ARGS__)
|
||||
#define MOCK_METHOD10(m, ...) GMOCK_METHOD10_(, , , m, __VA_ARGS__)
|
||||
|
||||
#define MOCK_CONST_METHOD0(m, ...) GMOCK_METHOD0_(, const, , m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD1(m, ...) GMOCK_METHOD1_(, const, , m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD2(m, ...) GMOCK_METHOD2_(, const, , m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD3(m, ...) GMOCK_METHOD3_(, const, , m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD4(m, ...) GMOCK_METHOD4_(, const, , m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD5(m, ...) GMOCK_METHOD5_(, const, , m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD6(m, ...) GMOCK_METHOD6_(, const, , m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD7(m, ...) GMOCK_METHOD7_(, const, , m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD8(m, ...) GMOCK_METHOD8_(, const, , m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD9(m, ...) GMOCK_METHOD9_(, const, , m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD10(m, ...) GMOCK_METHOD10_(, const, , m, __VA_ARGS__)
|
||||
|
||||
#define MOCK_METHOD0_T(m, ...) GMOCK_METHOD0_(typename, , , m, __VA_ARGS__)
|
||||
#define MOCK_METHOD1_T(m, ...) GMOCK_METHOD1_(typename, , , m, __VA_ARGS__)
|
||||
#define MOCK_METHOD2_T(m, ...) GMOCK_METHOD2_(typename, , , m, __VA_ARGS__)
|
||||
#define MOCK_METHOD3_T(m, ...) GMOCK_METHOD3_(typename, , , m, __VA_ARGS__)
|
||||
#define MOCK_METHOD4_T(m, ...) GMOCK_METHOD4_(typename, , , m, __VA_ARGS__)
|
||||
#define MOCK_METHOD5_T(m, ...) GMOCK_METHOD5_(typename, , , m, __VA_ARGS__)
|
||||
#define MOCK_METHOD6_T(m, ...) GMOCK_METHOD6_(typename, , , m, __VA_ARGS__)
|
||||
#define MOCK_METHOD7_T(m, ...) GMOCK_METHOD7_(typename, , , m, __VA_ARGS__)
|
||||
#define MOCK_METHOD8_T(m, ...) GMOCK_METHOD8_(typename, , , m, __VA_ARGS__)
|
||||
#define MOCK_METHOD9_T(m, ...) GMOCK_METHOD9_(typename, , , m, __VA_ARGS__)
|
||||
#define MOCK_METHOD10_T(m, ...) GMOCK_METHOD10_(typename, , , m, __VA_ARGS__)
|
||||
|
||||
#define MOCK_CONST_METHOD0_T(m, ...) \
|
||||
GMOCK_METHOD0_(typename, const, , m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD1_T(m, ...) \
|
||||
GMOCK_METHOD1_(typename, const, , m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD2_T(m, ...) \
|
||||
GMOCK_METHOD2_(typename, const, , m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD3_T(m, ...) \
|
||||
GMOCK_METHOD3_(typename, const, , m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD4_T(m, ...) \
|
||||
GMOCK_METHOD4_(typename, const, , m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD5_T(m, ...) \
|
||||
GMOCK_METHOD5_(typename, const, , m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD6_T(m, ...) \
|
||||
GMOCK_METHOD6_(typename, const, , m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD7_T(m, ...) \
|
||||
GMOCK_METHOD7_(typename, const, , m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD8_T(m, ...) \
|
||||
GMOCK_METHOD8_(typename, const, , m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD9_T(m, ...) \
|
||||
GMOCK_METHOD9_(typename, const, , m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD10_T(m, ...) \
|
||||
GMOCK_METHOD10_(typename, const, , m, __VA_ARGS__)
|
||||
|
||||
#define MOCK_METHOD0_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD0_(, , ct, m, __VA_ARGS__)
|
||||
#define MOCK_METHOD1_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD1_(, , ct, m, __VA_ARGS__)
|
||||
#define MOCK_METHOD2_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD2_(, , ct, m, __VA_ARGS__)
|
||||
#define MOCK_METHOD3_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD3_(, , ct, m, __VA_ARGS__)
|
||||
#define MOCK_METHOD4_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD4_(, , ct, m, __VA_ARGS__)
|
||||
#define MOCK_METHOD5_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD5_(, , ct, m, __VA_ARGS__)
|
||||
#define MOCK_METHOD6_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD6_(, , ct, m, __VA_ARGS__)
|
||||
#define MOCK_METHOD7_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD7_(, , ct, m, __VA_ARGS__)
|
||||
#define MOCK_METHOD8_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD8_(, , ct, m, __VA_ARGS__)
|
||||
#define MOCK_METHOD9_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD9_(, , ct, m, __VA_ARGS__)
|
||||
#define MOCK_METHOD10_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD10_(, , ct, m, __VA_ARGS__)
|
||||
|
||||
#define MOCK_CONST_METHOD0_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD0_(, const, ct, m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD1_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD1_(, const, ct, m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD2_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD2_(, const, ct, m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD3_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD3_(, const, ct, m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD4_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD4_(, const, ct, m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD5_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD5_(, const, ct, m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD6_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD6_(, const, ct, m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD7_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD7_(, const, ct, m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD8_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD8_(, const, ct, m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD9_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD9_(, const, ct, m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD10_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD10_(, const, ct, m, __VA_ARGS__)
|
||||
|
||||
#define MOCK_METHOD0_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD0_(typename, , ct, m, __VA_ARGS__)
|
||||
#define MOCK_METHOD1_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD1_(typename, , ct, m, __VA_ARGS__)
|
||||
#define MOCK_METHOD2_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD2_(typename, , ct, m, __VA_ARGS__)
|
||||
#define MOCK_METHOD3_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD3_(typename, , ct, m, __VA_ARGS__)
|
||||
#define MOCK_METHOD4_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD4_(typename, , ct, m, __VA_ARGS__)
|
||||
#define MOCK_METHOD5_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD5_(typename, , ct, m, __VA_ARGS__)
|
||||
#define MOCK_METHOD6_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD6_(typename, , ct, m, __VA_ARGS__)
|
||||
#define MOCK_METHOD7_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD7_(typename, , ct, m, __VA_ARGS__)
|
||||
#define MOCK_METHOD8_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD8_(typename, , ct, m, __VA_ARGS__)
|
||||
#define MOCK_METHOD9_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD9_(typename, , ct, m, __VA_ARGS__)
|
||||
#define MOCK_METHOD10_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD10_(typename, , ct, m, __VA_ARGS__)
|
||||
|
||||
#define MOCK_CONST_METHOD0_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD0_(typename, const, ct, m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD1_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD1_(typename, const, ct, m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD2_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD2_(typename, const, ct, m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD3_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD3_(typename, const, ct, m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD4_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD4_(typename, const, ct, m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD5_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD5_(typename, const, ct, m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD6_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD6_(typename, const, ct, m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD7_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD7_(typename, const, ct, m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD8_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD8_(typename, const, ct, m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD9_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD9_(typename, const, ct, m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD10_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD10_(typename, const, ct, m, __VA_ARGS__)
|
||||
|
||||
// A MockFunction<F> class has one mock method whose type is F. It is
|
||||
// useful when you just want your test code to emit some messages and
|
||||
// have Google Mock verify the right messages are sent (and perhaps at
|
||||
// the right times). For example, if you are exercising code:
|
||||
//
|
||||
// Foo(1);
|
||||
// Foo(2);
|
||||
// Foo(3);
|
||||
//
|
||||
// and want to verify that Foo(1) and Foo(3) both invoke
|
||||
// mock.Bar("a"), but Foo(2) doesn't invoke anything, you can write:
|
||||
//
|
||||
// TEST(FooTest, InvokesBarCorrectly) {
|
||||
// MyMock mock;
|
||||
// MockFunction<void(string check_point_name)> check;
|
||||
// {
|
||||
// InSequence s;
|
||||
//
|
||||
// EXPECT_CALL(mock, Bar("a"));
|
||||
// EXPECT_CALL(check, Call("1"));
|
||||
// EXPECT_CALL(check, Call("2"));
|
||||
// EXPECT_CALL(mock, Bar("a"));
|
||||
// }
|
||||
// Foo(1);
|
||||
// check.Call("1");
|
||||
// Foo(2);
|
||||
// check.Call("2");
|
||||
// Foo(3);
|
||||
// }
|
||||
//
|
||||
// The expectation spec says that the first Bar("a") must happen
|
||||
// before check point "1", the second Bar("a") must happen after check
|
||||
// point "2", and nothing should happen between the two check
|
||||
// points. The explicit check points make it easy to tell which
|
||||
// Bar("a") is called by which call to Foo().
|
||||
template <typename F>
|
||||
class MockFunction;
|
||||
|
||||
template <typename R>
|
||||
class MockFunction<R()> {
|
||||
public:
|
||||
MockFunction() {}
|
||||
|
||||
MOCK_METHOD0_T(Call, R());
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
|
||||
};
|
||||
|
||||
template <typename R, typename A0>
|
||||
class MockFunction<R(A0)> {
|
||||
public:
|
||||
MockFunction() {}
|
||||
|
||||
MOCK_METHOD1_T(Call, R(A0));
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
|
||||
};
|
||||
|
||||
template <typename R, typename A0, typename A1>
|
||||
class MockFunction<R(A0, A1)> {
|
||||
public:
|
||||
MockFunction() {}
|
||||
|
||||
MOCK_METHOD2_T(Call, R(A0, A1));
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
|
||||
};
|
||||
|
||||
template <typename R, typename A0, typename A1, typename A2>
|
||||
class MockFunction<R(A0, A1, A2)> {
|
||||
public:
|
||||
MockFunction() {}
|
||||
|
||||
MOCK_METHOD3_T(Call, R(A0, A1, A2));
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
|
||||
};
|
||||
|
||||
template <typename R, typename A0, typename A1, typename A2, typename A3>
|
||||
class MockFunction<R(A0, A1, A2, A3)> {
|
||||
public:
|
||||
MockFunction() {}
|
||||
|
||||
MOCK_METHOD4_T(Call, R(A0, A1, A2, A3));
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
|
||||
};
|
||||
|
||||
template <typename R, typename A0, typename A1, typename A2, typename A3,
|
||||
typename A4>
|
||||
class MockFunction<R(A0, A1, A2, A3, A4)> {
|
||||
public:
|
||||
MockFunction() {}
|
||||
|
||||
MOCK_METHOD5_T(Call, R(A0, A1, A2, A3, A4));
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
|
||||
};
|
||||
|
||||
template <typename R, typename A0, typename A1, typename A2, typename A3,
|
||||
typename A4, typename A5>
|
||||
class MockFunction<R(A0, A1, A2, A3, A4, A5)> {
|
||||
public:
|
||||
MockFunction() {}
|
||||
|
||||
MOCK_METHOD6_T(Call, R(A0, A1, A2, A3, A4, A5));
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
|
||||
};
|
||||
|
||||
template <typename R, typename A0, typename A1, typename A2, typename A3,
|
||||
typename A4, typename A5, typename A6>
|
||||
class MockFunction<R(A0, A1, A2, A3, A4, A5, A6)> {
|
||||
public:
|
||||
MockFunction() {}
|
||||
|
||||
MOCK_METHOD7_T(Call, R(A0, A1, A2, A3, A4, A5, A6));
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
|
||||
};
|
||||
|
||||
template <typename R, typename A0, typename A1, typename A2, typename A3,
|
||||
typename A4, typename A5, typename A6, typename A7>
|
||||
class MockFunction<R(A0, A1, A2, A3, A4, A5, A6, A7)> {
|
||||
public:
|
||||
MockFunction() {}
|
||||
|
||||
MOCK_METHOD8_T(Call, R(A0, A1, A2, A3, A4, A5, A6, A7));
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
|
||||
};
|
||||
|
||||
template <typename R, typename A0, typename A1, typename A2, typename A3,
|
||||
typename A4, typename A5, typename A6, typename A7, typename A8>
|
||||
class MockFunction<R(A0, A1, A2, A3, A4, A5, A6, A7, A8)> {
|
||||
public:
|
||||
MockFunction() {}
|
||||
|
||||
MOCK_METHOD9_T(Call, R(A0, A1, A2, A3, A4, A5, A6, A7, A8));
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
|
||||
};
|
||||
|
||||
template <typename R, typename A0, typename A1, typename A2, typename A3,
|
||||
typename A4, typename A5, typename A6, typename A7, typename A8,
|
||||
typename A9>
|
||||
class MockFunction<R(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9)> {
|
||||
public:
|
||||
MockFunction() {}
|
||||
|
||||
MOCK_METHOD10_T(Call, R(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9));
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
|
||||
};
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
|
||||
265
gmock/include/gmock/gmock-generated-function-mockers.h.pump
Normal file
265
gmock/include/gmock/gmock-generated-function-mockers.h.pump
Normal file
@@ -0,0 +1,265 @@
|
||||
$$ -*- mode: c++; -*-
|
||||
$$ This is a Pump source file. Please use Pump to convert it to
|
||||
$$ gmock-generated-function-mockers.h.
|
||||
$$
|
||||
$var n = 10 $$ The maximum arity we support.
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file implements function mockers of various arities.
|
||||
|
||||
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
|
||||
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
|
||||
|
||||
#include "gmock/gmock-spec-builders.h"
|
||||
#include "gmock/internal/gmock-internal-utils.h"
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
template <typename F>
|
||||
class FunctionMockerBase;
|
||||
|
||||
// Note: class FunctionMocker really belongs to the ::testing
|
||||
// namespace. However if we define it in ::testing, MSVC will
|
||||
// complain when classes in ::testing::internal declare it as a
|
||||
// friend class template. To workaround this compiler bug, we define
|
||||
// FunctionMocker in ::testing::internal and import it into ::testing.
|
||||
template <typename F>
|
||||
class FunctionMocker;
|
||||
|
||||
|
||||
$range i 0..n
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
$var typename_As = [[$for j [[, typename A$j]]]]
|
||||
$var As = [[$for j, [[A$j]]]]
|
||||
$var as = [[$for j, [[a$j]]]]
|
||||
$var Aas = [[$for j, [[A$j a$j]]]]
|
||||
$var ms = [[$for j, [[m$j]]]]
|
||||
$var matchers = [[$for j, [[const Matcher<A$j>& m$j]]]]
|
||||
template <typename R$typename_As>
|
||||
class FunctionMocker<R($As)> : public
|
||||
internal::FunctionMockerBase<R($As)> {
|
||||
public:
|
||||
typedef R F($As);
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F>& With($matchers) {
|
||||
|
||||
$if i >= 1 [[
|
||||
this->current_spec().SetMatchers(::std::tr1::make_tuple($ms));
|
||||
|
||||
]]
|
||||
return this->current_spec();
|
||||
}
|
||||
|
||||
R Invoke($Aas) {
|
||||
// Even though gcc and MSVC don't enforce it, 'this->' is required
|
||||
// by the C++ standard [14.6.4] here, as the base class type is
|
||||
// dependent on the template argument (and thus shouldn't be
|
||||
// looked into when resolving InvokeWith).
|
||||
return this->InvokeWith(ArgumentTuple($as));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
]]
|
||||
} // namespace internal
|
||||
|
||||
// The style guide prohibits "using" statements in a namespace scope
|
||||
// inside a header file. However, the FunctionMocker class template
|
||||
// is meant to be defined in the ::testing namespace. The following
|
||||
// line is just a trick for working around a bug in MSVC 8.0, which
|
||||
// cannot handle it if we define FunctionMocker in ::testing.
|
||||
using internal::FunctionMocker;
|
||||
|
||||
// GMOCK_RESULT_(tn, F) expands to the result type of function type F.
|
||||
// We define this as a variadic macro in case F contains unprotected
|
||||
// commas (the same reason that we use variadic macros in other places
|
||||
// in this file).
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_RESULT_(tn, ...) \
|
||||
tn ::testing::internal::Function<__VA_ARGS__>::Result
|
||||
|
||||
// The type of argument N of the given function type.
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_ARG_(tn, N, ...) \
|
||||
tn ::testing::internal::Function<__VA_ARGS__>::Argument##N
|
||||
|
||||
// The matcher type for argument N of the given function type.
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_MATCHER_(tn, N, ...) \
|
||||
const ::testing::Matcher<GMOCK_ARG_(tn, N, __VA_ARGS__)>&
|
||||
|
||||
// The variable for mocking the given method.
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_MOCKER_(arity, constness, Method) \
|
||||
GTEST_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__)
|
||||
|
||||
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
$var arg_as = [[$for j, \
|
||||
[[GMOCK_ARG_(tn, $j, __VA_ARGS__) gmock_a$j]]]]
|
||||
$var as = [[$for j, [[gmock_a$j]]]]
|
||||
$var matcher_as = [[$for j, \
|
||||
[[GMOCK_MATCHER_(tn, $j, __VA_ARGS__) gmock_a$j]]]]
|
||||
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||
#define GMOCK_METHOD$i[[]]_(tn, constness, ct, Method, ...) \
|
||||
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
|
||||
$arg_as) constness { \
|
||||
GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
|
||||
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value == $i), \
|
||||
this_method_does_not_take_$i[[]]_argument[[$if i != 1 [[s]]]]); \
|
||||
GMOCK_MOCKER_($i, constness, Method).SetOwnerAndName(this, #Method); \
|
||||
return GMOCK_MOCKER_($i, constness, Method).Invoke($as); \
|
||||
} \
|
||||
::testing::MockSpec<__VA_ARGS__>& \
|
||||
gmock_##Method($matcher_as) constness { \
|
||||
GMOCK_MOCKER_($i, constness, Method).RegisterOwner(this); \
|
||||
return GMOCK_MOCKER_($i, constness, Method).With($as); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_($i, constness, Method)
|
||||
|
||||
|
||||
]]
|
||||
$for i [[
|
||||
#define MOCK_METHOD$i(m, ...) GMOCK_METHOD$i[[]]_(, , , m, __VA_ARGS__)
|
||||
|
||||
]]
|
||||
|
||||
|
||||
$for i [[
|
||||
#define MOCK_CONST_METHOD$i(m, ...) GMOCK_METHOD$i[[]]_(, const, , m, __VA_ARGS__)
|
||||
|
||||
]]
|
||||
|
||||
|
||||
$for i [[
|
||||
#define MOCK_METHOD$i[[]]_T(m, ...) GMOCK_METHOD$i[[]]_(typename, , , m, __VA_ARGS__)
|
||||
|
||||
]]
|
||||
|
||||
|
||||
$for i [[
|
||||
#define MOCK_CONST_METHOD$i[[]]_T(m, ...) \
|
||||
GMOCK_METHOD$i[[]]_(typename, const, , m, __VA_ARGS__)
|
||||
|
||||
]]
|
||||
|
||||
|
||||
$for i [[
|
||||
#define MOCK_METHOD$i[[]]_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD$i[[]]_(, , ct, m, __VA_ARGS__)
|
||||
|
||||
]]
|
||||
|
||||
|
||||
$for i [[
|
||||
#define MOCK_CONST_METHOD$i[[]]_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD$i[[]]_(, const, ct, m, __VA_ARGS__)
|
||||
|
||||
]]
|
||||
|
||||
|
||||
$for i [[
|
||||
#define MOCK_METHOD$i[[]]_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD$i[[]]_(typename, , ct, m, __VA_ARGS__)
|
||||
|
||||
]]
|
||||
|
||||
|
||||
$for i [[
|
||||
#define MOCK_CONST_METHOD$i[[]]_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD$i[[]]_(typename, const, ct, m, __VA_ARGS__)
|
||||
|
||||
]]
|
||||
|
||||
// A MockFunction<F> class has one mock method whose type is F. It is
|
||||
// useful when you just want your test code to emit some messages and
|
||||
// have Google Mock verify the right messages are sent (and perhaps at
|
||||
// the right times). For example, if you are exercising code:
|
||||
//
|
||||
// Foo(1);
|
||||
// Foo(2);
|
||||
// Foo(3);
|
||||
//
|
||||
// and want to verify that Foo(1) and Foo(3) both invoke
|
||||
// mock.Bar("a"), but Foo(2) doesn't invoke anything, you can write:
|
||||
//
|
||||
// TEST(FooTest, InvokesBarCorrectly) {
|
||||
// MyMock mock;
|
||||
// MockFunction<void(string check_point_name)> check;
|
||||
// {
|
||||
// InSequence s;
|
||||
//
|
||||
// EXPECT_CALL(mock, Bar("a"));
|
||||
// EXPECT_CALL(check, Call("1"));
|
||||
// EXPECT_CALL(check, Call("2"));
|
||||
// EXPECT_CALL(mock, Bar("a"));
|
||||
// }
|
||||
// Foo(1);
|
||||
// check.Call("1");
|
||||
// Foo(2);
|
||||
// check.Call("2");
|
||||
// Foo(3);
|
||||
// }
|
||||
//
|
||||
// The expectation spec says that the first Bar("a") must happen
|
||||
// before check point "1", the second Bar("a") must happen after check
|
||||
// point "2", and nothing should happen between the two check
|
||||
// points. The explicit check points make it easy to tell which
|
||||
// Bar("a") is called by which call to Foo().
|
||||
template <typename F>
|
||||
class MockFunction;
|
||||
|
||||
|
||||
$for i [[
|
||||
$range j 0..i-1
|
||||
template <typename R$for j [[, typename A$j]]>
|
||||
class MockFunction<R($for j, [[A$j]])> {
|
||||
public:
|
||||
MockFunction() {}
|
||||
|
||||
MOCK_METHOD$i[[]]_T(Call, R($for j, [[A$j]]));
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
|
||||
};
|
||||
|
||||
|
||||
]]
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
|
||||
2190
gmock/include/gmock/gmock-generated-matchers.h
Normal file
2190
gmock/include/gmock/gmock-generated-matchers.h
Normal file
File diff suppressed because it is too large
Load Diff
674
gmock/include/gmock/gmock-generated-matchers.h.pump
Normal file
674
gmock/include/gmock/gmock-generated-matchers.h.pump
Normal file
@@ -0,0 +1,674 @@
|
||||
$$ -*- mode: c++; -*-
|
||||
$$ This is a Pump source file. Please use Pump to convert it to
|
||||
$$ gmock-generated-actions.h.
|
||||
$$
|
||||
$var n = 10 $$ The maximum arity we support.
|
||||
$$ }} This line fixes auto-indentation of the following code in Emacs.
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file implements some commonly used variadic matchers.
|
||||
|
||||
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_
|
||||
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_
|
||||
|
||||
#include <iterator>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "gmock/gmock-matchers.h"
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
$range i 0..n-1
|
||||
|
||||
// The type of the i-th (0-based) field of Tuple.
|
||||
#define GMOCK_FIELD_TYPE_(Tuple, i) \
|
||||
typename ::std::tr1::tuple_element<i, Tuple>::type
|
||||
|
||||
// TupleFields<Tuple, k0, ..., kn> is for selecting fields from a
|
||||
// tuple of type Tuple. It has two members:
|
||||
//
|
||||
// type: a tuple type whose i-th field is the ki-th field of Tuple.
|
||||
// GetSelectedFields(t): returns fields k0, ..., and kn of t as a tuple.
|
||||
//
|
||||
// For example, in class TupleFields<tuple<bool, char, int>, 2, 0>, we have:
|
||||
//
|
||||
// type is tuple<int, bool>, and
|
||||
// GetSelectedFields(make_tuple(true, 'a', 42)) is (42, true).
|
||||
|
||||
template <class Tuple$for i [[, int k$i = -1]]>
|
||||
class TupleFields;
|
||||
|
||||
// This generic version is used when there are $n selectors.
|
||||
template <class Tuple$for i [[, int k$i]]>
|
||||
class TupleFields {
|
||||
public:
|
||||
typedef ::std::tr1::tuple<$for i, [[GMOCK_FIELD_TYPE_(Tuple, k$i)]]> type;
|
||||
static type GetSelectedFields(const Tuple& t) {
|
||||
using ::std::tr1::get;
|
||||
return type($for i, [[get<k$i>(t)]]);
|
||||
}
|
||||
};
|
||||
|
||||
// The following specialization is used for 0 ~ $(n-1) selectors.
|
||||
|
||||
$for i [[
|
||||
$$ }}}
|
||||
$range j 0..i-1
|
||||
$range k 0..n-1
|
||||
|
||||
template <class Tuple$for j [[, int k$j]]>
|
||||
class TupleFields<Tuple, $for k, [[$if k < i [[k$k]] $else [[-1]]]]> {
|
||||
public:
|
||||
typedef ::std::tr1::tuple<$for j, [[GMOCK_FIELD_TYPE_(Tuple, k$j)]]> type;
|
||||
static type GetSelectedFields(const Tuple& $if i==0 [[/* t */]] $else [[t]]) {
|
||||
using ::std::tr1::get;
|
||||
return type($for j, [[get<k$j>(t)]]);
|
||||
}
|
||||
};
|
||||
|
||||
]]
|
||||
|
||||
#undef GMOCK_FIELD_TYPE_
|
||||
|
||||
// Implements the Args() matcher.
|
||||
|
||||
$var ks = [[$for i, [[k$i]]]]
|
||||
template <class ArgsTuple$for i [[, int k$i = -1]]>
|
||||
class ArgsMatcherImpl : public MatcherInterface<ArgsTuple> {
|
||||
public:
|
||||
// ArgsTuple may have top-level const or reference modifiers.
|
||||
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(ArgsTuple) RawArgsTuple;
|
||||
typedef typename internal::TupleFields<RawArgsTuple, $ks>::type SelectedArgs;
|
||||
typedef Matcher<const SelectedArgs&> MonomorphicInnerMatcher;
|
||||
|
||||
template <typename InnerMatcher>
|
||||
explicit ArgsMatcherImpl(const InnerMatcher& inner_matcher)
|
||||
: inner_matcher_(SafeMatcherCast<const SelectedArgs&>(inner_matcher)) {}
|
||||
|
||||
virtual bool MatchAndExplain(ArgsTuple args,
|
||||
MatchResultListener* listener) const {
|
||||
const SelectedArgs& selected_args = GetSelectedArgs(args);
|
||||
if (!listener->IsInterested())
|
||||
return inner_matcher_.Matches(selected_args);
|
||||
|
||||
PrintIndices(listener->stream());
|
||||
*listener << "are " << PrintToString(selected_args);
|
||||
|
||||
StringMatchResultListener inner_listener;
|
||||
const bool match = inner_matcher_.MatchAndExplain(selected_args,
|
||||
&inner_listener);
|
||||
PrintIfNotEmpty(inner_listener.str(), listener->stream());
|
||||
return match;
|
||||
}
|
||||
|
||||
virtual void DescribeTo(::std::ostream* os) const {
|
||||
*os << "are a tuple ";
|
||||
PrintIndices(os);
|
||||
inner_matcher_.DescribeTo(os);
|
||||
}
|
||||
|
||||
virtual void DescribeNegationTo(::std::ostream* os) const {
|
||||
*os << "are a tuple ";
|
||||
PrintIndices(os);
|
||||
inner_matcher_.DescribeNegationTo(os);
|
||||
}
|
||||
|
||||
private:
|
||||
static SelectedArgs GetSelectedArgs(ArgsTuple args) {
|
||||
return TupleFields<RawArgsTuple, $ks>::GetSelectedFields(args);
|
||||
}
|
||||
|
||||
// Prints the indices of the selected fields.
|
||||
static void PrintIndices(::std::ostream* os) {
|
||||
*os << "whose fields (";
|
||||
const int indices[$n] = { $ks };
|
||||
for (int i = 0; i < $n; i++) {
|
||||
if (indices[i] < 0)
|
||||
break;
|
||||
|
||||
if (i >= 1)
|
||||
*os << ", ";
|
||||
|
||||
*os << "#" << indices[i];
|
||||
}
|
||||
*os << ") ";
|
||||
}
|
||||
|
||||
const MonomorphicInnerMatcher inner_matcher_;
|
||||
|
||||
GTEST_DISALLOW_ASSIGN_(ArgsMatcherImpl);
|
||||
};
|
||||
|
||||
template <class InnerMatcher$for i [[, int k$i = -1]]>
|
||||
class ArgsMatcher {
|
||||
public:
|
||||
explicit ArgsMatcher(const InnerMatcher& inner_matcher)
|
||||
: inner_matcher_(inner_matcher) {}
|
||||
|
||||
template <typename ArgsTuple>
|
||||
operator Matcher<ArgsTuple>() const {
|
||||
return MakeMatcher(new ArgsMatcherImpl<ArgsTuple, $ks>(inner_matcher_));
|
||||
}
|
||||
|
||||
private:
|
||||
const InnerMatcher inner_matcher_;
|
||||
|
||||
GTEST_DISALLOW_ASSIGN_(ArgsMatcher);
|
||||
};
|
||||
|
||||
// A set of metafunctions for computing the result type of AllOf.
|
||||
// AllOf(m1, ..., mN) returns
|
||||
// AllOfResultN<decltype(m1), ..., decltype(mN)>::type.
|
||||
|
||||
// Although AllOf isn't defined for one argument, AllOfResult1 is defined
|
||||
// to simplify the implementation.
|
||||
template <typename M1>
|
||||
struct AllOfResult1 {
|
||||
typedef M1 type;
|
||||
};
|
||||
|
||||
$range i 1..n
|
||||
|
||||
$range i 2..n
|
||||
$for i [[
|
||||
$range j 2..i
|
||||
$var m = i/2
|
||||
$range k 1..m
|
||||
$range t m+1..i
|
||||
|
||||
template <typename M1$for j [[, typename M$j]]>
|
||||
struct AllOfResult$i {
|
||||
typedef BothOfMatcher<
|
||||
typename AllOfResult$m<$for k, [[M$k]]>::type,
|
||||
typename AllOfResult$(i-m)<$for t, [[M$t]]>::type
|
||||
> type;
|
||||
};
|
||||
|
||||
]]
|
||||
|
||||
// A set of metafunctions for computing the result type of AnyOf.
|
||||
// AnyOf(m1, ..., mN) returns
|
||||
// AnyOfResultN<decltype(m1), ..., decltype(mN)>::type.
|
||||
|
||||
// Although AnyOf isn't defined for one argument, AnyOfResult1 is defined
|
||||
// to simplify the implementation.
|
||||
template <typename M1>
|
||||
struct AnyOfResult1 {
|
||||
typedef M1 type;
|
||||
};
|
||||
|
||||
$range i 1..n
|
||||
|
||||
$range i 2..n
|
||||
$for i [[
|
||||
$range j 2..i
|
||||
$var m = i/2
|
||||
$range k 1..m
|
||||
$range t m+1..i
|
||||
|
||||
template <typename M1$for j [[, typename M$j]]>
|
||||
struct AnyOfResult$i {
|
||||
typedef EitherOfMatcher<
|
||||
typename AnyOfResult$m<$for k, [[M$k]]>::type,
|
||||
typename AnyOfResult$(i-m)<$for t, [[M$t]]>::type
|
||||
> type;
|
||||
};
|
||||
|
||||
]]
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// Args<N1, N2, ..., Nk>(a_matcher) matches a tuple if the selected
|
||||
// fields of it matches a_matcher. C++ doesn't support default
|
||||
// arguments for function templates, so we have to overload it.
|
||||
|
||||
$range i 0..n
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
template <$for j [[int k$j, ]]typename InnerMatcher>
|
||||
inline internal::ArgsMatcher<InnerMatcher$for j [[, k$j]]>
|
||||
Args(const InnerMatcher& matcher) {
|
||||
return internal::ArgsMatcher<InnerMatcher$for j [[, k$j]]>(matcher);
|
||||
}
|
||||
|
||||
|
||||
]]
|
||||
// ElementsAre(e_1, e_2, ... e_n) matches an STL-style container with
|
||||
// n elements, where the i-th element in the container must
|
||||
// match the i-th argument in the list. Each argument of
|
||||
// ElementsAre() can be either a value or a matcher. We support up to
|
||||
// $n arguments.
|
||||
//
|
||||
// The use of DecayArray in the implementation allows ElementsAre()
|
||||
// to accept string literals, whose type is const char[N], but we
|
||||
// want to treat them as const char*.
|
||||
//
|
||||
// NOTE: Since ElementsAre() cares about the order of the elements, it
|
||||
// must not be used with containers whose elements's order is
|
||||
// undefined (e.g. hash_map).
|
||||
|
||||
$range i 0..n
|
||||
$for i [[
|
||||
|
||||
$range j 1..i
|
||||
|
||||
$if i>0 [[
|
||||
|
||||
template <$for j, [[typename T$j]]>
|
||||
]]
|
||||
|
||||
inline internal::ElementsAreMatcher<
|
||||
std::tr1::tuple<
|
||||
$for j, [[
|
||||
|
||||
typename internal::DecayArray<T$j[[]]>::type]]> >
|
||||
ElementsAre($for j, [[const T$j& e$j]]) {
|
||||
typedef std::tr1::tuple<
|
||||
$for j, [[
|
||||
|
||||
typename internal::DecayArray<T$j[[]]>::type]]> Args;
|
||||
return internal::ElementsAreMatcher<Args>(Args($for j, [[e$j]]));
|
||||
}
|
||||
|
||||
]]
|
||||
|
||||
// UnorderedElementsAre(e_1, e_2, ..., e_n) is an ElementsAre extension
|
||||
// that matches n elements in any order. We support up to n=$n arguments.
|
||||
|
||||
$range i 0..n
|
||||
$for i [[
|
||||
|
||||
$range j 1..i
|
||||
|
||||
$if i>0 [[
|
||||
|
||||
template <$for j, [[typename T$j]]>
|
||||
]]
|
||||
|
||||
inline internal::UnorderedElementsAreMatcher<
|
||||
std::tr1::tuple<
|
||||
$for j, [[
|
||||
|
||||
typename internal::DecayArray<T$j[[]]>::type]]> >
|
||||
UnorderedElementsAre($for j, [[const T$j& e$j]]) {
|
||||
typedef std::tr1::tuple<
|
||||
$for j, [[
|
||||
|
||||
typename internal::DecayArray<T$j[[]]>::type]]> Args;
|
||||
return internal::UnorderedElementsAreMatcher<Args>(Args($for j, [[e$j]]));
|
||||
}
|
||||
|
||||
]]
|
||||
|
||||
// AllOf(m1, m2, ..., mk) matches any value that matches all of the given
|
||||
// sub-matchers. AllOf is called fully qualified to prevent ADL from firing.
|
||||
|
||||
$range i 2..n
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
$var m = i/2
|
||||
$range k 1..m
|
||||
$range t m+1..i
|
||||
|
||||
template <$for j, [[typename M$j]]>
|
||||
inline typename internal::AllOfResult$i<$for j, [[M$j]]>::type
|
||||
AllOf($for j, [[M$j m$j]]) {
|
||||
return typename internal::AllOfResult$i<$for j, [[M$j]]>::type(
|
||||
$if m == 1 [[m1]] $else [[::testing::AllOf($for k, [[m$k]])]],
|
||||
$if m+1 == i [[m$i]] $else [[::testing::AllOf($for t, [[m$t]])]]);
|
||||
}
|
||||
|
||||
]]
|
||||
|
||||
// AnyOf(m1, m2, ..., mk) matches any value that matches any of the given
|
||||
// sub-matchers. AnyOf is called fully qualified to prevent ADL from firing.
|
||||
|
||||
$range i 2..n
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
$var m = i/2
|
||||
$range k 1..m
|
||||
$range t m+1..i
|
||||
|
||||
template <$for j, [[typename M$j]]>
|
||||
inline typename internal::AnyOfResult$i<$for j, [[M$j]]>::type
|
||||
AnyOf($for j, [[M$j m$j]]) {
|
||||
return typename internal::AnyOfResult$i<$for j, [[M$j]]>::type(
|
||||
$if m == 1 [[m1]] $else [[::testing::AnyOf($for k, [[m$k]])]],
|
||||
$if m+1 == i [[m$i]] $else [[::testing::AnyOf($for t, [[m$t]])]]);
|
||||
}
|
||||
|
||||
]]
|
||||
|
||||
} // namespace testing
|
||||
$$ } // This Pump meta comment fixes auto-indentation in Emacs. It will not
|
||||
$$ // show up in the generated code.
|
||||
|
||||
|
||||
// The MATCHER* family of macros can be used in a namespace scope to
|
||||
// define custom matchers easily.
|
||||
//
|
||||
// Basic Usage
|
||||
// ===========
|
||||
//
|
||||
// The syntax
|
||||
//
|
||||
// MATCHER(name, description_string) { statements; }
|
||||
//
|
||||
// defines a matcher with the given name that executes the statements,
|
||||
// which must return a bool to indicate if the match succeeds. Inside
|
||||
// the statements, you can refer to the value being matched by 'arg',
|
||||
// and refer to its type by 'arg_type'.
|
||||
//
|
||||
// The description string documents what the matcher does, and is used
|
||||
// to generate the failure message when the match fails. Since a
|
||||
// MATCHER() is usually defined in a header file shared by multiple
|
||||
// C++ source files, we require the description to be a C-string
|
||||
// literal to avoid possible side effects. It can be empty, in which
|
||||
// case we'll use the sequence of words in the matcher name as the
|
||||
// description.
|
||||
//
|
||||
// For example:
|
||||
//
|
||||
// MATCHER(IsEven, "") { return (arg % 2) == 0; }
|
||||
//
|
||||
// allows you to write
|
||||
//
|
||||
// // Expects mock_foo.Bar(n) to be called where n is even.
|
||||
// EXPECT_CALL(mock_foo, Bar(IsEven()));
|
||||
//
|
||||
// or,
|
||||
//
|
||||
// // Verifies that the value of some_expression is even.
|
||||
// EXPECT_THAT(some_expression, IsEven());
|
||||
//
|
||||
// If the above assertion fails, it will print something like:
|
||||
//
|
||||
// Value of: some_expression
|
||||
// Expected: is even
|
||||
// Actual: 7
|
||||
//
|
||||
// where the description "is even" is automatically calculated from the
|
||||
// matcher name IsEven.
|
||||
//
|
||||
// Argument Type
|
||||
// =============
|
||||
//
|
||||
// Note that the type of the value being matched (arg_type) is
|
||||
// determined by the context in which you use the matcher and is
|
||||
// supplied to you by the compiler, so you don't need to worry about
|
||||
// declaring it (nor can you). This allows the matcher to be
|
||||
// polymorphic. For example, IsEven() can be used to match any type
|
||||
// where the value of "(arg % 2) == 0" can be implicitly converted to
|
||||
// a bool. In the "Bar(IsEven())" example above, if method Bar()
|
||||
// takes an int, 'arg_type' will be int; if it takes an unsigned long,
|
||||
// 'arg_type' will be unsigned long; and so on.
|
||||
//
|
||||
// Parameterizing Matchers
|
||||
// =======================
|
||||
//
|
||||
// Sometimes you'll want to parameterize the matcher. For that you
|
||||
// can use another macro:
|
||||
//
|
||||
// MATCHER_P(name, param_name, description_string) { statements; }
|
||||
//
|
||||
// For example:
|
||||
//
|
||||
// MATCHER_P(HasAbsoluteValue, value, "") { return abs(arg) == value; }
|
||||
//
|
||||
// will allow you to write:
|
||||
//
|
||||
// EXPECT_THAT(Blah("a"), HasAbsoluteValue(n));
|
||||
//
|
||||
// which may lead to this message (assuming n is 10):
|
||||
//
|
||||
// Value of: Blah("a")
|
||||
// Expected: has absolute value 10
|
||||
// Actual: -9
|
||||
//
|
||||
// Note that both the matcher description and its parameter are
|
||||
// printed, making the message human-friendly.
|
||||
//
|
||||
// In the matcher definition body, you can write 'foo_type' to
|
||||
// reference the type of a parameter named 'foo'. For example, in the
|
||||
// body of MATCHER_P(HasAbsoluteValue, value) above, you can write
|
||||
// 'value_type' to refer to the type of 'value'.
|
||||
//
|
||||
// We also provide MATCHER_P2, MATCHER_P3, ..., up to MATCHER_P$n to
|
||||
// support multi-parameter matchers.
|
||||
//
|
||||
// Describing Parameterized Matchers
|
||||
// =================================
|
||||
//
|
||||
// The last argument to MATCHER*() is a string-typed expression. The
|
||||
// expression can reference all of the matcher's parameters and a
|
||||
// special bool-typed variable named 'negation'. When 'negation' is
|
||||
// false, the expression should evaluate to the matcher's description;
|
||||
// otherwise it should evaluate to the description of the negation of
|
||||
// the matcher. For example,
|
||||
//
|
||||
// using testing::PrintToString;
|
||||
//
|
||||
// MATCHER_P2(InClosedRange, low, hi,
|
||||
// string(negation ? "is not" : "is") + " in range [" +
|
||||
// PrintToString(low) + ", " + PrintToString(hi) + "]") {
|
||||
// return low <= arg && arg <= hi;
|
||||
// }
|
||||
// ...
|
||||
// EXPECT_THAT(3, InClosedRange(4, 6));
|
||||
// EXPECT_THAT(3, Not(InClosedRange(2, 4)));
|
||||
//
|
||||
// would generate two failures that contain the text:
|
||||
//
|
||||
// Expected: is in range [4, 6]
|
||||
// ...
|
||||
// Expected: is not in range [2, 4]
|
||||
//
|
||||
// If you specify "" as the description, the failure message will
|
||||
// contain the sequence of words in the matcher name followed by the
|
||||
// parameter values printed as a tuple. For example,
|
||||
//
|
||||
// MATCHER_P2(InClosedRange, low, hi, "") { ... }
|
||||
// ...
|
||||
// EXPECT_THAT(3, InClosedRange(4, 6));
|
||||
// EXPECT_THAT(3, Not(InClosedRange(2, 4)));
|
||||
//
|
||||
// would generate two failures that contain the text:
|
||||
//
|
||||
// Expected: in closed range (4, 6)
|
||||
// ...
|
||||
// Expected: not (in closed range (2, 4))
|
||||
//
|
||||
// Types of Matcher Parameters
|
||||
// ===========================
|
||||
//
|
||||
// For the purpose of typing, you can view
|
||||
//
|
||||
// MATCHER_Pk(Foo, p1, ..., pk, description_string) { ... }
|
||||
//
|
||||
// as shorthand for
|
||||
//
|
||||
// template <typename p1_type, ..., typename pk_type>
|
||||
// FooMatcherPk<p1_type, ..., pk_type>
|
||||
// Foo(p1_type p1, ..., pk_type pk) { ... }
|
||||
//
|
||||
// When you write Foo(v1, ..., vk), the compiler infers the types of
|
||||
// the parameters v1, ..., and vk for you. If you are not happy with
|
||||
// the result of the type inference, you can specify the types by
|
||||
// explicitly instantiating the template, as in Foo<long, bool>(5,
|
||||
// false). As said earlier, you don't get to (or need to) specify
|
||||
// 'arg_type' as that's determined by the context in which the matcher
|
||||
// is used. You can assign the result of expression Foo(p1, ..., pk)
|
||||
// to a variable of type FooMatcherPk<p1_type, ..., pk_type>. This
|
||||
// can be useful when composing matchers.
|
||||
//
|
||||
// While you can instantiate a matcher template with reference types,
|
||||
// passing the parameters by pointer usually makes your code more
|
||||
// readable. If, however, you still want to pass a parameter by
|
||||
// reference, be aware that in the failure message generated by the
|
||||
// matcher you will see the value of the referenced object but not its
|
||||
// address.
|
||||
//
|
||||
// Explaining Match Results
|
||||
// ========================
|
||||
//
|
||||
// Sometimes the matcher description alone isn't enough to explain why
|
||||
// the match has failed or succeeded. For example, when expecting a
|
||||
// long string, it can be very helpful to also print the diff between
|
||||
// the expected string and the actual one. To achieve that, you can
|
||||
// optionally stream additional information to a special variable
|
||||
// named result_listener, whose type is a pointer to class
|
||||
// MatchResultListener:
|
||||
//
|
||||
// MATCHER_P(EqualsLongString, str, "") {
|
||||
// if (arg == str) return true;
|
||||
//
|
||||
// *result_listener << "the difference: "
|
||||
/// << DiffStrings(str, arg);
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// Overloading Matchers
|
||||
// ====================
|
||||
//
|
||||
// You can overload matchers with different numbers of parameters:
|
||||
//
|
||||
// MATCHER_P(Blah, a, description_string1) { ... }
|
||||
// MATCHER_P2(Blah, a, b, description_string2) { ... }
|
||||
//
|
||||
// Caveats
|
||||
// =======
|
||||
//
|
||||
// When defining a new matcher, you should also consider implementing
|
||||
// MatcherInterface or using MakePolymorphicMatcher(). These
|
||||
// approaches require more work than the MATCHER* macros, but also
|
||||
// give you more control on the types of the value being matched and
|
||||
// the matcher parameters, which may leads to better compiler error
|
||||
// messages when the matcher is used wrong. They also allow
|
||||
// overloading matchers based on parameter types (as opposed to just
|
||||
// based on the number of parameters).
|
||||
//
|
||||
// MATCHER*() can only be used in a namespace scope. The reason is
|
||||
// that C++ doesn't yet allow function-local types to be used to
|
||||
// instantiate templates. The up-coming C++0x standard will fix this.
|
||||
// Once that's done, we'll consider supporting using MATCHER*() inside
|
||||
// a function.
|
||||
//
|
||||
// More Information
|
||||
// ================
|
||||
//
|
||||
// To learn more about using these macros, please search for 'MATCHER'
|
||||
// on http://code.google.com/p/googlemock/wiki/CookBook.
|
||||
|
||||
$range i 0..n
|
||||
$for i
|
||||
|
||||
[[
|
||||
$var macro_name = [[$if i==0 [[MATCHER]] $elif i==1 [[MATCHER_P]]
|
||||
$else [[MATCHER_P$i]]]]
|
||||
$var class_name = [[name##Matcher[[$if i==0 [[]] $elif i==1 [[P]]
|
||||
$else [[P$i]]]]]]
|
||||
$range j 0..i-1
|
||||
$var template = [[$if i==0 [[]] $else [[
|
||||
|
||||
template <$for j, [[typename p$j##_type]]>\
|
||||
]]]]
|
||||
$var ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]]
|
||||
$var impl_ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]]
|
||||
$var impl_inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(gmock_p$j)]]]]]]
|
||||
$var inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(gmock_p$j)]]]]]]
|
||||
$var params = [[$for j, [[p$j]]]]
|
||||
$var param_types = [[$if i==0 [[]] $else [[<$for j, [[p$j##_type]]>]]]]
|
||||
$var param_types_and_names = [[$for j, [[p$j##_type p$j]]]]
|
||||
$var param_field_decls = [[$for j
|
||||
[[
|
||||
|
||||
p$j##_type p$j;\
|
||||
]]]]
|
||||
$var param_field_decls2 = [[$for j
|
||||
[[
|
||||
|
||||
p$j##_type p$j;\
|
||||
]]]]
|
||||
|
||||
#define $macro_name(name$for j [[, p$j]], description)\$template
|
||||
class $class_name {\
|
||||
public:\
|
||||
template <typename arg_type>\
|
||||
class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
|
||||
public:\
|
||||
[[$if i==1 [[explicit ]]]]gmock_Impl($impl_ctor_param_list)\
|
||||
$impl_inits {}\
|
||||
virtual bool MatchAndExplain(\
|
||||
arg_type arg, ::testing::MatchResultListener* result_listener) const;\
|
||||
virtual void DescribeTo(::std::ostream* gmock_os) const {\
|
||||
*gmock_os << FormatDescription(false);\
|
||||
}\
|
||||
virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
|
||||
*gmock_os << FormatDescription(true);\
|
||||
}\$param_field_decls
|
||||
private:\
|
||||
::testing::internal::string FormatDescription(bool negation) const {\
|
||||
const ::testing::internal::string gmock_description = (description);\
|
||||
if (!gmock_description.empty())\
|
||||
return gmock_description;\
|
||||
return ::testing::internal::FormatMatcherDescription(\
|
||||
negation, #name, \
|
||||
::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
|
||||
::std::tr1::tuple<$for j, [[p$j##_type]]>($for j, [[p$j]])));\
|
||||
}\
|
||||
GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
|
||||
};\
|
||||
template <typename arg_type>\
|
||||
operator ::testing::Matcher<arg_type>() const {\
|
||||
return ::testing::Matcher<arg_type>(\
|
||||
new gmock_Impl<arg_type>($params));\
|
||||
}\
|
||||
$class_name($ctor_param_list)$inits {\
|
||||
}\$param_field_decls2
|
||||
private:\
|
||||
GTEST_DISALLOW_ASSIGN_($class_name);\
|
||||
};\$template
|
||||
inline $class_name$param_types name($param_types_and_names) {\
|
||||
return $class_name$param_types($params);\
|
||||
}\$template
|
||||
template <typename arg_type>\
|
||||
bool $class_name$param_types::gmock_Impl<arg_type>::MatchAndExplain(\
|
||||
arg_type arg, \
|
||||
::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\
|
||||
const
|
||||
]]
|
||||
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_
|
||||
397
gmock/include/gmock/gmock-generated-nice-strict.h
Normal file
397
gmock/include/gmock/gmock-generated-nice-strict.h
Normal file
@@ -0,0 +1,397 @@
|
||||
// This file was GENERATED by command:
|
||||
// pump.py gmock-generated-nice-strict.h.pump
|
||||
// DO NOT EDIT BY HAND!!!
|
||||
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Implements class templates NiceMock, NaggyMock, and StrictMock.
|
||||
//
|
||||
// Given a mock class MockFoo that is created using Google Mock,
|
||||
// NiceMock<MockFoo> is a subclass of MockFoo that allows
|
||||
// uninteresting calls (i.e. calls to mock methods that have no
|
||||
// EXPECT_CALL specs), NaggyMock<MockFoo> is a subclass of MockFoo
|
||||
// that prints a warning when an uninteresting call occurs, and
|
||||
// StrictMock<MockFoo> is a subclass of MockFoo that treats all
|
||||
// uninteresting calls as errors.
|
||||
//
|
||||
// Currently a mock is naggy by default, so MockFoo and
|
||||
// NaggyMock<MockFoo> behave like the same. However, we will soon
|
||||
// switch the default behavior of mocks to be nice, as that in general
|
||||
// leads to more maintainable tests. When that happens, MockFoo will
|
||||
// stop behaving like NaggyMock<MockFoo> and start behaving like
|
||||
// NiceMock<MockFoo>.
|
||||
//
|
||||
// NiceMock, NaggyMock, and StrictMock "inherit" the constructors of
|
||||
// their respective base class, with up-to 10 arguments. Therefore
|
||||
// you can write NiceMock<MockFoo>(5, "a") to construct a nice mock
|
||||
// where MockFoo has a constructor that accepts (int, const char*),
|
||||
// for example.
|
||||
//
|
||||
// A known limitation is that NiceMock<MockFoo>, NaggyMock<MockFoo>,
|
||||
// and StrictMock<MockFoo> only works for mock methods defined using
|
||||
// the MOCK_METHOD* family of macros DIRECTLY in the MockFoo class.
|
||||
// If a mock method is defined in a base class of MockFoo, the "nice"
|
||||
// or "strict" modifier may not affect it, depending on the compiler.
|
||||
// In particular, nesting NiceMock, NaggyMock, and StrictMock is NOT
|
||||
// supported.
|
||||
//
|
||||
// Another known limitation is that the constructors of the base mock
|
||||
// cannot have arguments passed by non-const reference, which are
|
||||
// banned by the Google C++ style guide anyway.
|
||||
|
||||
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
|
||||
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
|
||||
|
||||
#include "gmock/gmock-spec-builders.h"
|
||||
#include "gmock/internal/gmock-port.h"
|
||||
|
||||
namespace testing {
|
||||
|
||||
template <class MockClass>
|
||||
class NiceMock : public MockClass {
|
||||
public:
|
||||
// We don't factor out the constructor body to a common method, as
|
||||
// we have to avoid a possible clash with members of MockClass.
|
||||
NiceMock() {
|
||||
::testing::Mock::AllowUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
// C++ doesn't (yet) allow inheritance of constructors, so we have
|
||||
// to define it for each arity.
|
||||
template <typename A1>
|
||||
explicit NiceMock(const A1& a1) : MockClass(a1) {
|
||||
::testing::Mock::AllowUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
template <typename A1, typename A2>
|
||||
NiceMock(const A1& a1, const A2& a2) : MockClass(a1, a2) {
|
||||
::testing::Mock::AllowUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3>
|
||||
NiceMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2, a3) {
|
||||
::testing::Mock::AllowUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4>
|
||||
NiceMock(const A1& a1, const A2& a2, const A3& a3,
|
||||
const A4& a4) : MockClass(a1, a2, a3, a4) {
|
||||
::testing::Mock::AllowUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5>
|
||||
NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||
const A5& a5) : MockClass(a1, a2, a3, a4, a5) {
|
||||
::testing::Mock::AllowUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6>
|
||||
NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||
const A5& a5, const A6& a6) : MockClass(a1, a2, a3, a4, a5, a6) {
|
||||
::testing::Mock::AllowUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7>
|
||||
NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||
const A5& a5, const A6& a6, const A7& a7) : MockClass(a1, a2, a3, a4, a5,
|
||||
a6, a7) {
|
||||
::testing::Mock::AllowUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7, typename A8>
|
||||
NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||
const A5& a5, const A6& a6, const A7& a7, const A8& a8) : MockClass(a1,
|
||||
a2, a3, a4, a5, a6, a7, a8) {
|
||||
::testing::Mock::AllowUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7, typename A8, typename A9>
|
||||
NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||
const A5& a5, const A6& a6, const A7& a7, const A8& a8,
|
||||
const A9& a9) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9) {
|
||||
::testing::Mock::AllowUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7, typename A8, typename A9, typename A10>
|
||||
NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||
const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9,
|
||||
const A10& a10) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {
|
||||
::testing::Mock::AllowUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
virtual ~NiceMock() {
|
||||
::testing::Mock::UnregisterCallReaction(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(NiceMock);
|
||||
};
|
||||
|
||||
template <class MockClass>
|
||||
class NaggyMock : public MockClass {
|
||||
public:
|
||||
// We don't factor out the constructor body to a common method, as
|
||||
// we have to avoid a possible clash with members of MockClass.
|
||||
NaggyMock() {
|
||||
::testing::Mock::WarnUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
// C++ doesn't (yet) allow inheritance of constructors, so we have
|
||||
// to define it for each arity.
|
||||
template <typename A1>
|
||||
explicit NaggyMock(const A1& a1) : MockClass(a1) {
|
||||
::testing::Mock::WarnUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
template <typename A1, typename A2>
|
||||
NaggyMock(const A1& a1, const A2& a2) : MockClass(a1, a2) {
|
||||
::testing::Mock::WarnUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3>
|
||||
NaggyMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2, a3) {
|
||||
::testing::Mock::WarnUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4>
|
||||
NaggyMock(const A1& a1, const A2& a2, const A3& a3,
|
||||
const A4& a4) : MockClass(a1, a2, a3, a4) {
|
||||
::testing::Mock::WarnUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5>
|
||||
NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||
const A5& a5) : MockClass(a1, a2, a3, a4, a5) {
|
||||
::testing::Mock::WarnUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6>
|
||||
NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||
const A5& a5, const A6& a6) : MockClass(a1, a2, a3, a4, a5, a6) {
|
||||
::testing::Mock::WarnUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7>
|
||||
NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||
const A5& a5, const A6& a6, const A7& a7) : MockClass(a1, a2, a3, a4, a5,
|
||||
a6, a7) {
|
||||
::testing::Mock::WarnUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7, typename A8>
|
||||
NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||
const A5& a5, const A6& a6, const A7& a7, const A8& a8) : MockClass(a1,
|
||||
a2, a3, a4, a5, a6, a7, a8) {
|
||||
::testing::Mock::WarnUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7, typename A8, typename A9>
|
||||
NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||
const A5& a5, const A6& a6, const A7& a7, const A8& a8,
|
||||
const A9& a9) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9) {
|
||||
::testing::Mock::WarnUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7, typename A8, typename A9, typename A10>
|
||||
NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||
const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9,
|
||||
const A10& a10) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {
|
||||
::testing::Mock::WarnUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
virtual ~NaggyMock() {
|
||||
::testing::Mock::UnregisterCallReaction(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(NaggyMock);
|
||||
};
|
||||
|
||||
template <class MockClass>
|
||||
class StrictMock : public MockClass {
|
||||
public:
|
||||
// We don't factor out the constructor body to a common method, as
|
||||
// we have to avoid a possible clash with members of MockClass.
|
||||
StrictMock() {
|
||||
::testing::Mock::FailUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
// C++ doesn't (yet) allow inheritance of constructors, so we have
|
||||
// to define it for each arity.
|
||||
template <typename A1>
|
||||
explicit StrictMock(const A1& a1) : MockClass(a1) {
|
||||
::testing::Mock::FailUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
template <typename A1, typename A2>
|
||||
StrictMock(const A1& a1, const A2& a2) : MockClass(a1, a2) {
|
||||
::testing::Mock::FailUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3>
|
||||
StrictMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2, a3) {
|
||||
::testing::Mock::FailUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4>
|
||||
StrictMock(const A1& a1, const A2& a2, const A3& a3,
|
||||
const A4& a4) : MockClass(a1, a2, a3, a4) {
|
||||
::testing::Mock::FailUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5>
|
||||
StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||
const A5& a5) : MockClass(a1, a2, a3, a4, a5) {
|
||||
::testing::Mock::FailUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6>
|
||||
StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||
const A5& a5, const A6& a6) : MockClass(a1, a2, a3, a4, a5, a6) {
|
||||
::testing::Mock::FailUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7>
|
||||
StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||
const A5& a5, const A6& a6, const A7& a7) : MockClass(a1, a2, a3, a4, a5,
|
||||
a6, a7) {
|
||||
::testing::Mock::FailUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7, typename A8>
|
||||
StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||
const A5& a5, const A6& a6, const A7& a7, const A8& a8) : MockClass(a1,
|
||||
a2, a3, a4, a5, a6, a7, a8) {
|
||||
::testing::Mock::FailUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7, typename A8, typename A9>
|
||||
StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||
const A5& a5, const A6& a6, const A7& a7, const A8& a8,
|
||||
const A9& a9) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9) {
|
||||
::testing::Mock::FailUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7, typename A8, typename A9, typename A10>
|
||||
StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||
const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9,
|
||||
const A10& a10) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {
|
||||
::testing::Mock::FailUninterestingCalls(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
virtual ~StrictMock() {
|
||||
::testing::Mock::UnregisterCallReaction(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(StrictMock);
|
||||
};
|
||||
|
||||
// The following specializations catch some (relatively more common)
|
||||
// user errors of nesting nice and strict mocks. They do NOT catch
|
||||
// all possible errors.
|
||||
|
||||
// These specializations are declared but not defined, as NiceMock,
|
||||
// NaggyMock, and StrictMock cannot be nested.
|
||||
|
||||
template <typename MockClass>
|
||||
class NiceMock<NiceMock<MockClass> >;
|
||||
template <typename MockClass>
|
||||
class NiceMock<NaggyMock<MockClass> >;
|
||||
template <typename MockClass>
|
||||
class NiceMock<StrictMock<MockClass> >;
|
||||
|
||||
template <typename MockClass>
|
||||
class NaggyMock<NiceMock<MockClass> >;
|
||||
template <typename MockClass>
|
||||
class NaggyMock<NaggyMock<MockClass> >;
|
||||
template <typename MockClass>
|
||||
class NaggyMock<StrictMock<MockClass> >;
|
||||
|
||||
template <typename MockClass>
|
||||
class StrictMock<NiceMock<MockClass> >;
|
||||
template <typename MockClass>
|
||||
class StrictMock<NaggyMock<MockClass> >;
|
||||
template <typename MockClass>
|
||||
class StrictMock<StrictMock<MockClass> >;
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
|
||||
161
gmock/include/gmock/gmock-generated-nice-strict.h.pump
Normal file
161
gmock/include/gmock/gmock-generated-nice-strict.h.pump
Normal file
@@ -0,0 +1,161 @@
|
||||
$$ -*- mode: c++; -*-
|
||||
$$ This is a Pump source file. Please use Pump to convert it to
|
||||
$$ gmock-generated-nice-strict.h.
|
||||
$$
|
||||
$var n = 10 $$ The maximum arity we support.
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Implements class templates NiceMock, NaggyMock, and StrictMock.
|
||||
//
|
||||
// Given a mock class MockFoo that is created using Google Mock,
|
||||
// NiceMock<MockFoo> is a subclass of MockFoo that allows
|
||||
// uninteresting calls (i.e. calls to mock methods that have no
|
||||
// EXPECT_CALL specs), NaggyMock<MockFoo> is a subclass of MockFoo
|
||||
// that prints a warning when an uninteresting call occurs, and
|
||||
// StrictMock<MockFoo> is a subclass of MockFoo that treats all
|
||||
// uninteresting calls as errors.
|
||||
//
|
||||
// Currently a mock is naggy by default, so MockFoo and
|
||||
// NaggyMock<MockFoo> behave like the same. However, we will soon
|
||||
// switch the default behavior of mocks to be nice, as that in general
|
||||
// leads to more maintainable tests. When that happens, MockFoo will
|
||||
// stop behaving like NaggyMock<MockFoo> and start behaving like
|
||||
// NiceMock<MockFoo>.
|
||||
//
|
||||
// NiceMock, NaggyMock, and StrictMock "inherit" the constructors of
|
||||
// their respective base class, with up-to $n arguments. Therefore
|
||||
// you can write NiceMock<MockFoo>(5, "a") to construct a nice mock
|
||||
// where MockFoo has a constructor that accepts (int, const char*),
|
||||
// for example.
|
||||
//
|
||||
// A known limitation is that NiceMock<MockFoo>, NaggyMock<MockFoo>,
|
||||
// and StrictMock<MockFoo> only works for mock methods defined using
|
||||
// the MOCK_METHOD* family of macros DIRECTLY in the MockFoo class.
|
||||
// If a mock method is defined in a base class of MockFoo, the "nice"
|
||||
// or "strict" modifier may not affect it, depending on the compiler.
|
||||
// In particular, nesting NiceMock, NaggyMock, and StrictMock is NOT
|
||||
// supported.
|
||||
//
|
||||
// Another known limitation is that the constructors of the base mock
|
||||
// cannot have arguments passed by non-const reference, which are
|
||||
// banned by the Google C++ style guide anyway.
|
||||
|
||||
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
|
||||
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
|
||||
|
||||
#include "gmock/gmock-spec-builders.h"
|
||||
#include "gmock/internal/gmock-port.h"
|
||||
|
||||
namespace testing {
|
||||
|
||||
$range kind 0..2
|
||||
$for kind [[
|
||||
|
||||
$var clazz=[[$if kind==0 [[NiceMock]]
|
||||
$elif kind==1 [[NaggyMock]]
|
||||
$else [[StrictMock]]]]
|
||||
|
||||
$var method=[[$if kind==0 [[AllowUninterestingCalls]]
|
||||
$elif kind==1 [[WarnUninterestingCalls]]
|
||||
$else [[FailUninterestingCalls]]]]
|
||||
|
||||
template <class MockClass>
|
||||
class $clazz : public MockClass {
|
||||
public:
|
||||
// We don't factor out the constructor body to a common method, as
|
||||
// we have to avoid a possible clash with members of MockClass.
|
||||
$clazz() {
|
||||
::testing::Mock::$method(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
// C++ doesn't (yet) allow inheritance of constructors, so we have
|
||||
// to define it for each arity.
|
||||
template <typename A1>
|
||||
explicit $clazz(const A1& a1) : MockClass(a1) {
|
||||
::testing::Mock::$method(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
$range i 2..n
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
template <$for j, [[typename A$j]]>
|
||||
$clazz($for j, [[const A$j& a$j]]) : MockClass($for j, [[a$j]]) {
|
||||
::testing::Mock::$method(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
|
||||
]]
|
||||
virtual ~$clazz() {
|
||||
::testing::Mock::UnregisterCallReaction(
|
||||
internal::ImplicitCast_<MockClass*>(this));
|
||||
}
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_($clazz);
|
||||
};
|
||||
|
||||
]]
|
||||
|
||||
// The following specializations catch some (relatively more common)
|
||||
// user errors of nesting nice and strict mocks. They do NOT catch
|
||||
// all possible errors.
|
||||
|
||||
// These specializations are declared but not defined, as NiceMock,
|
||||
// NaggyMock, and StrictMock cannot be nested.
|
||||
|
||||
template <typename MockClass>
|
||||
class NiceMock<NiceMock<MockClass> >;
|
||||
template <typename MockClass>
|
||||
class NiceMock<NaggyMock<MockClass> >;
|
||||
template <typename MockClass>
|
||||
class NiceMock<StrictMock<MockClass> >;
|
||||
|
||||
template <typename MockClass>
|
||||
class NaggyMock<NiceMock<MockClass> >;
|
||||
template <typename MockClass>
|
||||
class NaggyMock<NaggyMock<MockClass> >;
|
||||
template <typename MockClass>
|
||||
class NaggyMock<StrictMock<MockClass> >;
|
||||
|
||||
template <typename MockClass>
|
||||
class StrictMock<NiceMock<MockClass> >;
|
||||
template <typename MockClass>
|
||||
class StrictMock<NaggyMock<MockClass> >;
|
||||
template <typename MockClass>
|
||||
class StrictMock<StrictMock<MockClass> >;
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
|
||||
3986
gmock/include/gmock/gmock-matchers.h
Normal file
3986
gmock/include/gmock/gmock-matchers.h
Normal file
File diff suppressed because it is too large
Load Diff
233
gmock/include/gmock/gmock-more-actions.h
Normal file
233
gmock/include/gmock/gmock-more-actions.h
Normal file
@@ -0,0 +1,233 @@
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file implements some actions that depend on gmock-generated-actions.h.
|
||||
|
||||
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
|
||||
#define GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "gmock/gmock-generated-actions.h"
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// Implements the Invoke(f) action. The template argument
|
||||
// FunctionImpl is the implementation type of f, which can be either a
|
||||
// function pointer or a functor. Invoke(f) can be used as an
|
||||
// Action<F> as long as f's type is compatible with F (i.e. f can be
|
||||
// assigned to a tr1::function<F>).
|
||||
template <typename FunctionImpl>
|
||||
class InvokeAction {
|
||||
public:
|
||||
// The c'tor makes a copy of function_impl (either a function
|
||||
// pointer or a functor).
|
||||
explicit InvokeAction(FunctionImpl function_impl)
|
||||
: function_impl_(function_impl) {}
|
||||
|
||||
template <typename Result, typename ArgumentTuple>
|
||||
Result Perform(const ArgumentTuple& args) {
|
||||
return InvokeHelper<Result, ArgumentTuple>::Invoke(function_impl_, args);
|
||||
}
|
||||
|
||||
private:
|
||||
FunctionImpl function_impl_;
|
||||
|
||||
GTEST_DISALLOW_ASSIGN_(InvokeAction);
|
||||
};
|
||||
|
||||
// Implements the Invoke(object_ptr, &Class::Method) action.
|
||||
template <class Class, typename MethodPtr>
|
||||
class InvokeMethodAction {
|
||||
public:
|
||||
InvokeMethodAction(Class* obj_ptr, MethodPtr method_ptr)
|
||||
: obj_ptr_(obj_ptr), method_ptr_(method_ptr) {}
|
||||
|
||||
template <typename Result, typename ArgumentTuple>
|
||||
Result Perform(const ArgumentTuple& args) const {
|
||||
return InvokeHelper<Result, ArgumentTuple>::InvokeMethod(
|
||||
obj_ptr_, method_ptr_, args);
|
||||
}
|
||||
|
||||
private:
|
||||
Class* const obj_ptr_;
|
||||
const MethodPtr method_ptr_;
|
||||
|
||||
GTEST_DISALLOW_ASSIGN_(InvokeMethodAction);
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// Various overloads for Invoke().
|
||||
|
||||
// Creates an action that invokes 'function_impl' with the mock
|
||||
// function's arguments.
|
||||
template <typename FunctionImpl>
|
||||
PolymorphicAction<internal::InvokeAction<FunctionImpl> > Invoke(
|
||||
FunctionImpl function_impl) {
|
||||
return MakePolymorphicAction(
|
||||
internal::InvokeAction<FunctionImpl>(function_impl));
|
||||
}
|
||||
|
||||
// Creates an action that invokes the given method on the given object
|
||||
// with the mock function's arguments.
|
||||
template <class Class, typename MethodPtr>
|
||||
PolymorphicAction<internal::InvokeMethodAction<Class, MethodPtr> > Invoke(
|
||||
Class* obj_ptr, MethodPtr method_ptr) {
|
||||
return MakePolymorphicAction(
|
||||
internal::InvokeMethodAction<Class, MethodPtr>(obj_ptr, method_ptr));
|
||||
}
|
||||
|
||||
// WithoutArgs(inner_action) can be used in a mock function with a
|
||||
// non-empty argument list to perform inner_action, which takes no
|
||||
// argument. In other words, it adapts an action accepting no
|
||||
// argument to one that accepts (and ignores) arguments.
|
||||
template <typename InnerAction>
|
||||
inline internal::WithArgsAction<InnerAction>
|
||||
WithoutArgs(const InnerAction& action) {
|
||||
return internal::WithArgsAction<InnerAction>(action);
|
||||
}
|
||||
|
||||
// WithArg<k>(an_action) creates an action that passes the k-th
|
||||
// (0-based) argument of the mock function to an_action and performs
|
||||
// it. It adapts an action accepting one argument to one that accepts
|
||||
// multiple arguments. For convenience, we also provide
|
||||
// WithArgs<k>(an_action) (defined below) as a synonym.
|
||||
template <int k, typename InnerAction>
|
||||
inline internal::WithArgsAction<InnerAction, k>
|
||||
WithArg(const InnerAction& action) {
|
||||
return internal::WithArgsAction<InnerAction, k>(action);
|
||||
}
|
||||
|
||||
// The ACTION*() macros trigger warning C4100 (unreferenced formal
|
||||
// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in
|
||||
// the macro definition, as the warnings are generated when the macro
|
||||
// is expanded and macro expansion cannot contain #pragma. Therefore
|
||||
// we suppress them here.
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable:4100)
|
||||
#endif
|
||||
|
||||
// Action ReturnArg<k>() returns the k-th argument of the mock function.
|
||||
ACTION_TEMPLATE(ReturnArg,
|
||||
HAS_1_TEMPLATE_PARAMS(int, k),
|
||||
AND_0_VALUE_PARAMS()) {
|
||||
return std::tr1::get<k>(args);
|
||||
}
|
||||
|
||||
// Action SaveArg<k>(pointer) saves the k-th (0-based) argument of the
|
||||
// mock function to *pointer.
|
||||
ACTION_TEMPLATE(SaveArg,
|
||||
HAS_1_TEMPLATE_PARAMS(int, k),
|
||||
AND_1_VALUE_PARAMS(pointer)) {
|
||||
*pointer = ::std::tr1::get<k>(args);
|
||||
}
|
||||
|
||||
// Action SaveArgPointee<k>(pointer) saves the value pointed to
|
||||
// by the k-th (0-based) argument of the mock function to *pointer.
|
||||
ACTION_TEMPLATE(SaveArgPointee,
|
||||
HAS_1_TEMPLATE_PARAMS(int, k),
|
||||
AND_1_VALUE_PARAMS(pointer)) {
|
||||
*pointer = *::std::tr1::get<k>(args);
|
||||
}
|
||||
|
||||
// Action SetArgReferee<k>(value) assigns 'value' to the variable
|
||||
// referenced by the k-th (0-based) argument of the mock function.
|
||||
ACTION_TEMPLATE(SetArgReferee,
|
||||
HAS_1_TEMPLATE_PARAMS(int, k),
|
||||
AND_1_VALUE_PARAMS(value)) {
|
||||
typedef typename ::std::tr1::tuple_element<k, args_type>::type argk_type;
|
||||
// Ensures that argument #k is a reference. If you get a compiler
|
||||
// error on the next line, you are using SetArgReferee<k>(value) in
|
||||
// a mock function whose k-th (0-based) argument is not a reference.
|
||||
GTEST_COMPILE_ASSERT_(internal::is_reference<argk_type>::value,
|
||||
SetArgReferee_must_be_used_with_a_reference_argument);
|
||||
::std::tr1::get<k>(args) = value;
|
||||
}
|
||||
|
||||
// Action SetArrayArgument<k>(first, last) copies the elements in
|
||||
// source range [first, last) to the array pointed to by the k-th
|
||||
// (0-based) argument, which can be either a pointer or an
|
||||
// iterator. The action does not take ownership of the elements in the
|
||||
// source range.
|
||||
ACTION_TEMPLATE(SetArrayArgument,
|
||||
HAS_1_TEMPLATE_PARAMS(int, k),
|
||||
AND_2_VALUE_PARAMS(first, last)) {
|
||||
// Microsoft compiler deprecates ::std::copy, so we want to suppress warning
|
||||
// 4996 (Function call with parameters that may be unsafe) there.
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(push) // Saves the current warning state.
|
||||
# pragma warning(disable:4996) // Temporarily disables warning 4996.
|
||||
#endif
|
||||
::std::copy(first, last, ::std::tr1::get<k>(args));
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(pop) // Restores the warning state.
|
||||
#endif
|
||||
}
|
||||
|
||||
// Action DeleteArg<k>() deletes the k-th (0-based) argument of the mock
|
||||
// function.
|
||||
ACTION_TEMPLATE(DeleteArg,
|
||||
HAS_1_TEMPLATE_PARAMS(int, k),
|
||||
AND_0_VALUE_PARAMS()) {
|
||||
delete ::std::tr1::get<k>(args);
|
||||
}
|
||||
|
||||
// This action returns the value pointed to by 'pointer'.
|
||||
ACTION_P(ReturnPointee, pointer) { return *pointer; }
|
||||
|
||||
// Action Throw(exception) can be used in a mock function of any type
|
||||
// to throw the given exception. Any copyable value can be thrown.
|
||||
#if GTEST_HAS_EXCEPTIONS
|
||||
|
||||
// Suppresses the 'unreachable code' warning that VC generates in opt modes.
|
||||
# ifdef _MSC_VER
|
||||
# pragma warning(push) // Saves the current warning state.
|
||||
# pragma warning(disable:4702) // Temporarily disables warning 4702.
|
||||
# endif
|
||||
ACTION_P(Throw, exception) { throw exception; }
|
||||
# ifdef _MSC_VER
|
||||
# pragma warning(pop) // Restores the warning state.
|
||||
# endif
|
||||
|
||||
#endif // GTEST_HAS_EXCEPTIONS
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
|
||||
58
gmock/include/gmock/gmock-more-matchers.h
Normal file
58
gmock/include/gmock/gmock-more-matchers.h
Normal file
@@ -0,0 +1,58 @@
|
||||
// Copyright 2013, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: marcus.boerger@google.com (Marcus Boerger)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file implements some matchers that depend on gmock-generated-matchers.h.
|
||||
//
|
||||
// Note that tests are implemented in gmock-matchers_test.cc rather than
|
||||
// gmock-more-matchers-test.cc.
|
||||
|
||||
#ifndef GMOCK_GMOCK_MORE_MATCHERS_H_
|
||||
#define GMOCK_GMOCK_MORE_MATCHERS_H_
|
||||
|
||||
#include "gmock/gmock-generated-matchers.h"
|
||||
|
||||
namespace testing {
|
||||
|
||||
// Defines a matcher that matches an empty container. The container must
|
||||
// support both size() and empty(), which all STL-like containers provide.
|
||||
MATCHER(IsEmpty, negation ? "isn't empty" : "is empty") {
|
||||
if (arg.empty()) {
|
||||
return true;
|
||||
}
|
||||
*result_listener << "whose size is " << arg.size();
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_GMOCK_MORE_MATCHERS_H_
|
||||
1791
gmock/include/gmock/gmock-spec-builders.h
Normal file
1791
gmock/include/gmock/gmock-spec-builders.h
Normal file
File diff suppressed because it is too large
Load Diff
94
gmock/include/gmock/gmock.h
Normal file
94
gmock/include/gmock/gmock.h
Normal file
@@ -0,0 +1,94 @@
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This is the main header file a user should include.
|
||||
|
||||
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_H_
|
||||
#define GMOCK_INCLUDE_GMOCK_GMOCK_H_
|
||||
|
||||
// This file implements the following syntax:
|
||||
//
|
||||
// ON_CALL(mock_object.Method(...))
|
||||
// .With(...) ?
|
||||
// .WillByDefault(...);
|
||||
//
|
||||
// where With() is optional and WillByDefault() must appear exactly
|
||||
// once.
|
||||
//
|
||||
// EXPECT_CALL(mock_object.Method(...))
|
||||
// .With(...) ?
|
||||
// .Times(...) ?
|
||||
// .InSequence(...) *
|
||||
// .WillOnce(...) *
|
||||
// .WillRepeatedly(...) ?
|
||||
// .RetiresOnSaturation() ? ;
|
||||
//
|
||||
// where all clauses are optional and WillOnce() can be repeated.
|
||||
|
||||
#include "gmock/gmock-actions.h"
|
||||
#include "gmock/gmock-cardinalities.h"
|
||||
#include "gmock/gmock-generated-actions.h"
|
||||
#include "gmock/gmock-generated-function-mockers.h"
|
||||
#include "gmock/gmock-generated-nice-strict.h"
|
||||
#include "gmock/gmock-generated-matchers.h"
|
||||
#include "gmock/gmock-matchers.h"
|
||||
#include "gmock/gmock-more-actions.h"
|
||||
#include "gmock/gmock-more-matchers.h"
|
||||
#include "gmock/internal/gmock-internal-utils.h"
|
||||
|
||||
namespace testing {
|
||||
|
||||
// Declares Google Mock flags that we want a user to use programmatically.
|
||||
GMOCK_DECLARE_bool_(catch_leaked_mocks);
|
||||
GMOCK_DECLARE_string_(verbose);
|
||||
|
||||
// Initializes Google Mock. This must be called before running the
|
||||
// tests. In particular, it parses the command line for the flags
|
||||
// that Google Mock recognizes. Whenever a Google Mock flag is seen,
|
||||
// it is removed from argv, and *argc is decremented.
|
||||
//
|
||||
// No value is returned. Instead, the Google Mock flag variables are
|
||||
// updated.
|
||||
//
|
||||
// Since Google Test is needed for Google Mock to work, this function
|
||||
// also initializes Google Test and parses its flags, if that hasn't
|
||||
// been done.
|
||||
GTEST_API_ void InitGoogleMock(int* argc, char** argv);
|
||||
|
||||
// This overloaded version can be used in Windows programs compiled in
|
||||
// UNICODE mode.
|
||||
GTEST_API_ void InitGoogleMock(int* argc, wchar_t** argv);
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_H_
|
||||
279
gmock/include/gmock/internal/gmock-generated-internal-utils.h
Normal file
279
gmock/include/gmock/internal/gmock-generated-internal-utils.h
Normal file
@@ -0,0 +1,279 @@
|
||||
// This file was GENERATED by command:
|
||||
// pump.py gmock-generated-internal-utils.h.pump
|
||||
// DO NOT EDIT BY HAND!!!
|
||||
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file contains template meta-programming utility classes needed
|
||||
// for implementing Google Mock.
|
||||
|
||||
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
|
||||
#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
|
||||
|
||||
#include "gmock/internal/gmock-port.h"
|
||||
|
||||
namespace testing {
|
||||
|
||||
template <typename T>
|
||||
class Matcher;
|
||||
|
||||
namespace internal {
|
||||
|
||||
// An IgnoredValue object can be implicitly constructed from ANY value.
|
||||
// This is used in implementing the IgnoreResult(a) action.
|
||||
class IgnoredValue {
|
||||
public:
|
||||
// This constructor template allows any value to be implicitly
|
||||
// converted to IgnoredValue. The object has no data member and
|
||||
// doesn't try to remember anything about the argument. We
|
||||
// deliberately omit the 'explicit' keyword in order to allow the
|
||||
// conversion to be implicit.
|
||||
template <typename T>
|
||||
IgnoredValue(const T& /* ignored */) {} // NOLINT(runtime/explicit)
|
||||
};
|
||||
|
||||
// MatcherTuple<T>::type is a tuple type where each field is a Matcher
|
||||
// for the corresponding field in tuple type T.
|
||||
template <typename Tuple>
|
||||
struct MatcherTuple;
|
||||
|
||||
template <>
|
||||
struct MatcherTuple< ::std::tr1::tuple<> > {
|
||||
typedef ::std::tr1::tuple< > type;
|
||||
};
|
||||
|
||||
template <typename A1>
|
||||
struct MatcherTuple< ::std::tr1::tuple<A1> > {
|
||||
typedef ::std::tr1::tuple<Matcher<A1> > type;
|
||||
};
|
||||
|
||||
template <typename A1, typename A2>
|
||||
struct MatcherTuple< ::std::tr1::tuple<A1, A2> > {
|
||||
typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2> > type;
|
||||
};
|
||||
|
||||
template <typename A1, typename A2, typename A3>
|
||||
struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3> > {
|
||||
typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3> > type;
|
||||
};
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4>
|
||||
struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4> > {
|
||||
typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>,
|
||||
Matcher<A4> > type;
|
||||
};
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5>
|
||||
struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4, A5> > {
|
||||
typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
|
||||
Matcher<A5> > type;
|
||||
};
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6>
|
||||
struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4, A5, A6> > {
|
||||
typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
|
||||
Matcher<A5>, Matcher<A6> > type;
|
||||
};
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7>
|
||||
struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7> > {
|
||||
typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
|
||||
Matcher<A5>, Matcher<A6>, Matcher<A7> > type;
|
||||
};
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7, typename A8>
|
||||
struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8> > {
|
||||
typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
|
||||
Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8> > type;
|
||||
};
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7, typename A8, typename A9>
|
||||
struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9> > {
|
||||
typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
|
||||
Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8>, Matcher<A9> > type;
|
||||
};
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||
typename A6, typename A7, typename A8, typename A9, typename A10>
|
||||
struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9,
|
||||
A10> > {
|
||||
typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
|
||||
Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8>, Matcher<A9>,
|
||||
Matcher<A10> > type;
|
||||
};
|
||||
|
||||
// Template struct Function<F>, where F must be a function type, contains
|
||||
// the following typedefs:
|
||||
//
|
||||
// Result: the function's return type.
|
||||
// ArgumentN: the type of the N-th argument, where N starts with 1.
|
||||
// ArgumentTuple: the tuple type consisting of all parameters of F.
|
||||
// ArgumentMatcherTuple: the tuple type consisting of Matchers for all
|
||||
// parameters of F.
|
||||
// MakeResultVoid: the function type obtained by substituting void
|
||||
// for the return type of F.
|
||||
// MakeResultIgnoredValue:
|
||||
// the function type obtained by substituting Something
|
||||
// for the return type of F.
|
||||
template <typename F>
|
||||
struct Function;
|
||||
|
||||
template <typename R>
|
||||
struct Function<R()> {
|
||||
typedef R Result;
|
||||
typedef ::std::tr1::tuple<> ArgumentTuple;
|
||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||
typedef void MakeResultVoid();
|
||||
typedef IgnoredValue MakeResultIgnoredValue();
|
||||
};
|
||||
|
||||
template <typename R, typename A1>
|
||||
struct Function<R(A1)>
|
||||
: Function<R()> {
|
||||
typedef A1 Argument1;
|
||||
typedef ::std::tr1::tuple<A1> ArgumentTuple;
|
||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||
typedef void MakeResultVoid(A1);
|
||||
typedef IgnoredValue MakeResultIgnoredValue(A1);
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2>
|
||||
struct Function<R(A1, A2)>
|
||||
: Function<R(A1)> {
|
||||
typedef A2 Argument2;
|
||||
typedef ::std::tr1::tuple<A1, A2> ArgumentTuple;
|
||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||
typedef void MakeResultVoid(A1, A2);
|
||||
typedef IgnoredValue MakeResultIgnoredValue(A1, A2);
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3>
|
||||
struct Function<R(A1, A2, A3)>
|
||||
: Function<R(A1, A2)> {
|
||||
typedef A3 Argument3;
|
||||
typedef ::std::tr1::tuple<A1, A2, A3> ArgumentTuple;
|
||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||
typedef void MakeResultVoid(A1, A2, A3);
|
||||
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3);
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4>
|
||||
struct Function<R(A1, A2, A3, A4)>
|
||||
: Function<R(A1, A2, A3)> {
|
||||
typedef A4 Argument4;
|
||||
typedef ::std::tr1::tuple<A1, A2, A3, A4> ArgumentTuple;
|
||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||
typedef void MakeResultVoid(A1, A2, A3, A4);
|
||||
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4);
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
typename A5>
|
||||
struct Function<R(A1, A2, A3, A4, A5)>
|
||||
: Function<R(A1, A2, A3, A4)> {
|
||||
typedef A5 Argument5;
|
||||
typedef ::std::tr1::tuple<A1, A2, A3, A4, A5> ArgumentTuple;
|
||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||
typedef void MakeResultVoid(A1, A2, A3, A4, A5);
|
||||
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5);
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
typename A5, typename A6>
|
||||
struct Function<R(A1, A2, A3, A4, A5, A6)>
|
||||
: Function<R(A1, A2, A3, A4, A5)> {
|
||||
typedef A6 Argument6;
|
||||
typedef ::std::tr1::tuple<A1, A2, A3, A4, A5, A6> ArgumentTuple;
|
||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||
typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6);
|
||||
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6);
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
typename A5, typename A6, typename A7>
|
||||
struct Function<R(A1, A2, A3, A4, A5, A6, A7)>
|
||||
: Function<R(A1, A2, A3, A4, A5, A6)> {
|
||||
typedef A7 Argument7;
|
||||
typedef ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7> ArgumentTuple;
|
||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||
typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7);
|
||||
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7);
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
typename A5, typename A6, typename A7, typename A8>
|
||||
struct Function<R(A1, A2, A3, A4, A5, A6, A7, A8)>
|
||||
: Function<R(A1, A2, A3, A4, A5, A6, A7)> {
|
||||
typedef A8 Argument8;
|
||||
typedef ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8> ArgumentTuple;
|
||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||
typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7, A8);
|
||||
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7, A8);
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
typename A5, typename A6, typename A7, typename A8, typename A9>
|
||||
struct Function<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)>
|
||||
: Function<R(A1, A2, A3, A4, A5, A6, A7, A8)> {
|
||||
typedef A9 Argument9;
|
||||
typedef ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9> ArgumentTuple;
|
||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||
typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7, A8, A9);
|
||||
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7, A8,
|
||||
A9);
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
typename A5, typename A6, typename A7, typename A8, typename A9,
|
||||
typename A10>
|
||||
struct Function<R(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)>
|
||||
: Function<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)> {
|
||||
typedef A10 Argument10;
|
||||
typedef ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9,
|
||||
A10> ArgumentTuple;
|
||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||
typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10);
|
||||
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7, A8,
|
||||
A9, A10);
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
|
||||
@@ -0,0 +1,136 @@
|
||||
$$ -*- mode: c++; -*-
|
||||
$$ This is a Pump source file. Please use Pump to convert it to
|
||||
$$ gmock-generated-function-mockers.h.
|
||||
$$
|
||||
$var n = 10 $$ The maximum arity we support.
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file contains template meta-programming utility classes needed
|
||||
// for implementing Google Mock.
|
||||
|
||||
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
|
||||
#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
|
||||
|
||||
#include "gmock/internal/gmock-port.h"
|
||||
|
||||
namespace testing {
|
||||
|
||||
template <typename T>
|
||||
class Matcher;
|
||||
|
||||
namespace internal {
|
||||
|
||||
// An IgnoredValue object can be implicitly constructed from ANY value.
|
||||
// This is used in implementing the IgnoreResult(a) action.
|
||||
class IgnoredValue {
|
||||
public:
|
||||
// This constructor template allows any value to be implicitly
|
||||
// converted to IgnoredValue. The object has no data member and
|
||||
// doesn't try to remember anything about the argument. We
|
||||
// deliberately omit the 'explicit' keyword in order to allow the
|
||||
// conversion to be implicit.
|
||||
template <typename T>
|
||||
IgnoredValue(const T& /* ignored */) {} // NOLINT(runtime/explicit)
|
||||
};
|
||||
|
||||
// MatcherTuple<T>::type is a tuple type where each field is a Matcher
|
||||
// for the corresponding field in tuple type T.
|
||||
template <typename Tuple>
|
||||
struct MatcherTuple;
|
||||
|
||||
|
||||
$range i 0..n
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
$var typename_As = [[$for j, [[typename A$j]]]]
|
||||
$var As = [[$for j, [[A$j]]]]
|
||||
$var matcher_As = [[$for j, [[Matcher<A$j>]]]]
|
||||
template <$typename_As>
|
||||
struct MatcherTuple< ::std::tr1::tuple<$As> > {
|
||||
typedef ::std::tr1::tuple<$matcher_As > type;
|
||||
};
|
||||
|
||||
|
||||
]]
|
||||
// Template struct Function<F>, where F must be a function type, contains
|
||||
// the following typedefs:
|
||||
//
|
||||
// Result: the function's return type.
|
||||
// ArgumentN: the type of the N-th argument, where N starts with 1.
|
||||
// ArgumentTuple: the tuple type consisting of all parameters of F.
|
||||
// ArgumentMatcherTuple: the tuple type consisting of Matchers for all
|
||||
// parameters of F.
|
||||
// MakeResultVoid: the function type obtained by substituting void
|
||||
// for the return type of F.
|
||||
// MakeResultIgnoredValue:
|
||||
// the function type obtained by substituting Something
|
||||
// for the return type of F.
|
||||
template <typename F>
|
||||
struct Function;
|
||||
|
||||
template <typename R>
|
||||
struct Function<R()> {
|
||||
typedef R Result;
|
||||
typedef ::std::tr1::tuple<> ArgumentTuple;
|
||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||
typedef void MakeResultVoid();
|
||||
typedef IgnoredValue MakeResultIgnoredValue();
|
||||
};
|
||||
|
||||
|
||||
$range i 1..n
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
$var typename_As = [[$for j [[, typename A$j]]]]
|
||||
$var As = [[$for j, [[A$j]]]]
|
||||
$var matcher_As = [[$for j, [[Matcher<A$j>]]]]
|
||||
$range k 1..i-1
|
||||
$var prev_As = [[$for k, [[A$k]]]]
|
||||
template <typename R$typename_As>
|
||||
struct Function<R($As)>
|
||||
: Function<R($prev_As)> {
|
||||
typedef A$i Argument$i;
|
||||
typedef ::std::tr1::tuple<$As> ArgumentTuple;
|
||||
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||
typedef void MakeResultVoid($As);
|
||||
typedef IgnoredValue MakeResultIgnoredValue($As);
|
||||
};
|
||||
|
||||
|
||||
]]
|
||||
} // namespace internal
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
|
||||
498
gmock/include/gmock/internal/gmock-internal-utils.h
Normal file
498
gmock/include/gmock/internal/gmock-internal-utils.h
Normal file
@@ -0,0 +1,498 @@
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file defines some utilities useful for implementing Google
|
||||
// Mock. They are subject to change without notice, so please DO NOT
|
||||
// USE THEM IN USER CODE.
|
||||
|
||||
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
|
||||
#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ostream> // NOLINT
|
||||
#include <string>
|
||||
|
||||
#include "gmock/internal/gmock-generated-internal-utils.h"
|
||||
#include "gmock/internal/gmock-port.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// Converts an identifier name to a space-separated list of lower-case
|
||||
// words. Each maximum substring of the form [A-Za-z][a-z]*|\d+ is
|
||||
// treated as one word. For example, both "FooBar123" and
|
||||
// "foo_bar_123" are converted to "foo bar 123".
|
||||
GTEST_API_ string ConvertIdentifierNameToWords(const char* id_name);
|
||||
|
||||
// PointeeOf<Pointer>::type is the type of a value pointed to by a
|
||||
// Pointer, which can be either a smart pointer or a raw pointer. The
|
||||
// following default implementation is for the case where Pointer is a
|
||||
// smart pointer.
|
||||
template <typename Pointer>
|
||||
struct PointeeOf {
|
||||
// Smart pointer classes define type element_type as the type of
|
||||
// their pointees.
|
||||
typedef typename Pointer::element_type type;
|
||||
};
|
||||
// This specialization is for the raw pointer case.
|
||||
template <typename T>
|
||||
struct PointeeOf<T*> { typedef T type; }; // NOLINT
|
||||
|
||||
// GetRawPointer(p) returns the raw pointer underlying p when p is a
|
||||
// smart pointer, or returns p itself when p is already a raw pointer.
|
||||
// The following default implementation is for the smart pointer case.
|
||||
template <typename Pointer>
|
||||
inline const typename Pointer::element_type* GetRawPointer(const Pointer& p) {
|
||||
return p.get();
|
||||
}
|
||||
// This overloaded version is for the raw pointer case.
|
||||
template <typename Element>
|
||||
inline Element* GetRawPointer(Element* p) { return p; }
|
||||
|
||||
// This comparator allows linked_ptr to be stored in sets.
|
||||
template <typename T>
|
||||
struct LinkedPtrLessThan {
|
||||
bool operator()(const ::testing::internal::linked_ptr<T>& lhs,
|
||||
const ::testing::internal::linked_ptr<T>& rhs) const {
|
||||
return lhs.get() < rhs.get();
|
||||
}
|
||||
};
|
||||
|
||||
// Symbian compilation can be done with wchar_t being either a native
|
||||
// type or a typedef. Using Google Mock with OpenC without wchar_t
|
||||
// should require the definition of _STLP_NO_WCHAR_T.
|
||||
//
|
||||
// MSVC treats wchar_t as a native type usually, but treats it as the
|
||||
// same as unsigned short when the compiler option /Zc:wchar_t- is
|
||||
// specified. It defines _NATIVE_WCHAR_T_DEFINED symbol when wchar_t
|
||||
// is a native type.
|
||||
#if (GTEST_OS_SYMBIAN && defined(_STLP_NO_WCHAR_T)) || \
|
||||
(defined(_MSC_VER) && !defined(_NATIVE_WCHAR_T_DEFINED))
|
||||
// wchar_t is a typedef.
|
||||
#else
|
||||
# define GMOCK_WCHAR_T_IS_NATIVE_ 1
|
||||
#endif
|
||||
|
||||
// signed wchar_t and unsigned wchar_t are NOT in the C++ standard.
|
||||
// Using them is a bad practice and not portable. So DON'T use them.
|
||||
//
|
||||
// Still, Google Mock is designed to work even if the user uses signed
|
||||
// wchar_t or unsigned wchar_t (obviously, assuming the compiler
|
||||
// supports them).
|
||||
//
|
||||
// To gcc,
|
||||
// wchar_t == signed wchar_t != unsigned wchar_t == unsigned int
|
||||
#ifdef __GNUC__
|
||||
// signed/unsigned wchar_t are valid types.
|
||||
# define GMOCK_HAS_SIGNED_WCHAR_T_ 1
|
||||
#endif
|
||||
|
||||
// In what follows, we use the term "kind" to indicate whether a type
|
||||
// is bool, an integer type (excluding bool), a floating-point type,
|
||||
// or none of them. This categorization is useful for determining
|
||||
// when a matcher argument type can be safely converted to another
|
||||
// type in the implementation of SafeMatcherCast.
|
||||
enum TypeKind {
|
||||
kBool, kInteger, kFloatingPoint, kOther
|
||||
};
|
||||
|
||||
// KindOf<T>::value is the kind of type T.
|
||||
template <typename T> struct KindOf {
|
||||
enum { value = kOther }; // The default kind.
|
||||
};
|
||||
|
||||
// This macro declares that the kind of 'type' is 'kind'.
|
||||
#define GMOCK_DECLARE_KIND_(type, kind) \
|
||||
template <> struct KindOf<type> { enum { value = kind }; }
|
||||
|
||||
GMOCK_DECLARE_KIND_(bool, kBool);
|
||||
|
||||
// All standard integer types.
|
||||
GMOCK_DECLARE_KIND_(char, kInteger);
|
||||
GMOCK_DECLARE_KIND_(signed char, kInteger);
|
||||
GMOCK_DECLARE_KIND_(unsigned char, kInteger);
|
||||
GMOCK_DECLARE_KIND_(short, kInteger); // NOLINT
|
||||
GMOCK_DECLARE_KIND_(unsigned short, kInteger); // NOLINT
|
||||
GMOCK_DECLARE_KIND_(int, kInteger);
|
||||
GMOCK_DECLARE_KIND_(unsigned int, kInteger);
|
||||
GMOCK_DECLARE_KIND_(long, kInteger); // NOLINT
|
||||
GMOCK_DECLARE_KIND_(unsigned long, kInteger); // NOLINT
|
||||
|
||||
#if GMOCK_WCHAR_T_IS_NATIVE_
|
||||
GMOCK_DECLARE_KIND_(wchar_t, kInteger);
|
||||
#endif
|
||||
|
||||
// Non-standard integer types.
|
||||
GMOCK_DECLARE_KIND_(Int64, kInteger);
|
||||
GMOCK_DECLARE_KIND_(UInt64, kInteger);
|
||||
|
||||
// All standard floating-point types.
|
||||
GMOCK_DECLARE_KIND_(float, kFloatingPoint);
|
||||
GMOCK_DECLARE_KIND_(double, kFloatingPoint);
|
||||
GMOCK_DECLARE_KIND_(long double, kFloatingPoint);
|
||||
|
||||
#undef GMOCK_DECLARE_KIND_
|
||||
|
||||
// Evaluates to the kind of 'type'.
|
||||
#define GMOCK_KIND_OF_(type) \
|
||||
static_cast< ::testing::internal::TypeKind>( \
|
||||
::testing::internal::KindOf<type>::value)
|
||||
|
||||
// Evaluates to true iff integer type T is signed.
|
||||
#define GMOCK_IS_SIGNED_(T) (static_cast<T>(-1) < 0)
|
||||
|
||||
// LosslessArithmeticConvertibleImpl<kFromKind, From, kToKind, To>::value
|
||||
// is true iff arithmetic type From can be losslessly converted to
|
||||
// arithmetic type To.
|
||||
//
|
||||
// It's the user's responsibility to ensure that both From and To are
|
||||
// raw (i.e. has no CV modifier, is not a pointer, and is not a
|
||||
// reference) built-in arithmetic types, kFromKind is the kind of
|
||||
// From, and kToKind is the kind of To; the value is
|
||||
// implementation-defined when the above pre-condition is violated.
|
||||
template <TypeKind kFromKind, typename From, TypeKind kToKind, typename To>
|
||||
struct LosslessArithmeticConvertibleImpl : public false_type {};
|
||||
|
||||
// Converting bool to bool is lossless.
|
||||
template <>
|
||||
struct LosslessArithmeticConvertibleImpl<kBool, bool, kBool, bool>
|
||||
: public true_type {}; // NOLINT
|
||||
|
||||
// Converting bool to any integer type is lossless.
|
||||
template <typename To>
|
||||
struct LosslessArithmeticConvertibleImpl<kBool, bool, kInteger, To>
|
||||
: public true_type {}; // NOLINT
|
||||
|
||||
// Converting bool to any floating-point type is lossless.
|
||||
template <typename To>
|
||||
struct LosslessArithmeticConvertibleImpl<kBool, bool, kFloatingPoint, To>
|
||||
: public true_type {}; // NOLINT
|
||||
|
||||
// Converting an integer to bool is lossy.
|
||||
template <typename From>
|
||||
struct LosslessArithmeticConvertibleImpl<kInteger, From, kBool, bool>
|
||||
: public false_type {}; // NOLINT
|
||||
|
||||
// Converting an integer to another non-bool integer is lossless iff
|
||||
// the target type's range encloses the source type's range.
|
||||
template <typename From, typename To>
|
||||
struct LosslessArithmeticConvertibleImpl<kInteger, From, kInteger, To>
|
||||
: public bool_constant<
|
||||
// When converting from a smaller size to a larger size, we are
|
||||
// fine as long as we are not converting from signed to unsigned.
|
||||
((sizeof(From) < sizeof(To)) &&
|
||||
(!GMOCK_IS_SIGNED_(From) || GMOCK_IS_SIGNED_(To))) ||
|
||||
// When converting between the same size, the signedness must match.
|
||||
((sizeof(From) == sizeof(To)) &&
|
||||
(GMOCK_IS_SIGNED_(From) == GMOCK_IS_SIGNED_(To)))> {}; // NOLINT
|
||||
|
||||
#undef GMOCK_IS_SIGNED_
|
||||
|
||||
// Converting an integer to a floating-point type may be lossy, since
|
||||
// the format of a floating-point number is implementation-defined.
|
||||
template <typename From, typename To>
|
||||
struct LosslessArithmeticConvertibleImpl<kInteger, From, kFloatingPoint, To>
|
||||
: public false_type {}; // NOLINT
|
||||
|
||||
// Converting a floating-point to bool is lossy.
|
||||
template <typename From>
|
||||
struct LosslessArithmeticConvertibleImpl<kFloatingPoint, From, kBool, bool>
|
||||
: public false_type {}; // NOLINT
|
||||
|
||||
// Converting a floating-point to an integer is lossy.
|
||||
template <typename From, typename To>
|
||||
struct LosslessArithmeticConvertibleImpl<kFloatingPoint, From, kInteger, To>
|
||||
: public false_type {}; // NOLINT
|
||||
|
||||
// Converting a floating-point to another floating-point is lossless
|
||||
// iff the target type is at least as big as the source type.
|
||||
template <typename From, typename To>
|
||||
struct LosslessArithmeticConvertibleImpl<
|
||||
kFloatingPoint, From, kFloatingPoint, To>
|
||||
: public bool_constant<sizeof(From) <= sizeof(To)> {}; // NOLINT
|
||||
|
||||
// LosslessArithmeticConvertible<From, To>::value is true iff arithmetic
|
||||
// type From can be losslessly converted to arithmetic type To.
|
||||
//
|
||||
// It's the user's responsibility to ensure that both From and To are
|
||||
// raw (i.e. has no CV modifier, is not a pointer, and is not a
|
||||
// reference) built-in arithmetic types; the value is
|
||||
// implementation-defined when the above pre-condition is violated.
|
||||
template <typename From, typename To>
|
||||
struct LosslessArithmeticConvertible
|
||||
: public LosslessArithmeticConvertibleImpl<
|
||||
GMOCK_KIND_OF_(From), From, GMOCK_KIND_OF_(To), To> {}; // NOLINT
|
||||
|
||||
// This interface knows how to report a Google Mock failure (either
|
||||
// non-fatal or fatal).
|
||||
class FailureReporterInterface {
|
||||
public:
|
||||
// The type of a failure (either non-fatal or fatal).
|
||||
enum FailureType {
|
||||
kNonfatal, kFatal
|
||||
};
|
||||
|
||||
virtual ~FailureReporterInterface() {}
|
||||
|
||||
// Reports a failure that occurred at the given source file location.
|
||||
virtual void ReportFailure(FailureType type, const char* file, int line,
|
||||
const string& message) = 0;
|
||||
};
|
||||
|
||||
// Returns the failure reporter used by Google Mock.
|
||||
GTEST_API_ FailureReporterInterface* GetFailureReporter();
|
||||
|
||||
// Asserts that condition is true; aborts the process with the given
|
||||
// message if condition is false. We cannot use LOG(FATAL) or CHECK()
|
||||
// as Google Mock might be used to mock the log sink itself. We
|
||||
// inline this function to prevent it from showing up in the stack
|
||||
// trace.
|
||||
inline void Assert(bool condition, const char* file, int line,
|
||||
const string& msg) {
|
||||
if (!condition) {
|
||||
GetFailureReporter()->ReportFailure(FailureReporterInterface::kFatal,
|
||||
file, line, msg);
|
||||
}
|
||||
}
|
||||
inline void Assert(bool condition, const char* file, int line) {
|
||||
Assert(condition, file, line, "Assertion failed.");
|
||||
}
|
||||
|
||||
// Verifies that condition is true; generates a non-fatal failure if
|
||||
// condition is false.
|
||||
inline void Expect(bool condition, const char* file, int line,
|
||||
const string& msg) {
|
||||
if (!condition) {
|
||||
GetFailureReporter()->ReportFailure(FailureReporterInterface::kNonfatal,
|
||||
file, line, msg);
|
||||
}
|
||||
}
|
||||
inline void Expect(bool condition, const char* file, int line) {
|
||||
Expect(condition, file, line, "Expectation failed.");
|
||||
}
|
||||
|
||||
// Severity level of a log.
|
||||
enum LogSeverity {
|
||||
kInfo = 0,
|
||||
kWarning = 1
|
||||
};
|
||||
|
||||
// Valid values for the --gmock_verbose flag.
|
||||
|
||||
// All logs (informational and warnings) are printed.
|
||||
const char kInfoVerbosity[] = "info";
|
||||
// Only warnings are printed.
|
||||
const char kWarningVerbosity[] = "warning";
|
||||
// No logs are printed.
|
||||
const char kErrorVerbosity[] = "error";
|
||||
|
||||
// Returns true iff a log with the given severity is visible according
|
||||
// to the --gmock_verbose flag.
|
||||
GTEST_API_ bool LogIsVisible(LogSeverity severity);
|
||||
|
||||
// Prints the given message to stdout iff 'severity' >= the level
|
||||
// specified by the --gmock_verbose flag. If stack_frames_to_skip >=
|
||||
// 0, also prints the stack trace excluding the top
|
||||
// stack_frames_to_skip frames. In opt mode, any positive
|
||||
// stack_frames_to_skip is treated as 0, since we don't know which
|
||||
// function calls will be inlined by the compiler and need to be
|
||||
// conservative.
|
||||
GTEST_API_ void Log(LogSeverity severity,
|
||||
const string& message,
|
||||
int stack_frames_to_skip);
|
||||
|
||||
// TODO(wan@google.com): group all type utilities together.
|
||||
|
||||
// Type traits.
|
||||
|
||||
// is_reference<T>::value is non-zero iff T is a reference type.
|
||||
template <typename T> struct is_reference : public false_type {};
|
||||
template <typename T> struct is_reference<T&> : public true_type {};
|
||||
|
||||
// type_equals<T1, T2>::value is non-zero iff T1 and T2 are the same type.
|
||||
template <typename T1, typename T2> struct type_equals : public false_type {};
|
||||
template <typename T> struct type_equals<T, T> : public true_type {};
|
||||
|
||||
// remove_reference<T>::type removes the reference from type T, if any.
|
||||
template <typename T> struct remove_reference { typedef T type; }; // NOLINT
|
||||
template <typename T> struct remove_reference<T&> { typedef T type; }; // NOLINT
|
||||
|
||||
// DecayArray<T>::type turns an array type U[N] to const U* and preserves
|
||||
// other types. Useful for saving a copy of a function argument.
|
||||
template <typename T> struct DecayArray { typedef T type; }; // NOLINT
|
||||
template <typename T, size_t N> struct DecayArray<T[N]> {
|
||||
typedef const T* type;
|
||||
};
|
||||
// Sometimes people use arrays whose size is not available at the use site
|
||||
// (e.g. extern const char kNamePrefix[]). This specialization covers that
|
||||
// case.
|
||||
template <typename T> struct DecayArray<T[]> {
|
||||
typedef const T* type;
|
||||
};
|
||||
|
||||
// Invalid<T>() returns an invalid value of type T. This is useful
|
||||
// when a value of type T is needed for compilation, but the statement
|
||||
// will not really be executed (or we don't care if the statement
|
||||
// crashes).
|
||||
template <typename T>
|
||||
inline T Invalid() {
|
||||
return const_cast<typename remove_reference<T>::type&>(
|
||||
*static_cast<volatile typename remove_reference<T>::type*>(NULL));
|
||||
}
|
||||
template <>
|
||||
inline void Invalid<void>() {}
|
||||
|
||||
// Given a raw type (i.e. having no top-level reference or const
|
||||
// modifier) RawContainer that's either an STL-style container or a
|
||||
// native array, class StlContainerView<RawContainer> has the
|
||||
// following members:
|
||||
//
|
||||
// - type is a type that provides an STL-style container view to
|
||||
// (i.e. implements the STL container concept for) RawContainer;
|
||||
// - const_reference is a type that provides a reference to a const
|
||||
// RawContainer;
|
||||
// - ConstReference(raw_container) returns a const reference to an STL-style
|
||||
// container view to raw_container, which is a RawContainer.
|
||||
// - Copy(raw_container) returns an STL-style container view of a
|
||||
// copy of raw_container, which is a RawContainer.
|
||||
//
|
||||
// This generic version is used when RawContainer itself is already an
|
||||
// STL-style container.
|
||||
template <class RawContainer>
|
||||
class StlContainerView {
|
||||
public:
|
||||
typedef RawContainer type;
|
||||
typedef const type& const_reference;
|
||||
|
||||
static const_reference ConstReference(const RawContainer& container) {
|
||||
// Ensures that RawContainer is not a const type.
|
||||
testing::StaticAssertTypeEq<RawContainer,
|
||||
GTEST_REMOVE_CONST_(RawContainer)>();
|
||||
return container;
|
||||
}
|
||||
static type Copy(const RawContainer& container) { return container; }
|
||||
};
|
||||
|
||||
// This specialization is used when RawContainer is a native array type.
|
||||
template <typename Element, size_t N>
|
||||
class StlContainerView<Element[N]> {
|
||||
public:
|
||||
typedef GTEST_REMOVE_CONST_(Element) RawElement;
|
||||
typedef internal::NativeArray<RawElement> type;
|
||||
// NativeArray<T> can represent a native array either by value or by
|
||||
// reference (selected by a constructor argument), so 'const type'
|
||||
// can be used to reference a const native array. We cannot
|
||||
// 'typedef const type& const_reference' here, as that would mean
|
||||
// ConstReference() has to return a reference to a local variable.
|
||||
typedef const type const_reference;
|
||||
|
||||
static const_reference ConstReference(const Element (&array)[N]) {
|
||||
// Ensures that Element is not a const type.
|
||||
testing::StaticAssertTypeEq<Element, RawElement>();
|
||||
#if GTEST_OS_SYMBIAN
|
||||
// The Nokia Symbian compiler confuses itself in template instantiation
|
||||
// for this call without the cast to Element*:
|
||||
// function call '[testing::internal::NativeArray<char *>].NativeArray(
|
||||
// {lval} const char *[4], long, testing::internal::RelationToSource)'
|
||||
// does not match
|
||||
// 'testing::internal::NativeArray<char *>::NativeArray(
|
||||
// char *const *, unsigned int, testing::internal::RelationToSource)'
|
||||
// (instantiating: 'testing::internal::ContainsMatcherImpl
|
||||
// <const char * (&)[4]>::Matches(const char * (&)[4]) const')
|
||||
// (instantiating: 'testing::internal::StlContainerView<char *[4]>::
|
||||
// ConstReference(const char * (&)[4])')
|
||||
// (and though the N parameter type is mismatched in the above explicit
|
||||
// conversion of it doesn't help - only the conversion of the array).
|
||||
return type(const_cast<Element*>(&array[0]), N, kReference);
|
||||
#else
|
||||
return type(array, N, kReference);
|
||||
#endif // GTEST_OS_SYMBIAN
|
||||
}
|
||||
static type Copy(const Element (&array)[N]) {
|
||||
#if GTEST_OS_SYMBIAN
|
||||
return type(const_cast<Element*>(&array[0]), N, kCopy);
|
||||
#else
|
||||
return type(array, N, kCopy);
|
||||
#endif // GTEST_OS_SYMBIAN
|
||||
}
|
||||
};
|
||||
|
||||
// This specialization is used when RawContainer is a native array
|
||||
// represented as a (pointer, size) tuple.
|
||||
template <typename ElementPointer, typename Size>
|
||||
class StlContainerView< ::std::tr1::tuple<ElementPointer, Size> > {
|
||||
public:
|
||||
typedef GTEST_REMOVE_CONST_(
|
||||
typename internal::PointeeOf<ElementPointer>::type) RawElement;
|
||||
typedef internal::NativeArray<RawElement> type;
|
||||
typedef const type const_reference;
|
||||
|
||||
static const_reference ConstReference(
|
||||
const ::std::tr1::tuple<ElementPointer, Size>& array) {
|
||||
using ::std::tr1::get;
|
||||
return type(get<0>(array), get<1>(array), kReference);
|
||||
}
|
||||
static type Copy(const ::std::tr1::tuple<ElementPointer, Size>& array) {
|
||||
using ::std::tr1::get;
|
||||
return type(get<0>(array), get<1>(array), kCopy);
|
||||
}
|
||||
};
|
||||
|
||||
// The following specialization prevents the user from instantiating
|
||||
// StlContainer with a reference type.
|
||||
template <typename T> class StlContainerView<T&>;
|
||||
|
||||
// A type transform to remove constness from the first part of a pair.
|
||||
// Pairs like that are used as the value_type of associative containers,
|
||||
// and this transform produces a similar but assignable pair.
|
||||
template <typename T>
|
||||
struct RemoveConstFromKey {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
// Partially specialized to remove constness from std::pair<const K, V>.
|
||||
template <typename K, typename V>
|
||||
struct RemoveConstFromKey<std::pair<const K, V> > {
|
||||
typedef std::pair<K, V> type;
|
||||
};
|
||||
|
||||
// Mapping from booleans to types. Similar to boost::bool_<kValue> and
|
||||
// std::integral_constant<bool, kValue>.
|
||||
template <bool kValue>
|
||||
struct BooleanConstant {};
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
|
||||
78
gmock/include/gmock/internal/gmock-port.h
Normal file
78
gmock/include/gmock/internal/gmock-port.h
Normal file
@@ -0,0 +1,78 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: vadimb@google.com (Vadim Berman)
|
||||
//
|
||||
// Low-level types and utilities for porting Google Mock to various
|
||||
// platforms. They are subject to change without notice. DO NOT USE
|
||||
// THEM IN USER CODE.
|
||||
|
||||
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
|
||||
#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
|
||||
// Most of the types needed for porting Google Mock are also required
|
||||
// for Google Test and are defined in gtest-port.h.
|
||||
#include "gtest/internal/gtest-linked_ptr.h"
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
|
||||
// To avoid conditional compilation everywhere, we make it
|
||||
// gmock-port.h's responsibility to #include the header implementing
|
||||
// tr1/tuple. gmock-port.h does this via gtest-port.h, which is
|
||||
// guaranteed to pull in the tuple header.
|
||||
|
||||
// For MS Visual C++, check the compiler version. At least VS 2003 is
|
||||
// required to compile Google Mock.
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1310
|
||||
# error "At least Visual C++ 2003 (7.1) is required to compile Google Mock."
|
||||
#endif
|
||||
|
||||
// Macro for referencing flags. This is public as we want the user to
|
||||
// use this syntax to reference Google Mock flags.
|
||||
#define GMOCK_FLAG(name) FLAGS_gmock_##name
|
||||
|
||||
// Macros for declaring flags.
|
||||
#define GMOCK_DECLARE_bool_(name) extern GTEST_API_ bool GMOCK_FLAG(name)
|
||||
#define GMOCK_DECLARE_int32_(name) \
|
||||
extern GTEST_API_ ::testing::internal::Int32 GMOCK_FLAG(name)
|
||||
#define GMOCK_DECLARE_string_(name) \
|
||||
extern GTEST_API_ ::std::string GMOCK_FLAG(name)
|
||||
|
||||
// Macros for defining flags.
|
||||
#define GMOCK_DEFINE_bool_(name, default_val, doc) \
|
||||
GTEST_API_ bool GMOCK_FLAG(name) = (default_val)
|
||||
#define GMOCK_DEFINE_int32_(name, default_val, doc) \
|
||||
GTEST_API_ ::testing::internal::Int32 GMOCK_FLAG(name) = (default_val)
|
||||
#define GMOCK_DEFINE_string_(name, default_val, doc) \
|
||||
GTEST_API_ ::std::string GMOCK_FLAG(name) = (default_val)
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
|
||||
47
gmock/src/gmock-all.cc
Normal file
47
gmock/src/gmock-all.cc
Normal file
@@ -0,0 +1,47 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
//
|
||||
// Google C++ Mocking Framework (Google Mock)
|
||||
//
|
||||
// This file #includes all Google Mock implementation .cc files. The
|
||||
// purpose is to allow a user to build Google Mock by compiling this
|
||||
// file alone.
|
||||
|
||||
// This line ensures that gmock.h can be compiled on its own, even
|
||||
// when it's fused.
|
||||
#include "gmock/gmock.h"
|
||||
|
||||
// The following lines pull in the real gmock *.cc files.
|
||||
#include "src/gmock-cardinalities.cc"
|
||||
#include "src/gmock-internal-utils.cc"
|
||||
#include "src/gmock-matchers.cc"
|
||||
#include "src/gmock-spec-builders.cc"
|
||||
#include "src/gmock.cc"
|
||||
156
gmock/src/gmock-cardinalities.cc
Normal file
156
gmock/src/gmock-cardinalities.cc
Normal file
@@ -0,0 +1,156 @@
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file implements cardinalities.
|
||||
|
||||
#include "gmock/gmock-cardinalities.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <ostream> // NOLINT
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include "gmock/internal/gmock-internal-utils.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace testing {
|
||||
|
||||
namespace {
|
||||
|
||||
// Implements the Between(m, n) cardinality.
|
||||
class BetweenCardinalityImpl : public CardinalityInterface {
|
||||
public:
|
||||
BetweenCardinalityImpl(int min, int max)
|
||||
: min_(min >= 0 ? min : 0),
|
||||
max_(max >= min_ ? max : min_) {
|
||||
std::stringstream ss;
|
||||
if (min < 0) {
|
||||
ss << "The invocation lower bound must be >= 0, "
|
||||
<< "but is actually " << min << ".";
|
||||
internal::Expect(false, __FILE__, __LINE__, ss.str());
|
||||
} else if (max < 0) {
|
||||
ss << "The invocation upper bound must be >= 0, "
|
||||
<< "but is actually " << max << ".";
|
||||
internal::Expect(false, __FILE__, __LINE__, ss.str());
|
||||
} else if (min > max) {
|
||||
ss << "The invocation upper bound (" << max
|
||||
<< ") must be >= the invocation lower bound (" << min
|
||||
<< ").";
|
||||
internal::Expect(false, __FILE__, __LINE__, ss.str());
|
||||
}
|
||||
}
|
||||
|
||||
// Conservative estimate on the lower/upper bound of the number of
|
||||
// calls allowed.
|
||||
virtual int ConservativeLowerBound() const { return min_; }
|
||||
virtual int ConservativeUpperBound() const { return max_; }
|
||||
|
||||
virtual bool IsSatisfiedByCallCount(int call_count) const {
|
||||
return min_ <= call_count && call_count <= max_;
|
||||
}
|
||||
|
||||
virtual bool IsSaturatedByCallCount(int call_count) const {
|
||||
return call_count >= max_;
|
||||
}
|
||||
|
||||
virtual void DescribeTo(::std::ostream* os) const;
|
||||
|
||||
private:
|
||||
const int min_;
|
||||
const int max_;
|
||||
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(BetweenCardinalityImpl);
|
||||
};
|
||||
|
||||
// Formats "n times" in a human-friendly way.
|
||||
inline internal::string FormatTimes(int n) {
|
||||
if (n == 1) {
|
||||
return "once";
|
||||
} else if (n == 2) {
|
||||
return "twice";
|
||||
} else {
|
||||
std::stringstream ss;
|
||||
ss << n << " times";
|
||||
return ss.str();
|
||||
}
|
||||
}
|
||||
|
||||
// Describes the Between(m, n) cardinality in human-friendly text.
|
||||
void BetweenCardinalityImpl::DescribeTo(::std::ostream* os) const {
|
||||
if (min_ == 0) {
|
||||
if (max_ == 0) {
|
||||
*os << "never called";
|
||||
} else if (max_ == INT_MAX) {
|
||||
*os << "called any number of times";
|
||||
} else {
|
||||
*os << "called at most " << FormatTimes(max_);
|
||||
}
|
||||
} else if (min_ == max_) {
|
||||
*os << "called " << FormatTimes(min_);
|
||||
} else if (max_ == INT_MAX) {
|
||||
*os << "called at least " << FormatTimes(min_);
|
||||
} else {
|
||||
// 0 < min_ < max_ < INT_MAX
|
||||
*os << "called between " << min_ << " and " << max_ << " times";
|
||||
}
|
||||
}
|
||||
|
||||
} // Unnamed namespace
|
||||
|
||||
// Describes the given call count to an ostream.
|
||||
void Cardinality::DescribeActualCallCountTo(int actual_call_count,
|
||||
::std::ostream* os) {
|
||||
if (actual_call_count > 0) {
|
||||
*os << "called " << FormatTimes(actual_call_count);
|
||||
} else {
|
||||
*os << "never called";
|
||||
}
|
||||
}
|
||||
|
||||
// Creates a cardinality that allows at least n calls.
|
||||
GTEST_API_ Cardinality AtLeast(int n) { return Between(n, INT_MAX); }
|
||||
|
||||
// Creates a cardinality that allows at most n calls.
|
||||
GTEST_API_ Cardinality AtMost(int n) { return Between(0, n); }
|
||||
|
||||
// Creates a cardinality that allows any number of calls.
|
||||
GTEST_API_ Cardinality AnyNumber() { return AtLeast(0); }
|
||||
|
||||
// Creates a cardinality that allows between min and max calls.
|
||||
GTEST_API_ Cardinality Between(int min, int max) {
|
||||
return Cardinality(new BetweenCardinalityImpl(min, max));
|
||||
}
|
||||
|
||||
// Creates a cardinality that allows exactly n calls.
|
||||
GTEST_API_ Cardinality Exactly(int n) { return Between(n, n); }
|
||||
|
||||
} // namespace testing
|
||||
174
gmock/src/gmock-internal-utils.cc
Normal file
174
gmock/src/gmock-internal-utils.cc
Normal file
@@ -0,0 +1,174 @@
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file defines some utilities useful for implementing Google
|
||||
// Mock. They are subject to change without notice, so please DO NOT
|
||||
// USE THEM IN USER CODE.
|
||||
|
||||
#include "gmock/internal/gmock-internal-utils.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <ostream> // NOLINT
|
||||
#include <string>
|
||||
#include "gmock/gmock.h"
|
||||
#include "gmock/internal/gmock-port.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// Converts an identifier name to a space-separated list of lower-case
|
||||
// words. Each maximum substring of the form [A-Za-z][a-z]*|\d+ is
|
||||
// treated as one word. For example, both "FooBar123" and
|
||||
// "foo_bar_123" are converted to "foo bar 123".
|
||||
GTEST_API_ string ConvertIdentifierNameToWords(const char* id_name) {
|
||||
string result;
|
||||
char prev_char = '\0';
|
||||
for (const char* p = id_name; *p != '\0'; prev_char = *(p++)) {
|
||||
// We don't care about the current locale as the input is
|
||||
// guaranteed to be a valid C++ identifier name.
|
||||
const bool starts_new_word = IsUpper(*p) ||
|
||||
(!IsAlpha(prev_char) && IsLower(*p)) ||
|
||||
(!IsDigit(prev_char) && IsDigit(*p));
|
||||
|
||||
if (IsAlNum(*p)) {
|
||||
if (starts_new_word && result != "")
|
||||
result += ' ';
|
||||
result += ToLower(*p);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// This class reports Google Mock failures as Google Test failures. A
|
||||
// user can define another class in a similar fashion if he intends to
|
||||
// use Google Mock with a testing framework other than Google Test.
|
||||
class GoogleTestFailureReporter : public FailureReporterInterface {
|
||||
public:
|
||||
virtual void ReportFailure(FailureType type, const char* file, int line,
|
||||
const string& message) {
|
||||
AssertHelper(type == kFatal ?
|
||||
TestPartResult::kFatalFailure :
|
||||
TestPartResult::kNonFatalFailure,
|
||||
file,
|
||||
line,
|
||||
message.c_str()) = Message();
|
||||
if (type == kFatal) {
|
||||
posix::Abort();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Returns the global failure reporter. Will create a
|
||||
// GoogleTestFailureReporter and return it the first time called.
|
||||
GTEST_API_ FailureReporterInterface* GetFailureReporter() {
|
||||
// Points to the global failure reporter used by Google Mock. gcc
|
||||
// guarantees that the following use of failure_reporter is
|
||||
// thread-safe. We may need to add additional synchronization to
|
||||
// protect failure_reporter if we port Google Mock to other
|
||||
// compilers.
|
||||
static FailureReporterInterface* const failure_reporter =
|
||||
new GoogleTestFailureReporter();
|
||||
return failure_reporter;
|
||||
}
|
||||
|
||||
// Protects global resources (stdout in particular) used by Log().
|
||||
static GTEST_DEFINE_STATIC_MUTEX_(g_log_mutex);
|
||||
|
||||
// Returns true iff a log with the given severity is visible according
|
||||
// to the --gmock_verbose flag.
|
||||
GTEST_API_ bool LogIsVisible(LogSeverity severity) {
|
||||
if (GMOCK_FLAG(verbose) == kInfoVerbosity) {
|
||||
// Always show the log if --gmock_verbose=info.
|
||||
return true;
|
||||
} else if (GMOCK_FLAG(verbose) == kErrorVerbosity) {
|
||||
// Always hide it if --gmock_verbose=error.
|
||||
return false;
|
||||
} else {
|
||||
// If --gmock_verbose is neither "info" nor "error", we treat it
|
||||
// as "warning" (its default value).
|
||||
return severity == kWarning;
|
||||
}
|
||||
}
|
||||
|
||||
// Prints the given message to stdout iff 'severity' >= the level
|
||||
// specified by the --gmock_verbose flag. If stack_frames_to_skip >=
|
||||
// 0, also prints the stack trace excluding the top
|
||||
// stack_frames_to_skip frames. In opt mode, any positive
|
||||
// stack_frames_to_skip is treated as 0, since we don't know which
|
||||
// function calls will be inlined by the compiler and need to be
|
||||
// conservative.
|
||||
GTEST_API_ void Log(LogSeverity severity,
|
||||
const string& message,
|
||||
int stack_frames_to_skip) {
|
||||
if (!LogIsVisible(severity))
|
||||
return;
|
||||
|
||||
// Ensures that logs from different threads don't interleave.
|
||||
MutexLock l(&g_log_mutex);
|
||||
|
||||
// "using ::std::cout;" doesn't work with Symbian's STLport, where cout is a
|
||||
// macro.
|
||||
|
||||
if (severity == kWarning) {
|
||||
// Prints a GMOCK WARNING marker to make the warnings easily searchable.
|
||||
std::cout << "\nGMOCK WARNING:";
|
||||
}
|
||||
// Pre-pends a new-line to message if it doesn't start with one.
|
||||
if (message.empty() || message[0] != '\n') {
|
||||
std::cout << "\n";
|
||||
}
|
||||
std::cout << message;
|
||||
if (stack_frames_to_skip >= 0) {
|
||||
#ifdef NDEBUG
|
||||
// In opt mode, we have to be conservative and skip no stack frame.
|
||||
const int actual_to_skip = 0;
|
||||
#else
|
||||
// In dbg mode, we can do what the caller tell us to do (plus one
|
||||
// for skipping this function's stack frame).
|
||||
const int actual_to_skip = stack_frames_to_skip + 1;
|
||||
#endif // NDEBUG
|
||||
|
||||
// Appends a new-line to message if it doesn't end with one.
|
||||
if (!message.empty() && *message.rbegin() != '\n') {
|
||||
std::cout << "\n";
|
||||
}
|
||||
std::cout << "Stack trace:\n"
|
||||
<< ::testing::internal::GetCurrentOsStackTraceExceptTop(
|
||||
::testing::UnitTest::GetInstance(), actual_to_skip);
|
||||
}
|
||||
std::cout << ::std::flush;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
498
gmock/src/gmock-matchers.cc
Normal file
498
gmock/src/gmock-matchers.cc
Normal file
@@ -0,0 +1,498 @@
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file implements Matcher<const string&>, Matcher<string>, and
|
||||
// utilities for defining matchers.
|
||||
|
||||
#include "gmock/gmock-matchers.h"
|
||||
#include "gmock/gmock-generated-matchers.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
namespace testing {
|
||||
|
||||
// Constructs a matcher that matches a const string& whose value is
|
||||
// equal to s.
|
||||
Matcher<const internal::string&>::Matcher(const internal::string& s) {
|
||||
*this = Eq(s);
|
||||
}
|
||||
|
||||
// Constructs a matcher that matches a const string& whose value is
|
||||
// equal to s.
|
||||
Matcher<const internal::string&>::Matcher(const char* s) {
|
||||
*this = Eq(internal::string(s));
|
||||
}
|
||||
|
||||
// Constructs a matcher that matches a string whose value is equal to s.
|
||||
Matcher<internal::string>::Matcher(const internal::string& s) { *this = Eq(s); }
|
||||
|
||||
// Constructs a matcher that matches a string whose value is equal to s.
|
||||
Matcher<internal::string>::Matcher(const char* s) {
|
||||
*this = Eq(internal::string(s));
|
||||
}
|
||||
|
||||
#if GTEST_HAS_STRING_PIECE_
|
||||
// Constructs a matcher that matches a const StringPiece& whose value is
|
||||
// equal to s.
|
||||
Matcher<const StringPiece&>::Matcher(const internal::string& s) {
|
||||
*this = Eq(s);
|
||||
}
|
||||
|
||||
// Constructs a matcher that matches a const StringPiece& whose value is
|
||||
// equal to s.
|
||||
Matcher<const StringPiece&>::Matcher(const char* s) {
|
||||
*this = Eq(internal::string(s));
|
||||
}
|
||||
|
||||
// Constructs a matcher that matches a const StringPiece& whose value is
|
||||
// equal to s.
|
||||
Matcher<const StringPiece&>::Matcher(StringPiece s) {
|
||||
*this = Eq(s.ToString());
|
||||
}
|
||||
|
||||
// Constructs a matcher that matches a StringPiece whose value is equal to s.
|
||||
Matcher<StringPiece>::Matcher(const internal::string& s) {
|
||||
*this = Eq(s);
|
||||
}
|
||||
|
||||
// Constructs a matcher that matches a StringPiece whose value is equal to s.
|
||||
Matcher<StringPiece>::Matcher(const char* s) {
|
||||
*this = Eq(internal::string(s));
|
||||
}
|
||||
|
||||
// Constructs a matcher that matches a StringPiece whose value is equal to s.
|
||||
Matcher<StringPiece>::Matcher(StringPiece s) {
|
||||
*this = Eq(s.ToString());
|
||||
}
|
||||
#endif // GTEST_HAS_STRING_PIECE_
|
||||
|
||||
namespace internal {
|
||||
|
||||
// Joins a vector of strings as if they are fields of a tuple; returns
|
||||
// the joined string.
|
||||
GTEST_API_ string JoinAsTuple(const Strings& fields) {
|
||||
switch (fields.size()) {
|
||||
case 0:
|
||||
return "";
|
||||
case 1:
|
||||
return fields[0];
|
||||
default:
|
||||
string result = "(" + fields[0];
|
||||
for (size_t i = 1; i < fields.size(); i++) {
|
||||
result += ", ";
|
||||
result += fields[i];
|
||||
}
|
||||
result += ")";
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the description for a matcher defined using the MATCHER*()
|
||||
// macro where the user-supplied description string is "", if
|
||||
// 'negation' is false; otherwise returns the description of the
|
||||
// negation of the matcher. 'param_values' contains a list of strings
|
||||
// that are the print-out of the matcher's parameters.
|
||||
GTEST_API_ string FormatMatcherDescription(bool negation,
|
||||
const char* matcher_name,
|
||||
const Strings& param_values) {
|
||||
string result = ConvertIdentifierNameToWords(matcher_name);
|
||||
if (param_values.size() >= 1)
|
||||
result += " " + JoinAsTuple(param_values);
|
||||
return negation ? "not (" + result + ")" : result;
|
||||
}
|
||||
|
||||
// FindMaxBipartiteMatching and its helper class.
|
||||
//
|
||||
// Uses the well-known Ford-Fulkerson max flow method to find a maximum
|
||||
// bipartite matching. Flow is considered to be from left to right.
|
||||
// There is an implicit source node that is connected to all of the left
|
||||
// nodes, and an implicit sink node that is connected to all of the
|
||||
// right nodes. All edges have unit capacity.
|
||||
//
|
||||
// Neither the flow graph nor the residual flow graph are represented
|
||||
// explicitly. Instead, they are implied by the information in 'graph' and
|
||||
// a vector<int> called 'left_' whose elements are initialized to the
|
||||
// value kUnused. This represents the initial state of the algorithm,
|
||||
// where the flow graph is empty, and the residual flow graph has the
|
||||
// following edges:
|
||||
// - An edge from source to each left_ node
|
||||
// - An edge from each right_ node to sink
|
||||
// - An edge from each left_ node to each right_ node, if the
|
||||
// corresponding edge exists in 'graph'.
|
||||
//
|
||||
// When the TryAugment() method adds a flow, it sets left_[l] = r for some
|
||||
// nodes l and r. This induces the following changes:
|
||||
// - The edges (source, l), (l, r), and (r, sink) are added to the
|
||||
// flow graph.
|
||||
// - The same three edges are removed from the residual flow graph.
|
||||
// - The reverse edges (l, source), (r, l), and (sink, r) are added
|
||||
// to the residual flow graph, which is a directional graph
|
||||
// representing unused flow capacity.
|
||||
//
|
||||
// When the method augments a flow (moving left_[l] from some r1 to some
|
||||
// other r2), this can be thought of as "undoing" the above steps with
|
||||
// respect to r1 and "redoing" them with respect to r2.
|
||||
//
|
||||
// It bears repeating that the flow graph and residual flow graph are
|
||||
// never represented explicitly, but can be derived by looking at the
|
||||
// information in 'graph' and in left_.
|
||||
//
|
||||
// As an optimization, there is a second vector<int> called right_ which
|
||||
// does not provide any new information. Instead, it enables more
|
||||
// efficient queries about edges entering or leaving the right-side nodes
|
||||
// of the flow or residual flow graphs. The following invariants are
|
||||
// maintained:
|
||||
//
|
||||
// left[l] == kUnused or right[left[l]] == l
|
||||
// right[r] == kUnused or left[right[r]] == r
|
||||
//
|
||||
// . [ source ] .
|
||||
// . ||| .
|
||||
// . ||| .
|
||||
// . ||\--> left[0]=1 ---\ right[0]=-1 ----\ .
|
||||
// . || | | .
|
||||
// . |\---> left[1]=-1 \--> right[1]=0 ---\| .
|
||||
// . | || .
|
||||
// . \----> left[2]=2 ------> right[2]=2 --\|| .
|
||||
// . ||| .
|
||||
// . elements matchers vvv .
|
||||
// . [ sink ] .
|
||||
//
|
||||
// See Also:
|
||||
// [1] Cormen, et al (2001). "Section 26.2: The Ford–Fulkerson method".
|
||||
// "Introduction to Algorithms (Second ed.)", pp. 651–664.
|
||||
// [2] "Ford–Fulkerson algorithm", Wikipedia,
|
||||
// 'http://en.wikipedia.org/wiki/Ford%E2%80%93Fulkerson_algorithm'
|
||||
class MaxBipartiteMatchState {
|
||||
public:
|
||||
explicit MaxBipartiteMatchState(const MatchMatrix& graph)
|
||||
: graph_(&graph),
|
||||
left_(graph_->LhsSize(), kUnused),
|
||||
right_(graph_->RhsSize(), kUnused) {
|
||||
}
|
||||
|
||||
// Returns the edges of a maximal match, each in the form {left, right}.
|
||||
ElementMatcherPairs Compute() {
|
||||
// 'seen' is used for path finding { 0: unseen, 1: seen }.
|
||||
::std::vector<char> seen;
|
||||
// Searches the residual flow graph for a path from each left node to
|
||||
// the sink in the residual flow graph, and if one is found, add flow
|
||||
// to the graph. It's okay to search through the left nodes once. The
|
||||
// edge from the implicit source node to each previously-visited left
|
||||
// node will have flow if that left node has any path to the sink
|
||||
// whatsoever. Subsequent augmentations can only add flow to the
|
||||
// network, and cannot take away that previous flow unit from the source.
|
||||
// Since the source-to-left edge can only carry one flow unit (or,
|
||||
// each element can be matched to only one matcher), there is no need
|
||||
// to visit the left nodes more than once looking for augmented paths.
|
||||
// The flow is known to be possible or impossible by looking at the
|
||||
// node once.
|
||||
for (size_t ilhs = 0; ilhs < graph_->LhsSize(); ++ilhs) {
|
||||
// Reset the path-marking vector and try to find a path from
|
||||
// source to sink starting at the left_[ilhs] node.
|
||||
GTEST_CHECK_(left_[ilhs] == kUnused)
|
||||
<< "ilhs: " << ilhs << ", left_[ilhs]: " << left_[ilhs];
|
||||
// 'seen' initialized to 'graph_->RhsSize()' copies of 0.
|
||||
seen.assign(graph_->RhsSize(), 0);
|
||||
TryAugment(ilhs, &seen);
|
||||
}
|
||||
ElementMatcherPairs result;
|
||||
for (size_t ilhs = 0; ilhs < left_.size(); ++ilhs) {
|
||||
size_t irhs = left_[ilhs];
|
||||
if (irhs == kUnused) continue;
|
||||
result.push_back(ElementMatcherPair(ilhs, irhs));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
static const size_t kUnused = static_cast<size_t>(-1);
|
||||
|
||||
// Perform a depth-first search from left node ilhs to the sink. If a
|
||||
// path is found, flow is added to the network by linking the left and
|
||||
// right vector elements corresponding each segment of the path.
|
||||
// Returns true if a path to sink was found, which means that a unit of
|
||||
// flow was added to the network. The 'seen' vector elements correspond
|
||||
// to right nodes and are marked to eliminate cycles from the search.
|
||||
//
|
||||
// Left nodes will only be explored at most once because they
|
||||
// are accessible from at most one right node in the residual flow
|
||||
// graph.
|
||||
//
|
||||
// Note that left_[ilhs] is the only element of left_ that TryAugment will
|
||||
// potentially transition from kUnused to another value. Any other
|
||||
// left_ element holding kUnused before TryAugment will be holding it
|
||||
// when TryAugment returns.
|
||||
//
|
||||
bool TryAugment(size_t ilhs, ::std::vector<char>* seen) {
|
||||
for (size_t irhs = 0; irhs < graph_->RhsSize(); ++irhs) {
|
||||
if ((*seen)[irhs])
|
||||
continue;
|
||||
if (!graph_->HasEdge(ilhs, irhs))
|
||||
continue;
|
||||
// There's an available edge from ilhs to irhs.
|
||||
(*seen)[irhs] = 1;
|
||||
// Next a search is performed to determine whether
|
||||
// this edge is a dead end or leads to the sink.
|
||||
//
|
||||
// right_[irhs] == kUnused means that there is residual flow from
|
||||
// right node irhs to the sink, so we can use that to finish this
|
||||
// flow path and return success.
|
||||
//
|
||||
// Otherwise there is residual flow to some ilhs. We push flow
|
||||
// along that path and call ourselves recursively to see if this
|
||||
// ultimately leads to sink.
|
||||
if (right_[irhs] == kUnused || TryAugment(right_[irhs], seen)) {
|
||||
// Add flow from left_[ilhs] to right_[irhs].
|
||||
left_[ilhs] = irhs;
|
||||
right_[irhs] = ilhs;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const MatchMatrix* graph_; // not owned
|
||||
// Each element of the left_ vector represents a left hand side node
|
||||
// (i.e. an element) and each element of right_ is a right hand side
|
||||
// node (i.e. a matcher). The values in the left_ vector indicate
|
||||
// outflow from that node to a node on the the right_ side. The values
|
||||
// in the right_ indicate inflow, and specify which left_ node is
|
||||
// feeding that right_ node, if any. For example, left_[3] == 1 means
|
||||
// there's a flow from element #3 to matcher #1. Such a flow would also
|
||||
// be redundantly represented in the right_ vector as right_[1] == 3.
|
||||
// Elements of left_ and right_ are either kUnused or mutually
|
||||
// referent. Mutually referent means that left_[right_[i]] = i and
|
||||
// right_[left_[i]] = i.
|
||||
::std::vector<size_t> left_;
|
||||
::std::vector<size_t> right_;
|
||||
|
||||
GTEST_DISALLOW_ASSIGN_(MaxBipartiteMatchState);
|
||||
};
|
||||
|
||||
const size_t MaxBipartiteMatchState::kUnused;
|
||||
|
||||
GTEST_API_ ElementMatcherPairs
|
||||
FindMaxBipartiteMatching(const MatchMatrix& g) {
|
||||
return MaxBipartiteMatchState(g).Compute();
|
||||
}
|
||||
|
||||
static void LogElementMatcherPairVec(const ElementMatcherPairs& pairs,
|
||||
::std::ostream* stream) {
|
||||
typedef ElementMatcherPairs::const_iterator Iter;
|
||||
::std::ostream& os = *stream;
|
||||
os << "{";
|
||||
const char *sep = "";
|
||||
for (Iter it = pairs.begin(); it != pairs.end(); ++it) {
|
||||
os << sep << "\n ("
|
||||
<< "element #" << it->first << ", "
|
||||
<< "matcher #" << it->second << ")";
|
||||
sep = ",";
|
||||
}
|
||||
os << "\n}";
|
||||
}
|
||||
|
||||
// Tries to find a pairing, and explains the result.
|
||||
GTEST_API_ bool FindPairing(const MatchMatrix& matrix,
|
||||
MatchResultListener* listener) {
|
||||
ElementMatcherPairs matches = FindMaxBipartiteMatching(matrix);
|
||||
|
||||
size_t max_flow = matches.size();
|
||||
bool result = (max_flow == matrix.RhsSize());
|
||||
|
||||
if (!result) {
|
||||
if (listener->IsInterested()) {
|
||||
*listener << "where no permutation of the elements can "
|
||||
"satisfy all matchers, and the closest match is "
|
||||
<< max_flow << " of " << matrix.RhsSize()
|
||||
<< " matchers with the pairings:\n";
|
||||
LogElementMatcherPairVec(matches, listener->stream());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (matches.size() > 1) {
|
||||
if (listener->IsInterested()) {
|
||||
const char *sep = "where:\n";
|
||||
for (size_t mi = 0; mi < matches.size(); ++mi) {
|
||||
*listener << sep << " - element #" << matches[mi].first
|
||||
<< " is matched by matcher #" << matches[mi].second;
|
||||
sep = ",\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MatchMatrix::NextGraph() {
|
||||
for (size_t ilhs = 0; ilhs < LhsSize(); ++ilhs) {
|
||||
for (size_t irhs = 0; irhs < RhsSize(); ++irhs) {
|
||||
char& b = matched_[SpaceIndex(ilhs, irhs)];
|
||||
if (!b) {
|
||||
b = 1;
|
||||
return true;
|
||||
}
|
||||
b = 0;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void MatchMatrix::Randomize() {
|
||||
for (size_t ilhs = 0; ilhs < LhsSize(); ++ilhs) {
|
||||
for (size_t irhs = 0; irhs < RhsSize(); ++irhs) {
|
||||
char& b = matched_[SpaceIndex(ilhs, irhs)];
|
||||
b = static_cast<char>(rand() & 1); // NOLINT
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string MatchMatrix::DebugString() const {
|
||||
::std::stringstream ss;
|
||||
const char *sep = "";
|
||||
for (size_t i = 0; i < LhsSize(); ++i) {
|
||||
ss << sep;
|
||||
for (size_t j = 0; j < RhsSize(); ++j) {
|
||||
ss << HasEdge(i, j);
|
||||
}
|
||||
sep = ";";
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
void UnorderedElementsAreMatcherImplBase::DescribeToImpl(
|
||||
::std::ostream* os) const {
|
||||
if (matcher_describers_.empty()) {
|
||||
*os << "is empty";
|
||||
return;
|
||||
}
|
||||
if (matcher_describers_.size() == 1) {
|
||||
*os << "has " << Elements(1) << " and that element ";
|
||||
matcher_describers_[0]->DescribeTo(os);
|
||||
return;
|
||||
}
|
||||
*os << "has " << Elements(matcher_describers_.size())
|
||||
<< " and there exists some permutation of elements such that:\n";
|
||||
const char* sep = "";
|
||||
for (size_t i = 0; i != matcher_describers_.size(); ++i) {
|
||||
*os << sep << " - element #" << i << " ";
|
||||
matcher_describers_[i]->DescribeTo(os);
|
||||
sep = ", and\n";
|
||||
}
|
||||
}
|
||||
|
||||
void UnorderedElementsAreMatcherImplBase::DescribeNegationToImpl(
|
||||
::std::ostream* os) const {
|
||||
if (matcher_describers_.empty()) {
|
||||
*os << "isn't empty";
|
||||
return;
|
||||
}
|
||||
if (matcher_describers_.size() == 1) {
|
||||
*os << "doesn't have " << Elements(1)
|
||||
<< ", or has " << Elements(1) << " that ";
|
||||
matcher_describers_[0]->DescribeNegationTo(os);
|
||||
return;
|
||||
}
|
||||
*os << "doesn't have " << Elements(matcher_describers_.size())
|
||||
<< ", or there exists no permutation of elements such that:\n";
|
||||
const char* sep = "";
|
||||
for (size_t i = 0; i != matcher_describers_.size(); ++i) {
|
||||
*os << sep << " - element #" << i << " ";
|
||||
matcher_describers_[i]->DescribeTo(os);
|
||||
sep = ", and\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Checks that all matchers match at least one element, and that all
|
||||
// elements match at least one matcher. This enables faster matching
|
||||
// and better error reporting.
|
||||
// Returns false, writing an explanation to 'listener', if and only
|
||||
// if the success criteria are not met.
|
||||
bool UnorderedElementsAreMatcherImplBase::
|
||||
VerifyAllElementsAndMatchersAreMatched(
|
||||
const ::std::vector<string>& element_printouts,
|
||||
const MatchMatrix& matrix,
|
||||
MatchResultListener* listener) const {
|
||||
bool result = true;
|
||||
::std::vector<char> element_matched(matrix.LhsSize(), 0);
|
||||
::std::vector<char> matcher_matched(matrix.RhsSize(), 0);
|
||||
|
||||
for (size_t ilhs = 0; ilhs < matrix.LhsSize(); ilhs++) {
|
||||
for (size_t irhs = 0; irhs < matrix.RhsSize(); irhs++) {
|
||||
char matched = matrix.HasEdge(ilhs, irhs);
|
||||
element_matched[ilhs] |= matched;
|
||||
matcher_matched[irhs] |= matched;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const char* sep =
|
||||
"where the following matchers don't match any elements:\n";
|
||||
for (size_t mi = 0; mi < matcher_matched.size(); ++mi) {
|
||||
if (matcher_matched[mi])
|
||||
continue;
|
||||
result = false;
|
||||
if (listener->IsInterested()) {
|
||||
*listener << sep << "matcher #" << mi << ": ";
|
||||
matcher_describers_[mi]->DescribeTo(listener->stream());
|
||||
sep = ",\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const char* sep =
|
||||
"where the following elements don't match any matchers:\n";
|
||||
const char* outer_sep = "";
|
||||
if (!result) {
|
||||
outer_sep = "\nand ";
|
||||
}
|
||||
for (size_t ei = 0; ei < element_matched.size(); ++ei) {
|
||||
if (element_matched[ei])
|
||||
continue;
|
||||
result = false;
|
||||
if (listener->IsInterested()) {
|
||||
*listener << outer_sep << sep << "element #" << ei << ": "
|
||||
<< element_printouts[ei];
|
||||
sep = ",\n";
|
||||
outer_sep = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
813
gmock/src/gmock-spec-builders.cc
Normal file
813
gmock/src/gmock-spec-builders.cc
Normal file
@@ -0,0 +1,813 @@
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file implements the spec builder syntax (ON_CALL and
|
||||
// EXPECT_CALL).
|
||||
|
||||
#include "gmock/gmock-spec-builders.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <iostream> // NOLINT
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#if GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC
|
||||
# include <unistd.h> // NOLINT
|
||||
#endif
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// Protects the mock object registry (in class Mock), all function
|
||||
// mockers, and all expectations.
|
||||
GTEST_API_ GTEST_DEFINE_STATIC_MUTEX_(g_gmock_mutex);
|
||||
|
||||
// Logs a message including file and line number information.
|
||||
GTEST_API_ void LogWithLocation(testing::internal::LogSeverity severity,
|
||||
const char* file, int line,
|
||||
const string& message) {
|
||||
::std::ostringstream s;
|
||||
s << file << ":" << line << ": " << message << ::std::endl;
|
||||
Log(severity, s.str(), 0);
|
||||
}
|
||||
|
||||
// Constructs an ExpectationBase object.
|
||||
ExpectationBase::ExpectationBase(const char* a_file,
|
||||
int a_line,
|
||||
const string& a_source_text)
|
||||
: file_(a_file),
|
||||
line_(a_line),
|
||||
source_text_(a_source_text),
|
||||
cardinality_specified_(false),
|
||||
cardinality_(Exactly(1)),
|
||||
call_count_(0),
|
||||
retired_(false),
|
||||
extra_matcher_specified_(false),
|
||||
repeated_action_specified_(false),
|
||||
retires_on_saturation_(false),
|
||||
last_clause_(kNone),
|
||||
action_count_checked_(false) {}
|
||||
|
||||
// Destructs an ExpectationBase object.
|
||||
ExpectationBase::~ExpectationBase() {}
|
||||
|
||||
// Explicitly specifies the cardinality of this expectation. Used by
|
||||
// the subclasses to implement the .Times() clause.
|
||||
void ExpectationBase::SpecifyCardinality(const Cardinality& a_cardinality) {
|
||||
cardinality_specified_ = true;
|
||||
cardinality_ = a_cardinality;
|
||||
}
|
||||
|
||||
// Retires all pre-requisites of this expectation.
|
||||
void ExpectationBase::RetireAllPreRequisites()
|
||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
||||
if (is_retired()) {
|
||||
// We can take this short-cut as we never retire an expectation
|
||||
// until we have retired all its pre-requisites.
|
||||
return;
|
||||
}
|
||||
|
||||
for (ExpectationSet::const_iterator it = immediate_prerequisites_.begin();
|
||||
it != immediate_prerequisites_.end(); ++it) {
|
||||
ExpectationBase* const prerequisite = it->expectation_base().get();
|
||||
if (!prerequisite->is_retired()) {
|
||||
prerequisite->RetireAllPreRequisites();
|
||||
prerequisite->Retire();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Returns true iff all pre-requisites of this expectation have been
|
||||
// satisfied.
|
||||
bool ExpectationBase::AllPrerequisitesAreSatisfied() const
|
||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
||||
g_gmock_mutex.AssertHeld();
|
||||
for (ExpectationSet::const_iterator it = immediate_prerequisites_.begin();
|
||||
it != immediate_prerequisites_.end(); ++it) {
|
||||
if (!(it->expectation_base()->IsSatisfied()) ||
|
||||
!(it->expectation_base()->AllPrerequisitesAreSatisfied()))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Adds unsatisfied pre-requisites of this expectation to 'result'.
|
||||
void ExpectationBase::FindUnsatisfiedPrerequisites(ExpectationSet* result) const
|
||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
||||
g_gmock_mutex.AssertHeld();
|
||||
for (ExpectationSet::const_iterator it = immediate_prerequisites_.begin();
|
||||
it != immediate_prerequisites_.end(); ++it) {
|
||||
if (it->expectation_base()->IsSatisfied()) {
|
||||
// If *it is satisfied and has a call count of 0, some of its
|
||||
// pre-requisites may not be satisfied yet.
|
||||
if (it->expectation_base()->call_count_ == 0) {
|
||||
it->expectation_base()->FindUnsatisfiedPrerequisites(result);
|
||||
}
|
||||
} else {
|
||||
// Now that we know *it is unsatisfied, we are not so interested
|
||||
// in whether its pre-requisites are satisfied. Therefore we
|
||||
// don't recursively call FindUnsatisfiedPrerequisites() here.
|
||||
*result += *it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Describes how many times a function call matching this
|
||||
// expectation has occurred.
|
||||
void ExpectationBase::DescribeCallCountTo(::std::ostream* os) const
|
||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
||||
g_gmock_mutex.AssertHeld();
|
||||
|
||||
// Describes how many times the function is expected to be called.
|
||||
*os << " Expected: to be ";
|
||||
cardinality().DescribeTo(os);
|
||||
*os << "\n Actual: ";
|
||||
Cardinality::DescribeActualCallCountTo(call_count(), os);
|
||||
|
||||
// Describes the state of the expectation (e.g. is it satisfied?
|
||||
// is it active?).
|
||||
*os << " - " << (IsOverSaturated() ? "over-saturated" :
|
||||
IsSaturated() ? "saturated" :
|
||||
IsSatisfied() ? "satisfied" : "unsatisfied")
|
||||
<< " and "
|
||||
<< (is_retired() ? "retired" : "active");
|
||||
}
|
||||
|
||||
// Checks the action count (i.e. the number of WillOnce() and
|
||||
// WillRepeatedly() clauses) against the cardinality if this hasn't
|
||||
// been done before. Prints a warning if there are too many or too
|
||||
// few actions.
|
||||
void ExpectationBase::CheckActionCountIfNotDone() const
|
||||
GTEST_LOCK_EXCLUDED_(mutex_) {
|
||||
bool should_check = false;
|
||||
{
|
||||
MutexLock l(&mutex_);
|
||||
if (!action_count_checked_) {
|
||||
action_count_checked_ = true;
|
||||
should_check = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (should_check) {
|
||||
if (!cardinality_specified_) {
|
||||
// The cardinality was inferred - no need to check the action
|
||||
// count against it.
|
||||
return;
|
||||
}
|
||||
|
||||
// The cardinality was explicitly specified.
|
||||
const int action_count = static_cast<int>(untyped_actions_.size());
|
||||
const int upper_bound = cardinality().ConservativeUpperBound();
|
||||
const int lower_bound = cardinality().ConservativeLowerBound();
|
||||
bool too_many; // True if there are too many actions, or false
|
||||
// if there are too few.
|
||||
if (action_count > upper_bound ||
|
||||
(action_count == upper_bound && repeated_action_specified_)) {
|
||||
too_many = true;
|
||||
} else if (0 < action_count && action_count < lower_bound &&
|
||||
!repeated_action_specified_) {
|
||||
too_many = false;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
::std::stringstream ss;
|
||||
DescribeLocationTo(&ss);
|
||||
ss << "Too " << (too_many ? "many" : "few")
|
||||
<< " actions specified in " << source_text() << "...\n"
|
||||
<< "Expected to be ";
|
||||
cardinality().DescribeTo(&ss);
|
||||
ss << ", but has " << (too_many ? "" : "only ")
|
||||
<< action_count << " WillOnce()"
|
||||
<< (action_count == 1 ? "" : "s");
|
||||
if (repeated_action_specified_) {
|
||||
ss << " and a WillRepeatedly()";
|
||||
}
|
||||
ss << ".";
|
||||
Log(kWarning, ss.str(), -1); // -1 means "don't print stack trace".
|
||||
}
|
||||
}
|
||||
|
||||
// Implements the .Times() clause.
|
||||
void ExpectationBase::UntypedTimes(const Cardinality& a_cardinality) {
|
||||
if (last_clause_ == kTimes) {
|
||||
ExpectSpecProperty(false,
|
||||
".Times() cannot appear "
|
||||
"more than once in an EXPECT_CALL().");
|
||||
} else {
|
||||
ExpectSpecProperty(last_clause_ < kTimes,
|
||||
".Times() cannot appear after "
|
||||
".InSequence(), .WillOnce(), .WillRepeatedly(), "
|
||||
"or .RetiresOnSaturation().");
|
||||
}
|
||||
last_clause_ = kTimes;
|
||||
|
||||
SpecifyCardinality(a_cardinality);
|
||||
}
|
||||
|
||||
// Points to the implicit sequence introduced by a living InSequence
|
||||
// object (if any) in the current thread or NULL.
|
||||
GTEST_API_ ThreadLocal<Sequence*> g_gmock_implicit_sequence;
|
||||
|
||||
// Reports an uninteresting call (whose description is in msg) in the
|
||||
// manner specified by 'reaction'.
|
||||
void ReportUninterestingCall(CallReaction reaction, const string& msg) {
|
||||
switch (reaction) {
|
||||
case kAllow:
|
||||
Log(kInfo, msg, 3);
|
||||
break;
|
||||
case kWarn:
|
||||
Log(kWarning, msg, 3);
|
||||
break;
|
||||
default: // FAIL
|
||||
Expect(false, NULL, -1, msg);
|
||||
}
|
||||
}
|
||||
|
||||
UntypedFunctionMockerBase::UntypedFunctionMockerBase()
|
||||
: mock_obj_(NULL), name_("") {}
|
||||
|
||||
UntypedFunctionMockerBase::~UntypedFunctionMockerBase() {}
|
||||
|
||||
// Sets the mock object this mock method belongs to, and registers
|
||||
// this information in the global mock registry. Will be called
|
||||
// whenever an EXPECT_CALL() or ON_CALL() is executed on this mock
|
||||
// method.
|
||||
void UntypedFunctionMockerBase::RegisterOwner(const void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||
{
|
||||
MutexLock l(&g_gmock_mutex);
|
||||
mock_obj_ = mock_obj;
|
||||
}
|
||||
Mock::Register(mock_obj, this);
|
||||
}
|
||||
|
||||
// Sets the mock object this mock method belongs to, and sets the name
|
||||
// of the mock function. Will be called upon each invocation of this
|
||||
// mock function.
|
||||
void UntypedFunctionMockerBase::SetOwnerAndName(const void* mock_obj,
|
||||
const char* name)
|
||||
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||
// We protect name_ under g_gmock_mutex in case this mock function
|
||||
// is called from two threads concurrently.
|
||||
MutexLock l(&g_gmock_mutex);
|
||||
mock_obj_ = mock_obj;
|
||||
name_ = name;
|
||||
}
|
||||
|
||||
// Returns the name of the function being mocked. Must be called
|
||||
// after RegisterOwner() or SetOwnerAndName() has been called.
|
||||
const void* UntypedFunctionMockerBase::MockObject() const
|
||||
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||
const void* mock_obj;
|
||||
{
|
||||
// We protect mock_obj_ under g_gmock_mutex in case this mock
|
||||
// function is called from two threads concurrently.
|
||||
MutexLock l(&g_gmock_mutex);
|
||||
Assert(mock_obj_ != NULL, __FILE__, __LINE__,
|
||||
"MockObject() must not be called before RegisterOwner() or "
|
||||
"SetOwnerAndName() has been called.");
|
||||
mock_obj = mock_obj_;
|
||||
}
|
||||
return mock_obj;
|
||||
}
|
||||
|
||||
// Returns the name of this mock method. Must be called after
|
||||
// SetOwnerAndName() has been called.
|
||||
const char* UntypedFunctionMockerBase::Name() const
|
||||
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||
const char* name;
|
||||
{
|
||||
// We protect name_ under g_gmock_mutex in case this mock
|
||||
// function is called from two threads concurrently.
|
||||
MutexLock l(&g_gmock_mutex);
|
||||
Assert(name_ != NULL, __FILE__, __LINE__,
|
||||
"Name() must not be called before SetOwnerAndName() has "
|
||||
"been called.");
|
||||
name = name_;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
// Calculates the result of invoking this mock function with the given
|
||||
// arguments, prints it, and returns it. The caller is responsible
|
||||
// for deleting the result.
|
||||
const UntypedActionResultHolderBase*
|
||||
UntypedFunctionMockerBase::UntypedInvokeWith(const void* const untyped_args)
|
||||
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||
if (untyped_expectations_.size() == 0) {
|
||||
// No expectation is set on this mock method - we have an
|
||||
// uninteresting call.
|
||||
|
||||
// We must get Google Mock's reaction on uninteresting calls
|
||||
// made on this mock object BEFORE performing the action,
|
||||
// because the action may DELETE the mock object and make the
|
||||
// following expression meaningless.
|
||||
const CallReaction reaction =
|
||||
Mock::GetReactionOnUninterestingCalls(MockObject());
|
||||
|
||||
// True iff we need to print this call's arguments and return
|
||||
// value. This definition must be kept in sync with
|
||||
// the behavior of ReportUninterestingCall().
|
||||
const bool need_to_report_uninteresting_call =
|
||||
// If the user allows this uninteresting call, we print it
|
||||
// only when he wants informational messages.
|
||||
reaction == kAllow ? LogIsVisible(kInfo) :
|
||||
// If the user wants this to be a warning, we print it only
|
||||
// when he wants to see warnings.
|
||||
reaction == kWarn ? LogIsVisible(kWarning) :
|
||||
// Otherwise, the user wants this to be an error, and we
|
||||
// should always print detailed information in the error.
|
||||
true;
|
||||
|
||||
if (!need_to_report_uninteresting_call) {
|
||||
// Perform the action without printing the call information.
|
||||
return this->UntypedPerformDefaultAction(untyped_args, "");
|
||||
}
|
||||
|
||||
// Warns about the uninteresting call.
|
||||
::std::stringstream ss;
|
||||
this->UntypedDescribeUninterestingCall(untyped_args, &ss);
|
||||
|
||||
// Calculates the function result.
|
||||
const UntypedActionResultHolderBase* const result =
|
||||
this->UntypedPerformDefaultAction(untyped_args, ss.str());
|
||||
|
||||
// Prints the function result.
|
||||
if (result != NULL)
|
||||
result->PrintAsActionResult(&ss);
|
||||
|
||||
ReportUninterestingCall(reaction, ss.str());
|
||||
return result;
|
||||
}
|
||||
|
||||
bool is_excessive = false;
|
||||
::std::stringstream ss;
|
||||
::std::stringstream why;
|
||||
::std::stringstream loc;
|
||||
const void* untyped_action = NULL;
|
||||
|
||||
// The UntypedFindMatchingExpectation() function acquires and
|
||||
// releases g_gmock_mutex.
|
||||
const ExpectationBase* const untyped_expectation =
|
||||
this->UntypedFindMatchingExpectation(
|
||||
untyped_args, &untyped_action, &is_excessive,
|
||||
&ss, &why);
|
||||
const bool found = untyped_expectation != NULL;
|
||||
|
||||
// True iff we need to print the call's arguments and return value.
|
||||
// This definition must be kept in sync with the uses of Expect()
|
||||
// and Log() in this function.
|
||||
const bool need_to_report_call =
|
||||
!found || is_excessive || LogIsVisible(kInfo);
|
||||
if (!need_to_report_call) {
|
||||
// Perform the action without printing the call information.
|
||||
return
|
||||
untyped_action == NULL ?
|
||||
this->UntypedPerformDefaultAction(untyped_args, "") :
|
||||
this->UntypedPerformAction(untyped_action, untyped_args);
|
||||
}
|
||||
|
||||
ss << " Function call: " << Name();
|
||||
this->UntypedPrintArgs(untyped_args, &ss);
|
||||
|
||||
// In case the action deletes a piece of the expectation, we
|
||||
// generate the message beforehand.
|
||||
if (found && !is_excessive) {
|
||||
untyped_expectation->DescribeLocationTo(&loc);
|
||||
}
|
||||
|
||||
const UntypedActionResultHolderBase* const result =
|
||||
untyped_action == NULL ?
|
||||
this->UntypedPerformDefaultAction(untyped_args, ss.str()) :
|
||||
this->UntypedPerformAction(untyped_action, untyped_args);
|
||||
if (result != NULL)
|
||||
result->PrintAsActionResult(&ss);
|
||||
ss << "\n" << why.str();
|
||||
|
||||
if (!found) {
|
||||
// No expectation matches this call - reports a failure.
|
||||
Expect(false, NULL, -1, ss.str());
|
||||
} else if (is_excessive) {
|
||||
// We had an upper-bound violation and the failure message is in ss.
|
||||
Expect(false, untyped_expectation->file(),
|
||||
untyped_expectation->line(), ss.str());
|
||||
} else {
|
||||
// We had an expected call and the matching expectation is
|
||||
// described in ss.
|
||||
Log(kInfo, loc.str() + ss.str(), 2);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Returns an Expectation object that references and co-owns exp,
|
||||
// which must be an expectation on this mock function.
|
||||
Expectation UntypedFunctionMockerBase::GetHandleOf(ExpectationBase* exp) {
|
||||
for (UntypedExpectations::const_iterator it =
|
||||
untyped_expectations_.begin();
|
||||
it != untyped_expectations_.end(); ++it) {
|
||||
if (it->get() == exp) {
|
||||
return Expectation(*it);
|
||||
}
|
||||
}
|
||||
|
||||
Assert(false, __FILE__, __LINE__, "Cannot find expectation.");
|
||||
return Expectation();
|
||||
// The above statement is just to make the code compile, and will
|
||||
// never be executed.
|
||||
}
|
||||
|
||||
// Verifies that all expectations on this mock function have been
|
||||
// satisfied. Reports one or more Google Test non-fatal failures
|
||||
// and returns false if not.
|
||||
bool UntypedFunctionMockerBase::VerifyAndClearExpectationsLocked()
|
||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
||||
g_gmock_mutex.AssertHeld();
|
||||
bool expectations_met = true;
|
||||
for (UntypedExpectations::const_iterator it =
|
||||
untyped_expectations_.begin();
|
||||
it != untyped_expectations_.end(); ++it) {
|
||||
ExpectationBase* const untyped_expectation = it->get();
|
||||
if (untyped_expectation->IsOverSaturated()) {
|
||||
// There was an upper-bound violation. Since the error was
|
||||
// already reported when it occurred, there is no need to do
|
||||
// anything here.
|
||||
expectations_met = false;
|
||||
} else if (!untyped_expectation->IsSatisfied()) {
|
||||
expectations_met = false;
|
||||
::std::stringstream ss;
|
||||
ss << "Actual function call count doesn't match "
|
||||
<< untyped_expectation->source_text() << "...\n";
|
||||
// No need to show the source file location of the expectation
|
||||
// in the description, as the Expect() call that follows already
|
||||
// takes care of it.
|
||||
untyped_expectation->MaybeDescribeExtraMatcherTo(&ss);
|
||||
untyped_expectation->DescribeCallCountTo(&ss);
|
||||
Expect(false, untyped_expectation->file(),
|
||||
untyped_expectation->line(), ss.str());
|
||||
}
|
||||
}
|
||||
|
||||
// Deleting our expectations may trigger other mock objects to be deleted, for
|
||||
// example if an action contains a reference counted smart pointer to that
|
||||
// mock object, and that is the last reference. So if we delete our
|
||||
// expectations within the context of the global mutex we may deadlock when
|
||||
// this method is called again. Instead, make a copy of the set of
|
||||
// expectations to delete, clear our set within the mutex, and then clear the
|
||||
// copied set outside of it.
|
||||
UntypedExpectations expectations_to_delete;
|
||||
untyped_expectations_.swap(expectations_to_delete);
|
||||
|
||||
g_gmock_mutex.Unlock();
|
||||
expectations_to_delete.clear();
|
||||
g_gmock_mutex.Lock();
|
||||
|
||||
return expectations_met;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// Class Mock.
|
||||
|
||||
namespace {
|
||||
|
||||
typedef std::set<internal::UntypedFunctionMockerBase*> FunctionMockers;
|
||||
|
||||
// The current state of a mock object. Such information is needed for
|
||||
// detecting leaked mock objects and explicitly verifying a mock's
|
||||
// expectations.
|
||||
struct MockObjectState {
|
||||
MockObjectState()
|
||||
: first_used_file(NULL), first_used_line(-1), leakable(false) {}
|
||||
|
||||
// Where in the source file an ON_CALL or EXPECT_CALL is first
|
||||
// invoked on this mock object.
|
||||
const char* first_used_file;
|
||||
int first_used_line;
|
||||
::std::string first_used_test_case;
|
||||
::std::string first_used_test;
|
||||
bool leakable; // true iff it's OK to leak the object.
|
||||
FunctionMockers function_mockers; // All registered methods of the object.
|
||||
};
|
||||
|
||||
// A global registry holding the state of all mock objects that are
|
||||
// alive. A mock object is added to this registry the first time
|
||||
// Mock::AllowLeak(), ON_CALL(), or EXPECT_CALL() is called on it. It
|
||||
// is removed from the registry in the mock object's destructor.
|
||||
class MockObjectRegistry {
|
||||
public:
|
||||
// Maps a mock object (identified by its address) to its state.
|
||||
typedef std::map<const void*, MockObjectState> StateMap;
|
||||
|
||||
// This destructor will be called when a program exits, after all
|
||||
// tests in it have been run. By then, there should be no mock
|
||||
// object alive. Therefore we report any living object as test
|
||||
// failure, unless the user explicitly asked us to ignore it.
|
||||
~MockObjectRegistry() {
|
||||
// "using ::std::cout;" doesn't work with Symbian's STLport, where cout is
|
||||
// a macro.
|
||||
|
||||
if (!GMOCK_FLAG(catch_leaked_mocks))
|
||||
return;
|
||||
|
||||
int leaked_count = 0;
|
||||
for (StateMap::const_iterator it = states_.begin(); it != states_.end();
|
||||
++it) {
|
||||
if (it->second.leakable) // The user said it's fine to leak this object.
|
||||
continue;
|
||||
|
||||
// TODO(wan@google.com): Print the type of the leaked object.
|
||||
// This can help the user identify the leaked object.
|
||||
std::cout << "\n";
|
||||
const MockObjectState& state = it->second;
|
||||
std::cout << internal::FormatFileLocation(state.first_used_file,
|
||||
state.first_used_line);
|
||||
std::cout << " ERROR: this mock object";
|
||||
if (state.first_used_test != "") {
|
||||
std::cout << " (used in test " << state.first_used_test_case << "."
|
||||
<< state.first_used_test << ")";
|
||||
}
|
||||
std::cout << " should be deleted but never is. Its address is @"
|
||||
<< it->first << ".";
|
||||
leaked_count++;
|
||||
}
|
||||
if (leaked_count > 0) {
|
||||
std::cout << "\nERROR: " << leaked_count
|
||||
<< " leaked mock " << (leaked_count == 1 ? "object" : "objects")
|
||||
<< " found at program exit.\n";
|
||||
std::cout.flush();
|
||||
::std::cerr.flush();
|
||||
// RUN_ALL_TESTS() has already returned when this destructor is
|
||||
// called. Therefore we cannot use the normal Google Test
|
||||
// failure reporting mechanism.
|
||||
_exit(1); // We cannot call exit() as it is not reentrant and
|
||||
// may already have been called.
|
||||
}
|
||||
}
|
||||
|
||||
StateMap& states() { return states_; }
|
||||
|
||||
private:
|
||||
StateMap states_;
|
||||
};
|
||||
|
||||
// Protected by g_gmock_mutex.
|
||||
MockObjectRegistry g_mock_object_registry;
|
||||
|
||||
// Maps a mock object to the reaction Google Mock should have when an
|
||||
// uninteresting method is called. Protected by g_gmock_mutex.
|
||||
std::map<const void*, internal::CallReaction> g_uninteresting_call_reaction;
|
||||
|
||||
// Sets the reaction Google Mock should have when an uninteresting
|
||||
// method of the given mock object is called.
|
||||
void SetReactionOnUninterestingCalls(const void* mock_obj,
|
||||
internal::CallReaction reaction)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
g_uninteresting_call_reaction[mock_obj] = reaction;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// Tells Google Mock to allow uninteresting calls on the given mock
|
||||
// object.
|
||||
void Mock::AllowUninterestingCalls(const void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
SetReactionOnUninterestingCalls(mock_obj, internal::kAllow);
|
||||
}
|
||||
|
||||
// Tells Google Mock to warn the user about uninteresting calls on the
|
||||
// given mock object.
|
||||
void Mock::WarnUninterestingCalls(const void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
SetReactionOnUninterestingCalls(mock_obj, internal::kWarn);
|
||||
}
|
||||
|
||||
// Tells Google Mock to fail uninteresting calls on the given mock
|
||||
// object.
|
||||
void Mock::FailUninterestingCalls(const void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
SetReactionOnUninterestingCalls(mock_obj, internal::kFail);
|
||||
}
|
||||
|
||||
// Tells Google Mock the given mock object is being destroyed and its
|
||||
// entry in the call-reaction table should be removed.
|
||||
void Mock::UnregisterCallReaction(const void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
g_uninteresting_call_reaction.erase(mock_obj);
|
||||
}
|
||||
|
||||
// Returns the reaction Google Mock will have on uninteresting calls
|
||||
// made on the given mock object.
|
||||
internal::CallReaction Mock::GetReactionOnUninterestingCalls(
|
||||
const void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
return (g_uninteresting_call_reaction.count(mock_obj) == 0) ?
|
||||
internal::kDefault : g_uninteresting_call_reaction[mock_obj];
|
||||
}
|
||||
|
||||
// Tells Google Mock to ignore mock_obj when checking for leaked mock
|
||||
// objects.
|
||||
void Mock::AllowLeak(const void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
g_mock_object_registry.states()[mock_obj].leakable = true;
|
||||
}
|
||||
|
||||
// Verifies and clears all expectations on the given mock object. If
|
||||
// the expectations aren't satisfied, generates one or more Google
|
||||
// Test non-fatal failures and returns false.
|
||||
bool Mock::VerifyAndClearExpectations(void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
return VerifyAndClearExpectationsLocked(mock_obj);
|
||||
}
|
||||
|
||||
// Verifies all expectations on the given mock object and clears its
|
||||
// default actions and expectations. Returns true iff the
|
||||
// verification was successful.
|
||||
bool Mock::VerifyAndClear(void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
ClearDefaultActionsLocked(mock_obj);
|
||||
return VerifyAndClearExpectationsLocked(mock_obj);
|
||||
}
|
||||
|
||||
// Verifies and clears all expectations on the given mock object. If
|
||||
// the expectations aren't satisfied, generates one or more Google
|
||||
// Test non-fatal failures and returns false.
|
||||
bool Mock::VerifyAndClearExpectationsLocked(void* mock_obj)
|
||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) {
|
||||
internal::g_gmock_mutex.AssertHeld();
|
||||
if (g_mock_object_registry.states().count(mock_obj) == 0) {
|
||||
// No EXPECT_CALL() was set on the given mock object.
|
||||
return true;
|
||||
}
|
||||
|
||||
// Verifies and clears the expectations on each mock method in the
|
||||
// given mock object.
|
||||
bool expectations_met = true;
|
||||
FunctionMockers& mockers =
|
||||
g_mock_object_registry.states()[mock_obj].function_mockers;
|
||||
for (FunctionMockers::const_iterator it = mockers.begin();
|
||||
it != mockers.end(); ++it) {
|
||||
if (!(*it)->VerifyAndClearExpectationsLocked()) {
|
||||
expectations_met = false;
|
||||
}
|
||||
}
|
||||
|
||||
// We don't clear the content of mockers, as they may still be
|
||||
// needed by ClearDefaultActionsLocked().
|
||||
return expectations_met;
|
||||
}
|
||||
|
||||
// Registers a mock object and a mock method it owns.
|
||||
void Mock::Register(const void* mock_obj,
|
||||
internal::UntypedFunctionMockerBase* mocker)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
g_mock_object_registry.states()[mock_obj].function_mockers.insert(mocker);
|
||||
}
|
||||
|
||||
// Tells Google Mock where in the source code mock_obj is used in an
|
||||
// ON_CALL or EXPECT_CALL. In case mock_obj is leaked, this
|
||||
// information helps the user identify which object it is.
|
||||
void Mock::RegisterUseByOnCallOrExpectCall(const void* mock_obj,
|
||||
const char* file, int line)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
MockObjectState& state = g_mock_object_registry.states()[mock_obj];
|
||||
if (state.first_used_file == NULL) {
|
||||
state.first_used_file = file;
|
||||
state.first_used_line = line;
|
||||
const TestInfo* const test_info =
|
||||
UnitTest::GetInstance()->current_test_info();
|
||||
if (test_info != NULL) {
|
||||
// TODO(wan@google.com): record the test case name when the
|
||||
// ON_CALL or EXPECT_CALL is invoked from SetUpTestCase() or
|
||||
// TearDownTestCase().
|
||||
state.first_used_test_case = test_info->test_case_name();
|
||||
state.first_used_test = test_info->name();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Unregisters a mock method; removes the owning mock object from the
|
||||
// registry when the last mock method associated with it has been
|
||||
// unregistered. This is called only in the destructor of
|
||||
// FunctionMockerBase.
|
||||
void Mock::UnregisterLocked(internal::UntypedFunctionMockerBase* mocker)
|
||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) {
|
||||
internal::g_gmock_mutex.AssertHeld();
|
||||
for (MockObjectRegistry::StateMap::iterator it =
|
||||
g_mock_object_registry.states().begin();
|
||||
it != g_mock_object_registry.states().end(); ++it) {
|
||||
FunctionMockers& mockers = it->second.function_mockers;
|
||||
if (mockers.erase(mocker) > 0) {
|
||||
// mocker was in mockers and has been just removed.
|
||||
if (mockers.empty()) {
|
||||
g_mock_object_registry.states().erase(it);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clears all ON_CALL()s set on the given mock object.
|
||||
void Mock::ClearDefaultActionsLocked(void* mock_obj)
|
||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) {
|
||||
internal::g_gmock_mutex.AssertHeld();
|
||||
|
||||
if (g_mock_object_registry.states().count(mock_obj) == 0) {
|
||||
// No ON_CALL() was set on the given mock object.
|
||||
return;
|
||||
}
|
||||
|
||||
// Clears the default actions for each mock method in the given mock
|
||||
// object.
|
||||
FunctionMockers& mockers =
|
||||
g_mock_object_registry.states()[mock_obj].function_mockers;
|
||||
for (FunctionMockers::const_iterator it = mockers.begin();
|
||||
it != mockers.end(); ++it) {
|
||||
(*it)->ClearDefaultActionsLocked();
|
||||
}
|
||||
|
||||
// We don't clear the content of mockers, as they may still be
|
||||
// needed by VerifyAndClearExpectationsLocked().
|
||||
}
|
||||
|
||||
Expectation::Expectation() {}
|
||||
|
||||
Expectation::Expectation(
|
||||
const internal::linked_ptr<internal::ExpectationBase>& an_expectation_base)
|
||||
: expectation_base_(an_expectation_base) {}
|
||||
|
||||
Expectation::~Expectation() {}
|
||||
|
||||
// Adds an expectation to a sequence.
|
||||
void Sequence::AddExpectation(const Expectation& expectation) const {
|
||||
if (*last_expectation_ != expectation) {
|
||||
if (last_expectation_->expectation_base() != NULL) {
|
||||
expectation.expectation_base()->immediate_prerequisites_
|
||||
+= *last_expectation_;
|
||||
}
|
||||
*last_expectation_ = expectation;
|
||||
}
|
||||
}
|
||||
|
||||
// Creates the implicit sequence if there isn't one.
|
||||
InSequence::InSequence() {
|
||||
if (internal::g_gmock_implicit_sequence.get() == NULL) {
|
||||
internal::g_gmock_implicit_sequence.set(new Sequence);
|
||||
sequence_created_ = true;
|
||||
} else {
|
||||
sequence_created_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Deletes the implicit sequence if it was created by the constructor
|
||||
// of this object.
|
||||
InSequence::~InSequence() {
|
||||
if (sequence_created_) {
|
||||
delete internal::g_gmock_implicit_sequence.get();
|
||||
internal::g_gmock_implicit_sequence.set(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
182
gmock/src/gmock.cc
Normal file
182
gmock/src/gmock.cc
Normal file
@@ -0,0 +1,182 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gmock/internal/gmock-port.h"
|
||||
|
||||
namespace testing {
|
||||
|
||||
// TODO(wan@google.com): support using environment variables to
|
||||
// control the flag values, like what Google Test does.
|
||||
|
||||
GMOCK_DEFINE_bool_(catch_leaked_mocks, true,
|
||||
"true iff Google Mock should report leaked mock objects "
|
||||
"as failures.");
|
||||
|
||||
GMOCK_DEFINE_string_(verbose, internal::kWarningVerbosity,
|
||||
"Controls how verbose Google Mock's output is."
|
||||
" Valid values:\n"
|
||||
" info - prints all messages.\n"
|
||||
" warning - prints warnings and errors.\n"
|
||||
" error - prints errors only.");
|
||||
|
||||
namespace internal {
|
||||
|
||||
// Parses a string as a command line flag. The string should have the
|
||||
// format "--gmock_flag=value". When def_optional is true, the
|
||||
// "=value" part can be omitted.
|
||||
//
|
||||
// Returns the value of the flag, or NULL if the parsing failed.
|
||||
static const char* ParseGoogleMockFlagValue(const char* str,
|
||||
const char* flag,
|
||||
bool def_optional) {
|
||||
// str and flag must not be NULL.
|
||||
if (str == NULL || flag == NULL) return NULL;
|
||||
|
||||
// The flag must start with "--gmock_".
|
||||
const std::string flag_str = std::string("--gmock_") + flag;
|
||||
const size_t flag_len = flag_str.length();
|
||||
if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL;
|
||||
|
||||
// Skips the flag name.
|
||||
const char* flag_end = str + flag_len;
|
||||
|
||||
// When def_optional is true, it's OK to not have a "=value" part.
|
||||
if (def_optional && (flag_end[0] == '\0')) {
|
||||
return flag_end;
|
||||
}
|
||||
|
||||
// If def_optional is true and there are more characters after the
|
||||
// flag name, or if def_optional is false, there must be a '=' after
|
||||
// the flag name.
|
||||
if (flag_end[0] != '=') return NULL;
|
||||
|
||||
// Returns the string after "=".
|
||||
return flag_end + 1;
|
||||
}
|
||||
|
||||
// Parses a string for a Google Mock bool flag, in the form of
|
||||
// "--gmock_flag=value".
|
||||
//
|
||||
// On success, stores the value of the flag in *value, and returns
|
||||
// true. On failure, returns false without changing *value.
|
||||
static bool ParseGoogleMockBoolFlag(const char* str, const char* flag,
|
||||
bool* value) {
|
||||
// Gets the value of the flag as a string.
|
||||
const char* const value_str = ParseGoogleMockFlagValue(str, flag, true);
|
||||
|
||||
// Aborts if the parsing failed.
|
||||
if (value_str == NULL) return false;
|
||||
|
||||
// Converts the string value to a bool.
|
||||
*value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F');
|
||||
return true;
|
||||
}
|
||||
|
||||
// Parses a string for a Google Mock string flag, in the form of
|
||||
// "--gmock_flag=value".
|
||||
//
|
||||
// On success, stores the value of the flag in *value, and returns
|
||||
// true. On failure, returns false without changing *value.
|
||||
static bool ParseGoogleMockStringFlag(const char* str, const char* flag,
|
||||
std::string* value) {
|
||||
// Gets the value of the flag as a string.
|
||||
const char* const value_str = ParseGoogleMockFlagValue(str, flag, false);
|
||||
|
||||
// Aborts if the parsing failed.
|
||||
if (value_str == NULL) return false;
|
||||
|
||||
// Sets *value to the value of the flag.
|
||||
*value = value_str;
|
||||
return true;
|
||||
}
|
||||
|
||||
// The internal implementation of InitGoogleMock().
|
||||
//
|
||||
// The type parameter CharType can be instantiated to either char or
|
||||
// wchar_t.
|
||||
template <typename CharType>
|
||||
void InitGoogleMockImpl(int* argc, CharType** argv) {
|
||||
// Makes sure Google Test is initialized. InitGoogleTest() is
|
||||
// idempotent, so it's fine if the user has already called it.
|
||||
InitGoogleTest(argc, argv);
|
||||
if (*argc <= 0) return;
|
||||
|
||||
for (int i = 1; i != *argc; i++) {
|
||||
const std::string arg_string = StreamableToString(argv[i]);
|
||||
const char* const arg = arg_string.c_str();
|
||||
|
||||
// Do we see a Google Mock flag?
|
||||
if (ParseGoogleMockBoolFlag(arg, "catch_leaked_mocks",
|
||||
&GMOCK_FLAG(catch_leaked_mocks)) ||
|
||||
ParseGoogleMockStringFlag(arg, "verbose", &GMOCK_FLAG(verbose))) {
|
||||
// Yes. Shift the remainder of the argv list left by one. Note
|
||||
// that argv has (*argc + 1) elements, the last one always being
|
||||
// NULL. The following loop moves the trailing NULL element as
|
||||
// well.
|
||||
for (int j = i; j != *argc; j++) {
|
||||
argv[j] = argv[j + 1];
|
||||
}
|
||||
|
||||
// Decrements the argument count.
|
||||
(*argc)--;
|
||||
|
||||
// We also need to decrement the iterator as we just removed
|
||||
// an element.
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// Initializes Google Mock. This must be called before running the
|
||||
// tests. In particular, it parses a command line for the flags that
|
||||
// Google Mock recognizes. Whenever a Google Mock flag is seen, it is
|
||||
// removed from argv, and *argc is decremented.
|
||||
//
|
||||
// No value is returned. Instead, the Google Mock flag variables are
|
||||
// updated.
|
||||
//
|
||||
// Since Google Test is needed for Google Mock to work, this function
|
||||
// also initializes Google Test and parses its flags, if that hasn't
|
||||
// been done.
|
||||
GTEST_API_ void InitGoogleMock(int* argc, char** argv) {
|
||||
internal::InitGoogleMockImpl(argc, argv);
|
||||
}
|
||||
|
||||
// This overloaded version can be used in Windows programs compiled in
|
||||
// UNICODE mode.
|
||||
GTEST_API_ void InitGoogleMock(int* argc, wchar_t** argv) {
|
||||
internal::InitGoogleMockImpl(argc, argv);
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
54
gmock/src/gmock_main.cc
Normal file
54
gmock/src/gmock_main.cc
Normal file
@@ -0,0 +1,54 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
#include <iostream>
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
// MS C++ compiler/linker has a bug on Windows (not on Windows CE), which
|
||||
// causes a link error when _tmain is defined in a static library and UNICODE
|
||||
// is enabled. For this reason instead of _tmain, main function is used on
|
||||
// Windows. See the following link to track the current status of this bug:
|
||||
// http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=394464 // NOLINT
|
||||
#if GTEST_OS_WINDOWS_MOBILE
|
||||
# include <tchar.h> // NOLINT
|
||||
|
||||
GTEST_API_ int _tmain(int argc, TCHAR** argv) {
|
||||
#else
|
||||
GTEST_API_ int main(int argc, char** argv) {
|
||||
#endif // GTEST_OS_WINDOWS_MOBILE
|
||||
std::cout << "Running main() from gmock_main.cc\n";
|
||||
// Since Google Mock depends on Google Test, InitGoogleMock() is
|
||||
// also responsible for initializing Google Test. Therefore there's
|
||||
// no need for calling testing::InitGoogleTest() separately.
|
||||
testing::InitGoogleMock(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
11
gradle/wrapper/gradle-wrapper.properties
vendored
11
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,5 @@
|
||||
#Sat Nov 21 18:19:09 EST 2015
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.8-bin.zip
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-bin.zip
|
||||
|
||||
104
gradlew
vendored
104
gradlew
vendored
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
#!/usr/bin/env sh
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
@@ -6,42 +6,6 @@
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn ( ) {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die ( ) {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
esac
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
@@ -56,9 +20,49 @@ while [ -h "$PRG" ] ; do
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >&-
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >&-
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
@@ -85,7 +89,7 @@ location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
@@ -150,11 +154,19 @@ if $cygwin ; then
|
||||
esac
|
||||
fi
|
||||
|
||||
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||
function splitJvmOpts() {
|
||||
JVM_OPTS=("$@")
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||
APP_ARGS=$(save "$@")
|
||||
|
||||
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
|
||||
14
gradlew.bat
vendored
14
gradlew.bat
vendored
@@ -8,14 +8,14 @@
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
@@ -46,10 +46,9 @@ echo location of your Java installation.
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windowz variants
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
@@ -60,11 +59,6 @@ set _SKIP=2
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
goto execute
|
||||
|
||||
:4NT_args
|
||||
@rem Get arguments from the 4NT Shell from JP Software
|
||||
set CMD_LINE_ARGS=%$
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
43
hal/.styleguide
Normal file
43
hal/.styleguide
Normal file
@@ -0,0 +1,43 @@
|
||||
cppHeaderFileInclude {
|
||||
\.h$
|
||||
\.hpp$
|
||||
\.inc$
|
||||
}
|
||||
|
||||
cppSrcFileInclude {
|
||||
\.cpp$
|
||||
}
|
||||
|
||||
generatedFileExclude {
|
||||
gmock/
|
||||
ni-libraries/include/
|
||||
ni-libraries/lib/
|
||||
hal/src/main/native/athena/ctre/
|
||||
hal/src/main/native/athena/frccansae/
|
||||
hal/src/main/native/athena/visa/
|
||||
hal/src/main/native/include/ctre/
|
||||
UsageReporting\.h$
|
||||
}
|
||||
|
||||
modifiableFileExclude {
|
||||
wpilibj/src/arm-linux-jni/
|
||||
wpilibj/src/main/native/cpp/
|
||||
\.patch$
|
||||
\.png$
|
||||
\.py$
|
||||
\.so$
|
||||
}
|
||||
|
||||
includeOtherLibs {
|
||||
^FRC_FPGA_ChipObject/
|
||||
^FRC_NetworkCommunication/
|
||||
^i2clib/
|
||||
^llvm/
|
||||
^opencv2/
|
||||
^spilib/
|
||||
^support/
|
||||
}
|
||||
|
||||
includeProject {
|
||||
^ctre/
|
||||
}
|
||||
249
hal/build.gradle
249
hal/build.gradle
@@ -1,47 +1,222 @@
|
||||
// There are two hal libraries that are built
|
||||
// - Desktop which is used by simulation (gcc/msvc)
|
||||
// - Athena which is used by the roborio (arm)
|
||||
|
||||
apply plugin: 'cpp'
|
||||
apply plugin: 'google-test'
|
||||
apply plugin: 'visual-studio'
|
||||
apply plugin: 'edu.wpi.first.NativeUtils'
|
||||
|
||||
apply from: '../config.gradle'
|
||||
|
||||
ext.addHalToLinker = { binary->
|
||||
if (binary.targetPlatform.architecture.name == 'athena') {
|
||||
binary.lib project: ':hal', library: 'halAthena', linkage: 'shared'
|
||||
} else {
|
||||
binary.lib project: ':hal', library: 'halSim', linkage: 'shared'
|
||||
}
|
||||
}
|
||||
|
||||
model {
|
||||
components {
|
||||
HALAthena(NativeLibrarySpec) {
|
||||
targetPlatform 'arm'
|
||||
tasks.withType(CppCompile) {
|
||||
dependsOn addNiLibraryLinks
|
||||
}
|
||||
sources {
|
||||
cpp {
|
||||
source {
|
||||
srcDirs = ["lib/Athena", "lib/Athena/FRC_FPGA_ChipObject", "lib/Shared"]
|
||||
includes = ["**/*.cpp"]
|
||||
dependencyConfigs {
|
||||
wpiutil(DependencyConfig) {
|
||||
groupId = 'edu.wpi.first.wpiutil'
|
||||
artifactId = 'wpiutil-cpp'
|
||||
headerClassifier = 'headers'
|
||||
ext = 'zip'
|
||||
version = '3.+'
|
||||
sharedConfigs = [ halAthena: [], halSim: [], halDev: [], halSimTestingBaseTest: [] ]
|
||||
staticConfigs = [ halSimStaticDeps: [] ]
|
||||
}
|
||||
}
|
||||
// Exports config is a utility to enable exporting all symbols in a C++ library on windows to a DLL.
|
||||
// This removes the need for DllExport on a library. However, the gradle C++ builder has a bug
|
||||
// where some extra symbols are added that cannot be resolved at link time. This configuration
|
||||
// lets you specify specific symbols to exlude from exporting.
|
||||
exportsConfigs {
|
||||
halSim(ExportsConfig) {
|
||||
x86ExcludeSymbols = [ '_CT??_R0?AV_System_error', '_CT??_R0?AVexception', '_CT??_R0?AVfailure',
|
||||
'_CT??_R0?AVbad_cast',
|
||||
'_CT??_R0?AVruntime_error', '_CT??_R0?AVsystem_error', '_CTA5?AVfailure',
|
||||
'_TI5?AVfailure' ]
|
||||
x64ExcludeSymbols = [ '_CT??_R0?AV_System_error', '_CT??_R0?AVexception', '_CT??_R0?AVfailure',
|
||||
'_CT??_R0?AVbad_cast',
|
||||
'_CT??_R0?AVruntime_error', '_CT??_R0?AVsystem_error', '_CTA5?AVfailure',
|
||||
'_TI5?AVfailure' ]
|
||||
}
|
||||
halSimStaticDeps(ExportsConfig) {
|
||||
x86SymbolFilter = { symbols->
|
||||
def retList = []
|
||||
symbols.each { symbol->
|
||||
if (symbol.startsWith('HAL_')) {
|
||||
retList << symbol
|
||||
}
|
||||
exportedHeaders {
|
||||
srcDirs = ["include", "lib/Athena", "lib/Athena/FRC_FPGA_ChipObject", "lib/Shared"]
|
||||
}
|
||||
return retList
|
||||
}
|
||||
x64SymbolFilter = { symbols->
|
||||
def retList = []
|
||||
symbols.each { symbol->
|
||||
if (symbol.startsWith('HAL_')) {
|
||||
retList << symbol
|
||||
}
|
||||
}
|
||||
return retList
|
||||
}
|
||||
}
|
||||
}
|
||||
components {
|
||||
if (!project.hasProperty('skipAthena')) {
|
||||
halAthena(NativeLibrarySpec) {
|
||||
baseName = 'wpiHal'
|
||||
sources {
|
||||
cpp {
|
||||
source {
|
||||
srcDirs = [ 'src/main/native/shared', 'src/main/native/athena' ]
|
||||
includes = ["**/*.cpp"]
|
||||
}
|
||||
exportedHeaders {
|
||||
srcDirs = ["src/main/native/include"]
|
||||
}
|
||||
}
|
||||
}
|
||||
binaries.all { binary->
|
||||
if (binary.targetPlatform.architecture.name != 'athena') {
|
||||
binary.buildable = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// HALDesktop(NativeLibrarySpec) {
|
||||
// binaries.all {
|
||||
// if (toolChain in Gcc){
|
||||
// cppCompiler.args "-std=c++1y"
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// sources {
|
||||
// cpp {
|
||||
// source {
|
||||
// srcDirs = ["lib/Desktop", "lib/Shared"]
|
||||
// includes = ["**/*.cpp"]
|
||||
// }
|
||||
// exportedHeaders {
|
||||
// srcDirs = ["include", "lib/Desktop", "lib/Shared"]
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
if (!project.hasProperty('onlyAthena')) {
|
||||
halSim(NativeLibrarySpec) {
|
||||
baseName = 'wpiHal'
|
||||
sources {
|
||||
cpp {
|
||||
source {
|
||||
srcDirs = [ 'src/main/native/shared', 'src/main/native/sim' ]
|
||||
includes = ["**/*.cpp"]
|
||||
}
|
||||
exportedHeaders {
|
||||
srcDirs = ["src/main/native/include"]
|
||||
}
|
||||
}
|
||||
}
|
||||
binaries.all { binary ->
|
||||
if (binary.targetPlatform.operatingSystem.linux) {
|
||||
linker.args "-ldl"
|
||||
}
|
||||
}
|
||||
}
|
||||
if (project.hasProperty('buildHalStaticDeps')) {
|
||||
halSimStaticDeps(NativeLibrarySpec) {
|
||||
baseName = 'wpiHal'
|
||||
binaries {
|
||||
withType(StaticLibraryBinarySpec) {
|
||||
buildable = false
|
||||
}
|
||||
}
|
||||
sources {
|
||||
cpp {
|
||||
source {
|
||||
srcDirs = [ 'src/main/native/shared', 'src/main/native/sim' ]
|
||||
includes = ["**/*.cpp"]
|
||||
}
|
||||
exportedHeaders {
|
||||
srcDirs = ["src/main/native/include"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// The TestingBase library is a workaround for an issue with the GoogleTest plugin.
|
||||
// The plugin by default will rebuild the entire test source set, which increases
|
||||
// build time. By testing an empty library, and then just linking the already built component
|
||||
// into the test, we save the extra build
|
||||
halSimTestingBase(NativeLibrarySpec) { }
|
||||
// By default, a development executable will be generated. This is to help the case of
|
||||
// testing specific functionality of the library.
|
||||
if (!project.hasProperty('skipDevExe')) {
|
||||
halDev(NativeExecutableSpec) {
|
||||
binaries.all {
|
||||
project.addHalToLinker(it)
|
||||
}
|
||||
sources {
|
||||
cpp {
|
||||
source {
|
||||
srcDirs 'src/dev/native/cpp'
|
||||
include '**/*.cpp'
|
||||
}
|
||||
exportedHeaders {
|
||||
srcDirs 'src/dev/native/include'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
testSuites {
|
||||
halSimTestingBaseTest {
|
||||
sources {
|
||||
cpp.source.srcDir 'src/test/native/cpp'
|
||||
cpp.exportedHeaders.srcDir 'src/test/native/include'
|
||||
}
|
||||
}
|
||||
}
|
||||
binaries {
|
||||
all {
|
||||
project(':ni-libraries').addNiLibrariesToLinker(it)
|
||||
}
|
||||
withType(GoogleTestTestSuiteBinarySpec) {
|
||||
if (it.component.testedComponent.name.contains('TestingBase') && !project.hasProperty('onlyAthena')) {
|
||||
project(':gmock').addGmockToLinker(it)
|
||||
project.addHalToLinker(it)
|
||||
} else {
|
||||
it.buildable = false
|
||||
}
|
||||
}
|
||||
}
|
||||
tasks {
|
||||
runCpp(Exec) {
|
||||
def found = false
|
||||
$.components.each {
|
||||
if (it in NativeExecutableSpec && it.name == 'halDev') {
|
||||
it.binaries.each {
|
||||
if (!found) {
|
||||
def arch = it.targetPlatform.architecture.name
|
||||
if (arch == 'x86-64' || arch == 'x86') {
|
||||
dependsOn it.tasks.install
|
||||
commandLine it.tasks.install.runScript
|
||||
found = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
getHeaders(Task) {
|
||||
def list = []
|
||||
$.components.each {
|
||||
if (it in NativeLibrarySpec && (it.name == 'halAthena' || it.name == 'halSim')) {
|
||||
it.sources.each {
|
||||
it.exportedHeaders.srcDirs.each {
|
||||
list.add(it)
|
||||
}
|
||||
}
|
||||
it.binaries.each {
|
||||
it.libs.each {
|
||||
it.includeRoots.each {
|
||||
list.add(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
list = list.unique(false)
|
||||
doLast {
|
||||
list.each {
|
||||
print "WPIHEADER: "
|
||||
println it
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
apply from: 'publish.gradle'
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
enum AccelerometerRange {
|
||||
kRange_2G = 0,
|
||||
kRange_4G = 1,
|
||||
kRange_8G = 2,
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
void setAccelerometerActive(bool);
|
||||
void setAccelerometerRange(AccelerometerRange);
|
||||
double getAccelerometerX();
|
||||
double getAccelerometerY();
|
||||
double getAccelerometerZ();
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
enum AnalogTriggerType
|
||||
{
|
||||
kInWindow = 0,
|
||||
kState = 1,
|
||||
kRisingPulse = 2,
|
||||
kFallingPulse = 3
|
||||
};
|
||||
|
||||
extern "C"
|
||||
{
|
||||
// Analog output functions
|
||||
void* initializeAnalogOutputPort(void* port_pointer, int32_t *status);
|
||||
void freeAnalogOutputPort(void* analog_port_pointer);
|
||||
void setAnalogOutput(void* analog_port_pointer, double voltage, int32_t *status);
|
||||
double getAnalogOutput(void* analog_port_pointer, int32_t *status);
|
||||
bool checkAnalogOutputChannel(uint32_t pin);
|
||||
|
||||
// Analog input functions
|
||||
void* initializeAnalogInputPort(void* port_pointer, int32_t *status);
|
||||
void freeAnalogInputPort(void* analog_port_pointer);
|
||||
bool checkAnalogModule(uint8_t module);
|
||||
bool checkAnalogInputChannel(uint32_t pin);
|
||||
|
||||
void setAnalogSampleRate(double samplesPerSecond, int32_t *status);
|
||||
float getAnalogSampleRate(int32_t *status);
|
||||
void setAnalogAverageBits(void* analog_port_pointer, uint32_t bits, int32_t *status);
|
||||
uint32_t getAnalogAverageBits(void* analog_port_pointer, int32_t *status);
|
||||
void setAnalogOversampleBits(void* analog_port_pointer, uint32_t bits, int32_t *status);
|
||||
uint32_t getAnalogOversampleBits(void* analog_port_pointer, int32_t *status);
|
||||
int16_t getAnalogValue(void* analog_port_pointer, int32_t *status);
|
||||
int32_t getAnalogAverageValue(void* analog_port_pointer, int32_t *status);
|
||||
int32_t getAnalogVoltsToValue(void* analog_port_pointer, double voltage, int32_t *status);
|
||||
float getAnalogVoltage(void* analog_port_pointer, int32_t *status);
|
||||
float getAnalogAverageVoltage(void* analog_port_pointer, int32_t *status);
|
||||
uint32_t getAnalogLSBWeight(void* analog_port_pointer, int32_t *status);
|
||||
int32_t getAnalogOffset(void* analog_port_pointer, int32_t *status);
|
||||
|
||||
bool isAccumulatorChannel(void* analog_port_pointer, int32_t *status);
|
||||
void initAccumulator(void* analog_port_pointer, int32_t *status);
|
||||
void resetAccumulator(void* analog_port_pointer, int32_t *status);
|
||||
void setAccumulatorCenter(void* analog_port_pointer, int32_t center, int32_t *status);
|
||||
void setAccumulatorDeadband(void* analog_port_pointer, int32_t deadband, int32_t *status);
|
||||
int64_t getAccumulatorValue(void* analog_port_pointer, int32_t *status);
|
||||
uint32_t getAccumulatorCount(void* analog_port_pointer, int32_t *status);
|
||||
void getAccumulatorOutput(void* analog_port_pointer, int64_t *value, uint32_t *count,
|
||||
int32_t *status);
|
||||
|
||||
void* initializeAnalogTrigger(void* port_pointer, uint32_t *index, int32_t *status);
|
||||
void cleanAnalogTrigger(void* analog_trigger_pointer, int32_t *status);
|
||||
void setAnalogTriggerLimitsRaw(void* analog_trigger_pointer, int32_t lower, int32_t upper,
|
||||
int32_t *status);
|
||||
void setAnalogTriggerLimitsVoltage(void* analog_trigger_pointer, double lower, double upper,
|
||||
int32_t *status);
|
||||
void setAnalogTriggerAveraged(void* analog_trigger_pointer, bool useAveragedValue,
|
||||
int32_t *status);
|
||||
void setAnalogTriggerFiltered(void* analog_trigger_pointer, bool useFilteredValue,
|
||||
int32_t *status);
|
||||
bool getAnalogTriggerInWindow(void* analog_trigger_pointer, int32_t *status);
|
||||
bool getAnalogTriggerTriggerState(void* analog_trigger_pointer, int32_t *status);
|
||||
bool getAnalogTriggerOutput(void* analog_trigger_pointer, AnalogTriggerType type,
|
||||
int32_t *status);
|
||||
|
||||
//// Float JNA Hack
|
||||
// Float
|
||||
int getAnalogSampleRateIntHack(int32_t *status);
|
||||
int getAnalogVoltageIntHack(void* analog_port_pointer, int32_t *status);
|
||||
int getAnalogAverageVoltageIntHack(void* analog_port_pointer, int32_t *status);
|
||||
|
||||
// Doubles
|
||||
void setAnalogSampleRateIntHack(int samplesPerSecond, int32_t *status);
|
||||
int32_t getAnalogVoltsToValueIntHack(void* analog_port_pointer, int voltage, int32_t *status);
|
||||
void setAnalogTriggerLimitsVoltageIntHack(void* analog_trigger_pointer, int lower, int upper,
|
||||
int32_t *status);
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "FRC_NetworkCommunication/CANSessionMux.h"
|
||||
|
||||
void canTxSend(uint32_t arbID, uint8_t length, int32_t period = CAN_SEND_PERIOD_NO_REPEAT);
|
||||
|
||||
void canTxPackInt8 (uint32_t arbID, uint8_t offset, uint8_t value);
|
||||
void canTxPackInt16(uint32_t arbID, uint8_t offset, uint16_t value);
|
||||
void canTxPackInt32(uint32_t arbID, uint8_t offset, uint32_t value);
|
||||
void canTxPackFXP16(uint32_t arbID, uint8_t offset, double value);
|
||||
void canTxPackFXP32(uint32_t arbID, uint8_t offset, double value);
|
||||
|
||||
uint8_t canTxUnpackInt8 (uint32_t arbID, uint8_t offset);
|
||||
uint32_t canTxUnpackInt32(uint32_t arbID, uint8_t offset);
|
||||
uint16_t canTxUnpackInt16(uint32_t arbID, uint8_t offset);
|
||||
double canTxUnpackFXP16(uint32_t arbID, uint8_t offset);
|
||||
double canTxUnpackFXP32(uint32_t arbID, uint8_t offset);
|
||||
|
||||
bool canRxReceive(uint32_t arbID);
|
||||
|
||||
uint8_t canRxUnpackInt8 (uint32_t arbID, uint8_t offset);
|
||||
uint16_t canRxUnpackInt16(uint32_t arbID, uint8_t offset);
|
||||
uint32_t canRxUnpackInt32(uint32_t arbID, uint8_t offset);
|
||||
double canRxUnpackFXP16(uint32_t arbID, uint8_t offset);
|
||||
double canRxUnpackFXP32(uint32_t arbID, uint8_t offset);
|
||||
@@ -1,829 +0,0 @@
|
||||
/**
|
||||
* @brief CAN TALON SRX driver.
|
||||
*
|
||||
* The TALON SRX is designed to instrument all runtime signals periodically.
|
||||
* The default periods are chosen to support 16 TALONs with 10ms update rate
|
||||
* for control (throttle or setpoint). However these can be overridden with
|
||||
* SetStatusFrameRate. @see SetStatusFrameRate
|
||||
* The getters for these unsolicited signals are auto generated at the bottom
|
||||
* of this module.
|
||||
*
|
||||
* Likewise most control signals are sent periodically using the fire-and-forget
|
||||
* CAN API. The setters for these unsolicited signals are auto generated at the
|
||||
* bottom of this module.
|
||||
*
|
||||
* Signals that are not available in an unsolicited fashion are the Close Loop
|
||||
* gains. For teams that have a single profile for their TALON close loop they
|
||||
* can use either the webpage to configure their TALONs once or set the PIDF,
|
||||
* Izone, CloseLoopRampRate, etc... once in the robot application. These
|
||||
* parameters are saved to flash so once they are loaded in the TALON, they
|
||||
* will persist through power cycles and mode changes.
|
||||
*
|
||||
* For teams that have one or two profiles to switch between, they can use the
|
||||
* same strategy since there are two slots to choose from and the
|
||||
* ProfileSlotSelect is periodically sent in the 10 ms control frame.
|
||||
*
|
||||
* For teams that require changing gains frequently, they can use the soliciting
|
||||
* API to get and set those parameters. Most likely they will only need to set
|
||||
* them in a periodic fashion as a function of what motion the application is
|
||||
* attempting. If this API is used, be mindful of the CAN utilization reported
|
||||
* in the driver station.
|
||||
*
|
||||
* If calling application has used the config routines to configure the
|
||||
* selected feedback sensor, then all positions are measured in floating point
|
||||
* precision rotations. All sensor velocities are specified in floating point
|
||||
* precision RPM.
|
||||
* @see ConfigPotentiometerTurns
|
||||
* @see ConfigEncoderCodesPerRev
|
||||
* HOWEVER, if calling application has not called the config routine for
|
||||
* selected feedback sensor, then all getters/setters for position/velocity use
|
||||
* the native engineering units of the Talon SRX firm (just like in 2015).
|
||||
* Signals explained below.
|
||||
*
|
||||
* Encoder position is measured in encoder edges. Every edge is counted
|
||||
* (similar to roboRIO 4X mode). Analog position is 10 bits, meaning 1024
|
||||
* ticks per rotation (0V => 3.3V). Use SetFeedbackDeviceSelect to select
|
||||
* which sensor type you need. Once you do that you can use GetSensorPosition()
|
||||
* and GetSensorVelocity(). These signals are updated on CANBus every 20ms (by
|
||||
* default). If a relative sensor is selected, you can zero (or change the
|
||||
* current value) using SetSensorPosition.
|
||||
*
|
||||
* Analog Input and quadrature position (and velocity) are also explicitly
|
||||
* reported in GetEncPosition, GetEncVel, GetAnalogInWithOv, GetAnalogInVel.
|
||||
* These signals are available all the time, regardless of what sensor is
|
||||
* selected at a rate of 100ms. This allows easy instrumentation for "in the
|
||||
* pits" checking of all sensors regardless of modeselect. The 100ms rate is
|
||||
* overridable for teams who want to acquire sensor data for processing, not
|
||||
* just instrumentation. Or just select the sensor using
|
||||
* SetFeedbackDeviceSelect to get it at 20ms.
|
||||
*
|
||||
* Velocity is in position ticks / 100ms.
|
||||
*
|
||||
* All output units are in respect to duty cycle (throttle) which is -1023(full
|
||||
* reverse) to +1023 (full forward). This includes demand (which specifies
|
||||
* duty cycle when in duty cycle mode) and rampRamp, which is in throttle units
|
||||
* per 10ms (if nonzero).
|
||||
*
|
||||
* Pos and velocity close loops are calc'd as
|
||||
* err = target - posOrVel.
|
||||
* iErr += err;
|
||||
* if( (IZone!=0) and abs(err) > IZone)
|
||||
* ClearIaccum()
|
||||
* output = P X err + I X iErr + D X dErr + F X target
|
||||
* dErr = err - lastErr
|
||||
* P, I, and D gains are always positive. F can be negative.
|
||||
* Motor direction can be reversed using SetRevMotDuringCloseLoopEn if
|
||||
* sensor and motor are out of phase. Similarly feedback sensor can also be
|
||||
* reversed (multiplied by -1) if you prefer the sensor to be inverted.
|
||||
*
|
||||
* P gain is specified in throttle per error tick. For example, a value of 102
|
||||
* is ~9.9% (which is 102/1023) throttle per 1 ADC unit(10bit) or 1 quadrature
|
||||
* encoder edge depending on selected sensor.
|
||||
*
|
||||
* I gain is specified in throttle per integrated error. For example, a value
|
||||
* of 10 equates to ~0.99% (which is 10/1023) for each accumulated ADC unit
|
||||
* (10 bit) or 1 quadrature encoder edge depending on selected sensor.
|
||||
* Close loop and integral accumulator runs every 1ms.
|
||||
*
|
||||
* D gain is specified in throttle per derivative error. For example a value of
|
||||
* 102 equates to ~9.9% (which is 102/1023) per change of 1 unit (ADC or
|
||||
* encoder) per ms.
|
||||
*
|
||||
* I Zone is specified in the same units as sensor position (ADC units or
|
||||
* quadrature edges). If pos/vel error is outside of this value, the
|
||||
* integrated error will auto-clear...
|
||||
* if( (IZone!=0) and abs(err) > IZone)
|
||||
* ClearIaccum()
|
||||
* ...this is very useful in preventing integral windup and is highly
|
||||
* recommended if using full PID to keep stability low.
|
||||
*
|
||||
* CloseLoopRampRate is in throttle units per 1ms. Set to zero to disable
|
||||
* ramping. Works the same as RampThrottle but only is in effect when a close
|
||||
* loop mode and profile slot is selected.
|
||||
*
|
||||
* auto generated using spreadsheet and wpiclassgen.py
|
||||
* @link https://docs.google.com/spreadsheets/d/1OU_ZV7fZLGYUQ-Uhc8sVAmUmWTlT8XBFYK8lfjg_tac/edit#gid=1766046967
|
||||
*/
|
||||
#ifndef CanTalonSRX_H_
|
||||
#define CanTalonSRX_H_
|
||||
#include "ctre/ctre.h" //BIT Defines + Typedefs, TALON_Control_6_MotProfAddTrajPoint_t
|
||||
#include "ctre/CtreCanNode.h"
|
||||
#include <FRC_NetworkCommunication/CANSessionMux.h> //CAN Comm
|
||||
#include <map>
|
||||
#include <atomic>
|
||||
#include <deque>
|
||||
#include <mutex>
|
||||
class CanTalonSRX : public CtreCanNode {
|
||||
private:
|
||||
// Use this for determining whether the default move constructor has been
|
||||
// called; this prevents us from calling the destructor twice.
|
||||
struct HasBeenMoved {
|
||||
HasBeenMoved(HasBeenMoved &&other) {
|
||||
other.moved = true;
|
||||
moved = false;
|
||||
}
|
||||
HasBeenMoved() = default;
|
||||
std::atomic<bool> moved{false};
|
||||
operator bool() const { return moved; }
|
||||
} m_hasBeenMoved;
|
||||
|
||||
// Vars for opening a CAN stream if caller needs signals that require
|
||||
// soliciting
|
||||
uint32_t _can_h; //!< Session handle for catching response params.
|
||||
int32_t _can_stat; //!< Session handle status.
|
||||
struct tCANStreamMessage _msgBuff[20];
|
||||
static int const kMsgCapacity = 20;
|
||||
typedef std::map<uint32_t, uint32_t> sigs_t;
|
||||
// Catches signal updates that are solicited. Expect this to be very few.
|
||||
sigs_t _sigs;
|
||||
void OpenSessionIfNeedBe();
|
||||
void ProcessStreamMessages();
|
||||
/**
|
||||
* Called in various places to double check we are using the best control
|
||||
* frame. If the Talon firmware is too old, use control 1 framing, which
|
||||
* does not allow setting control signals until robot is enabled. If Talon
|
||||
* firmware can suport control5, use that since that frame can be
|
||||
* transmitted during robot-disable. If calling application uses setParam
|
||||
* to set the signal eLegacyControlMode, caller can force using control1
|
||||
* if needed for some reason.
|
||||
*/
|
||||
void UpdateControlId();
|
||||
/**
|
||||
* @return true if Talon is reporting that it supports control5, and therefore
|
||||
* RIO can send control5 to update control params (even when
|
||||
* disabled).
|
||||
*/
|
||||
bool IsControl5Supported();
|
||||
/**
|
||||
* Get a copy of the control frame to send.
|
||||
* @param [out] pointer to eight byte array to fill.
|
||||
*/
|
||||
void GetControlFrameCopy(uint8_t *toFill);
|
||||
/**
|
||||
* @return the tx task that transmits Control6 (motion profile control).
|
||||
* If it's not scheduled, then schedule it. This is part
|
||||
* of making the lazy-framing that only peforms MotionProf framing
|
||||
* when needed to save bandwidth.
|
||||
*/
|
||||
CtreCanNode::txTask<TALON_Control_6_MotProfAddTrajPoint_t> GetControl6();
|
||||
/**
|
||||
* Caller is either pushing a new motion profile point, or is
|
||||
* calling the Process buffer routine. In either case check our
|
||||
* flow control to see if we need to start sending control6.
|
||||
*/
|
||||
void ReactToMotionProfileCall();
|
||||
/**
|
||||
* Update the NextPt signals inside the control frame given the next pt to
|
||||
* send.
|
||||
* @param control pointer to the CAN frame payload containing control6. Only
|
||||
* the signals that serialize the next trajectory point are
|
||||
* updated from the contents of newPt.
|
||||
* @param newPt point to the next trajectory that needs to be inserted into
|
||||
* Talon RAM.
|
||||
*/
|
||||
void CopyTrajPtIntoControl(
|
||||
TALON_Control_6_MotProfAddTrajPoint_t *control,
|
||||
const TALON_Control_6_MotProfAddTrajPoint_t *newPt);
|
||||
//---------------------- General Control framing ---------------------------//
|
||||
/**
|
||||
* Frame period for control1 or control5, depending on which one we are using.
|
||||
*/
|
||||
int _controlPeriodMs = kDefaultControlPeriodMs;
|
||||
/**
|
||||
* Frame Period of the motion profile control6 frame.
|
||||
*/
|
||||
int _control6PeriodMs = kDefaultControl6PeriodMs;
|
||||
/**
|
||||
* When using control5, we still need to send a frame to enable robot. This
|
||||
* controls the period. This only is used when we are in the control5 state.
|
||||
* @see ControlFrameSelControl5
|
||||
*/
|
||||
int _enablePeriodMs = kDefaultEnablePeriodMs;
|
||||
/**
|
||||
* ArbID to use for control frame. Should be either CONTROL_1 or CONTROL_5.
|
||||
*/
|
||||
uint32_t _controlFrameArbId;
|
||||
/**
|
||||
* Boolean flag to signal calling applications intent to allow using control5
|
||||
* assuming Talon firmware supports it. This can be cleared to force control1
|
||||
* framing.
|
||||
*/
|
||||
bool _useControl5ifSupported = true;
|
||||
//--------------------- Buffering Motion Profile ---------------------------//
|
||||
/**
|
||||
* Top level Buffer for motion profile trajectory buffering.
|
||||
* Basically this buffers up the eight byte CAN frame payloads that are
|
||||
* handshaked into the Talon RAM.
|
||||
* TODO: Should this be moved into a separate header, and if so where
|
||||
* logically should it reside?
|
||||
* TODO: Add compression so that multiple CAN frames can be compressed into
|
||||
* one exchange.
|
||||
*/
|
||||
class TrajectoryBuffer {
|
||||
public:
|
||||
void Clear() { _motProfTopBuffer.clear(); }
|
||||
/**
|
||||
* push caller's uncompressed simple trajectory point.
|
||||
*/
|
||||
void Push(TALON_Control_6_MotProfAddTrajPoint_huff0_t &pt) {
|
||||
_motProfTopBuffer.push_back(pt);
|
||||
}
|
||||
/**
|
||||
* Get the next trajectory point CAN frame to send.
|
||||
* Underlying layer may compress the next few points together
|
||||
* into one control_6 frame.
|
||||
*/
|
||||
TALON_Control_6_MotProfAddTrajPoint_t *Front() {
|
||||
/* TODO : peek ahead and use compression strategies */
|
||||
_lastFront = _motProfTopBuffer.front();
|
||||
return (TALON_Control_6_MotProfAddTrajPoint_t *)&_lastFront;
|
||||
}
|
||||
void Pop() {
|
||||
/* TODO : pop multiple points if last front'd point was compressed. */
|
||||
_motProfTopBuffer.pop_front();
|
||||
}
|
||||
unsigned int GetNumTrajectories() { return _motProfTopBuffer.size(); }
|
||||
bool IsEmpty() { return _motProfTopBuffer.empty(); }
|
||||
|
||||
private:
|
||||
std::deque<TALON_Control_6_MotProfAddTrajPoint_huff0_t> _motProfTopBuffer;
|
||||
TALON_Control_6_MotProfAddTrajPoint_huff0_t _lastFront;
|
||||
};
|
||||
TrajectoryBuffer _motProfTopBuffer;
|
||||
/**
|
||||
* To keep buffers from getting out of control, place a cap on the top level
|
||||
* buffer. Calling application
|
||||
* can stream addition points as they are fed to Talon.
|
||||
* Approx memory footprint is this capacity X 8 bytes.
|
||||
*/
|
||||
static const int kMotionProfileTopBufferCapacity = 2048;
|
||||
/**
|
||||
* Flow control for streaming trajectories.
|
||||
*/
|
||||
int32_t _motProfFlowControl = -1;
|
||||
/**
|
||||
* Since we may need the MP pts to be emptied into Talon in the background
|
||||
* make sure the buffering is thread-safe.
|
||||
*/
|
||||
std::mutex _mutMotProf;
|
||||
/**
|
||||
* Send a one shot frame to set an arbitrary signal.
|
||||
* Most signals are in the control frame so avoid using this API unless you
|
||||
* have to.
|
||||
* Use this api for...
|
||||
* -A motor controller profile signal eProfileParam_XXXs. These are backed up
|
||||
* in flash. If you are gain-scheduling then call this periodically.
|
||||
* -Default brake and limit switch signals... eOnBoot_XXXs. Avoid doing this,
|
||||
* use the override signals in the control frame.
|
||||
* Talon will automatically send a PARAM_RESPONSE after the set, so
|
||||
* GetParamResponse will catch the latest value after a couple ms.
|
||||
*/
|
||||
CTR_Code SetParamRaw(uint32_t paramEnum, int32_t rawBits);
|
||||
/**
|
||||
* Checks cached CAN frames and updating solicited signals.
|
||||
*/
|
||||
CTR_Code GetParamResponseRaw(uint32_t paramEnum, int32_t &rawBits);
|
||||
|
||||
public:
|
||||
// default control update rate is 10ms.
|
||||
static const int kDefaultControlPeriodMs = 10;
|
||||
// default enable update rate is 50ms (when using the new control5 frame).
|
||||
static const int kDefaultEnablePeriodMs = 50;
|
||||
// Default update rate for motion profile control 6. This only takes effect
|
||||
// when calling uses MP functions.
|
||||
static const int kDefaultControl6PeriodMs = 10;
|
||||
explicit CanTalonSRX(int deviceNumber = 0,
|
||||
int controlPeriodMs = kDefaultControlPeriodMs,
|
||||
int enablePeriodMs = kDefaultEnablePeriodMs);
|
||||
~CanTalonSRX();
|
||||
void Set(double value);
|
||||
/* mode select enumerations */
|
||||
// Demand is 11bit signed duty cycle [-1023,1023].
|
||||
static const int kMode_DutyCycle = 0;
|
||||
// Position PIDF.
|
||||
static const int kMode_PositionCloseLoop = 1;
|
||||
// Velocity PIDF.
|
||||
static const int kMode_VelocityCloseLoop = 2;
|
||||
// Current close loop - not done.
|
||||
static const int kMode_CurrentCloseLoop = 3;
|
||||
// Voltage Compensation Mode - not done. Demand is fixed pt target 8.8 volts.
|
||||
static const int kMode_VoltCompen = 4;
|
||||
// Demand is the 6 bit Device ID of the 'master' TALON SRX.
|
||||
static const int kMode_SlaveFollower = 5;
|
||||
// Demand is '0' (Disabled), '1' (Enabled), or '2' (Hold).
|
||||
static const int kMode_MotionProfile = 6;
|
||||
// Zero the output (honors brake/coast) regardless of demand.
|
||||
// Might be useful if we need to change modes but can't atomically
|
||||
// change all the signals we want in between.
|
||||
static const int kMode_NoDrive = 15;
|
||||
/* limit switch enumerations */
|
||||
static const int kLimitSwitchOverride_UseDefaultsFromFlash = 1;
|
||||
static const int kLimitSwitchOverride_DisableFwd_DisableRev = 4;
|
||||
static const int kLimitSwitchOverride_DisableFwd_EnableRev = 5;
|
||||
static const int kLimitSwitchOverride_EnableFwd_DisableRev = 6;
|
||||
static const int kLimitSwitchOverride_EnableFwd_EnableRev = 7;
|
||||
/* brake override enumerations */
|
||||
static const int kBrakeOverride_UseDefaultsFromFlash = 0;
|
||||
static const int kBrakeOverride_OverrideCoast = 1;
|
||||
static const int kBrakeOverride_OverrideBrake = 2;
|
||||
/* feedback device enumerations */
|
||||
static const int kFeedbackDev_DigitalQuadEnc = 0;
|
||||
static const int kFeedbackDev_AnalogPot = 2;
|
||||
static const int kFeedbackDev_AnalogEncoder = 3;
|
||||
static const int kFeedbackDev_CountEveryRisingEdge = 4;
|
||||
static const int kFeedbackDev_CountEveryFallingEdge = 5;
|
||||
static const int kFeedbackDev_PosIsPulseWidth = 8;
|
||||
/* ProfileSlotSelect enumerations*/
|
||||
static const int kProfileSlotSelect_Slot0 = 0;
|
||||
static const int kProfileSlotSelect_Slot1 = 1;
|
||||
/* status frame rate types */
|
||||
static const int kStatusFrame_General = 0;
|
||||
static const int kStatusFrame_Feedback = 1;
|
||||
static const int kStatusFrame_Encoder = 2;
|
||||
static const int kStatusFrame_AnalogTempVbat = 3;
|
||||
static const int kStatusFrame_PulseWidthMeas = 4;
|
||||
static const int kStatusFrame_MotionProfile = 5;
|
||||
/* Motion Profile status bits */
|
||||
static const int kMotionProfileFlag_ActTraj_IsValid = 0x1;
|
||||
static const int kMotionProfileFlag_HasUnderrun = 0x2;
|
||||
static const int kMotionProfileFlag_IsUnderrun = 0x4;
|
||||
static const int kMotionProfileFlag_ActTraj_IsLast = 0x8;
|
||||
static const int kMotionProfileFlag_ActTraj_VelOnly = 0x10;
|
||||
/* Motion Profile Set Output */
|
||||
// Motor output is neutral, Motion Profile Executer is not running.
|
||||
static const int kMotionProf_Disabled = 0;
|
||||
// Motor output is updated from Motion Profile Executer, MPE will
|
||||
// process the buffered points.
|
||||
static const int kMotionProf_Enable = 1;
|
||||
// Motor output is updated from Motion Profile Executer, MPE will
|
||||
// stay processing current trajectory point.
|
||||
static const int kMotionProf_Hold = 2;
|
||||
/**
|
||||
* Signal enumeration for generic signal access.
|
||||
* Although every signal is enumerated, only use this for traffic that must
|
||||
* be solicited.
|
||||
* Use the auto generated getters/setters at bottom of this header as much as
|
||||
* possible.
|
||||
*/
|
||||
enum param_t {
|
||||
eProfileParamSlot0_P = 1,
|
||||
eProfileParamSlot0_I = 2,
|
||||
eProfileParamSlot0_D = 3,
|
||||
eProfileParamSlot0_F = 4,
|
||||
eProfileParamSlot0_IZone = 5,
|
||||
eProfileParamSlot0_CloseLoopRampRate = 6,
|
||||
eProfileParamSlot1_P = 11,
|
||||
eProfileParamSlot1_I = 12,
|
||||
eProfileParamSlot1_D = 13,
|
||||
eProfileParamSlot1_F = 14,
|
||||
eProfileParamSlot1_IZone = 15,
|
||||
eProfileParamSlot1_CloseLoopRampRate = 16,
|
||||
eProfileParamSoftLimitForThreshold = 21,
|
||||
eProfileParamSoftLimitRevThreshold = 22,
|
||||
eProfileParamSoftLimitForEnable = 23,
|
||||
eProfileParamSoftLimitRevEnable = 24,
|
||||
eOnBoot_BrakeMode = 31,
|
||||
eOnBoot_LimitSwitch_Forward_NormallyClosed = 32,
|
||||
eOnBoot_LimitSwitch_Reverse_NormallyClosed = 33,
|
||||
eOnBoot_LimitSwitch_Forward_Disable = 34,
|
||||
eOnBoot_LimitSwitch_Reverse_Disable = 35,
|
||||
eFault_OverTemp = 41,
|
||||
eFault_UnderVoltage = 42,
|
||||
eFault_ForLim = 43,
|
||||
eFault_RevLim = 44,
|
||||
eFault_HardwareFailure = 45,
|
||||
eFault_ForSoftLim = 46,
|
||||
eFault_RevSoftLim = 47,
|
||||
eStckyFault_OverTemp = 48,
|
||||
eStckyFault_UnderVoltage = 49,
|
||||
eStckyFault_ForLim = 50,
|
||||
eStckyFault_RevLim = 51,
|
||||
eStckyFault_ForSoftLim = 52,
|
||||
eStckyFault_RevSoftLim = 53,
|
||||
eAppliedThrottle = 61,
|
||||
eCloseLoopErr = 62,
|
||||
eFeedbackDeviceSelect = 63,
|
||||
eRevMotDuringCloseLoopEn = 64,
|
||||
eModeSelect = 65,
|
||||
eProfileSlotSelect = 66,
|
||||
eRampThrottle = 67,
|
||||
eRevFeedbackSensor = 68,
|
||||
eLimitSwitchEn = 69,
|
||||
eLimitSwitchClosedFor = 70,
|
||||
eLimitSwitchClosedRev = 71,
|
||||
eSensorPosition = 73,
|
||||
eSensorVelocity = 74,
|
||||
eCurrent = 75,
|
||||
eBrakeIsEnabled = 76,
|
||||
eEncPosition = 77,
|
||||
eEncVel = 78,
|
||||
eEncIndexRiseEvents = 79,
|
||||
eQuadApin = 80,
|
||||
eQuadBpin = 81,
|
||||
eQuadIdxpin = 82,
|
||||
eAnalogInWithOv = 83,
|
||||
eAnalogInVel = 84,
|
||||
eTemp = 85,
|
||||
eBatteryV = 86,
|
||||
eResetCount = 87,
|
||||
eResetFlags = 88,
|
||||
eFirmVers = 89,
|
||||
eSettingsChanged = 90,
|
||||
eQuadFilterEn = 91,
|
||||
ePidIaccum = 93,
|
||||
eStatus1FrameRate = 94, // TALON_Status_1_General_10ms_t
|
||||
eStatus2FrameRate = 95, // TALON_Status_2_Feedback_20ms_t
|
||||
eStatus3FrameRate = 96, // TALON_Status_3_Enc_100ms_t
|
||||
eStatus4FrameRate = 97, // TALON_Status_4_AinTempVbat_100ms_t
|
||||
eStatus6FrameRate = 98, // TALON_Status_6_Eol_t
|
||||
eStatus7FrameRate = 99, // TALON_Status_7_Debug_200ms_t
|
||||
eClearPositionOnIdx = 100,
|
||||
// reserved,
|
||||
// reserved,
|
||||
// reserved,
|
||||
ePeakPosOutput = 104,
|
||||
eNominalPosOutput = 105,
|
||||
ePeakNegOutput = 106,
|
||||
eNominalNegOutput = 107,
|
||||
eQuadIdxPolarity = 108,
|
||||
eStatus8FrameRate = 109, // TALON_Status_8_PulseWid_100ms_t
|
||||
eAllowPosOverflow = 110,
|
||||
eProfileParamSlot0_AllowableClosedLoopErr = 111,
|
||||
eNumberPotTurns = 112,
|
||||
eNumberEncoderCPR = 113,
|
||||
ePwdPosition = 114,
|
||||
eAinPosition = 115,
|
||||
eProfileParamVcompRate = 116,
|
||||
eProfileParamSlot1_AllowableClosedLoopErr = 117,
|
||||
eStatus9FrameRate = 118, // TALON_Status_9_MotProfBuffer_100ms_t
|
||||
eMotionProfileHasUnderrunErr = 119,
|
||||
eReserved120 = 120,
|
||||
eLegacyControlMode = 121,
|
||||
};
|
||||
//---- setters and getters that use the solicated param request/response ---//
|
||||
/**
|
||||
* Send a one shot frame to set an arbitrary signal.
|
||||
* Most signals are in the control frame so avoid using this API unless you
|
||||
* have to.
|
||||
* Use this api for...
|
||||
* -A motor controller profile signal eProfileParam_XXXs. These are backed
|
||||
* up in flash. If you are gain-scheduling then call this periodically.
|
||||
* -Default brake and limit switch signals... eOnBoot_XXXs. Avoid doing
|
||||
* this, use the override signals in the control frame.
|
||||
* Talon will automatically send a PARAM_RESPONSE after the set, so
|
||||
* GetParamResponse will catch the latest value after a couple ms.
|
||||
*/
|
||||
CTR_Code SetParam(param_t paramEnum, double value);
|
||||
/**
|
||||
* Asks TALON to immedietely respond with signal value. This API is only used
|
||||
* for signals that are not sent periodically.
|
||||
* This can be useful for reading params that rarely change like Limit Switch
|
||||
* settings and PIDF values.
|
||||
* @param param to request.
|
||||
*/
|
||||
CTR_Code RequestParam(param_t paramEnum);
|
||||
CTR_Code GetParamResponse(param_t paramEnum, double &value);
|
||||
CTR_Code GetParamResponseInt32(param_t paramEnum, int &value);
|
||||
//----------- getters and setters that use param request/response ----------//
|
||||
/**
|
||||
* These signals are backed up in flash and will survive a power cycle.
|
||||
* If your application requires changing these values consider using both
|
||||
* slots and switch between slot0 <=> slot1.
|
||||
* If your application requires changing these signals frequently then it
|
||||
* makes sense to leverage this API.
|
||||
* Getters don't block, so it may require several calls to get the latest
|
||||
* value.
|
||||
*/
|
||||
CTR_Code SetPgain(unsigned slotIdx, double gain);
|
||||
CTR_Code SetIgain(unsigned slotIdx, double gain);
|
||||
CTR_Code SetDgain(unsigned slotIdx, double gain);
|
||||
CTR_Code SetFgain(unsigned slotIdx, double gain);
|
||||
CTR_Code SetIzone(unsigned slotIdx, int zone);
|
||||
CTR_Code SetCloseLoopRampRate(unsigned slotIdx, int closeLoopRampRate);
|
||||
CTR_Code SetVoltageCompensationRate(double voltagePerMs);
|
||||
CTR_Code SetSensorPosition(int pos);
|
||||
CTR_Code SetForwardSoftLimit(int forwardLimit);
|
||||
CTR_Code SetReverseSoftLimit(int reverseLimit);
|
||||
CTR_Code SetForwardSoftEnable(int enable);
|
||||
CTR_Code SetReverseSoftEnable(int enable);
|
||||
CTR_Code GetPgain(unsigned slotIdx, double &gain);
|
||||
CTR_Code GetIgain(unsigned slotIdx, double &gain);
|
||||
CTR_Code GetDgain(unsigned slotIdx, double &gain);
|
||||
CTR_Code GetFgain(unsigned slotIdx, double &gain);
|
||||
CTR_Code GetIzone(unsigned slotIdx, int &zone);
|
||||
CTR_Code GetCloseLoopRampRate(unsigned slotIdx, int &closeLoopRampRate);
|
||||
CTR_Code GetVoltageCompensationRate(double &voltagePerMs);
|
||||
CTR_Code GetForwardSoftLimit(int &forwardLimit);
|
||||
CTR_Code GetReverseSoftLimit(int &reverseLimit);
|
||||
CTR_Code GetForwardSoftEnable(int &enable);
|
||||
CTR_Code GetReverseSoftEnable(int &enable);
|
||||
CTR_Code GetPulseWidthRiseToFallUs(int ¶m);
|
||||
CTR_Code IsPulseWidthSensorPresent(int ¶m);
|
||||
CTR_Code SetModeSelect(int modeSelect, int demand);
|
||||
/**
|
||||
* Change the periodMs of a TALON's status frame. See kStatusFrame_* enums
|
||||
* for what's available.
|
||||
*/
|
||||
CTR_Code SetStatusFrameRate(unsigned frameEnum, unsigned periodMs);
|
||||
/**
|
||||
* Clear all sticky faults in TALON.
|
||||
*/
|
||||
CTR_Code ClearStickyFaults();
|
||||
/**
|
||||
* Calling application can opt to speed up the handshaking between the robot
|
||||
* API and the Talon to increase the
|
||||
* download rate of the Talon's Motion Profile. Ideally the period should be
|
||||
* no more than half the period
|
||||
* of a trajectory point.
|
||||
*/
|
||||
void ChangeMotionControlFramePeriod(uint32_t periodMs);
|
||||
/**
|
||||
* Clear the buffered motion profile in both Talon RAM (bottom), and in the
|
||||
* API (top).
|
||||
*/
|
||||
void ClearMotionProfileTrajectories();
|
||||
/**
|
||||
* Retrieve just the buffer count for the api-level (top) buffer.
|
||||
* This routine performs no CAN or data structure lookups, so its fast and
|
||||
* ideal if caller needs to quickly poll the progress of trajectory points
|
||||
* being emptied into Talon's RAM. Otherwise just use GetMotionProfileStatus.
|
||||
* @return number of trajectory points in the top buffer.
|
||||
*/
|
||||
uint32_t GetMotionProfileTopLevelBufferCount();
|
||||
/**
|
||||
* Retrieve just the buffer full for the api-level (top) buffer.
|
||||
* This routine performs no CAN or data structure lookups, so its fast and
|
||||
* ideal if caller needs to quickly poll. Otherwise just use
|
||||
* GetMotionProfileStatus.
|
||||
* @return number of trajectory points in the top buffer.
|
||||
*/
|
||||
bool IsMotionProfileTopLevelBufferFull();
|
||||
/**
|
||||
* Push another trajectory point into the top level buffer (which is emptied
|
||||
* into the Talon's bottom buffer as room allows).
|
||||
* @param targPos servo position in native Talon units (sensor units).
|
||||
* @param targVel velocity to feed-forward in native Talon units (sensor
|
||||
* units per 100ms).
|
||||
* @param profileSlotSelect which slot to pull PIDF gains from. Currently
|
||||
* supports 0 or 1.
|
||||
* @param timeDurMs time in milliseconds of how long to apply this point.
|
||||
* @param velOnly set to nonzero to signal Talon that only the feed-foward
|
||||
* velocity should be used, i.e. do not perform PID on
|
||||
* position. This is equivalent to setting PID gains to zero,
|
||||
* but much more efficient and synchronized to MP.
|
||||
* @param isLastPoint set to nonzero to signal Talon to keep processing this
|
||||
* trajectory point, instead of jumping to the next one
|
||||
* when timeDurMs expires. Otherwise MP executer will
|
||||
* eventually see an empty buffer after the last point
|
||||
* expires, causing it to assert the IsUnderRun flag.
|
||||
* However this may be desired if calling application
|
||||
* nevers wants to terminate the MP.
|
||||
* @param zeroPos set to nonzero to signal Talon to "zero" the selected
|
||||
* position sensor before executing this trajectory point.
|
||||
* Typically the first point should have this set only thus
|
||||
* allowing the remainder of the MP positions to be relative
|
||||
* to zero.
|
||||
* @return CTR_OKAY if trajectory point push ok. CTR_BufferFull if buffer is
|
||||
* full due to kMotionProfileTopBufferCapacity.
|
||||
*/
|
||||
CTR_Code PushMotionProfileTrajectory(int targPos, int targVel,
|
||||
int profileSlotSelect, int timeDurMs,
|
||||
int velOnly, int isLastPoint,
|
||||
int zeroPos);
|
||||
/**
|
||||
* This must be called periodically to funnel the trajectory points from the
|
||||
* API's top level buffer to the Talon's bottom level buffer. Recommendation
|
||||
* is to call this twice as fast as the executation rate of the motion
|
||||
* profile. So if MP is running with 20ms trajectory points, try calling
|
||||
* this routine every 10ms. All motion profile functions are thread-safe
|
||||
* through the use of a mutex, so there is no harm in having the caller
|
||||
* utilize threading.
|
||||
*/
|
||||
void ProcessMotionProfileBuffer();
|
||||
/**
|
||||
* Retrieve all status information.
|
||||
* Since this all comes from one CAN frame, its ideal to have one routine to
|
||||
* retrieve the frame once and decode everything.
|
||||
* @param [out] flags bitfield for status bools. Starting with least
|
||||
* significant bit: IsValid, HasUnderrun, IsUnderrun, IsLast, VelOnly.
|
||||
*
|
||||
* IsValid set when MP executer is processing a trajectory point,
|
||||
* and that point's status is instrumented with IsLast,
|
||||
* VelOnly, targPos, targVel. However if MP executor is
|
||||
* not processing a trajectory point, then this flag is
|
||||
* false, and the instrumented signals will be zero.
|
||||
* HasUnderrun is set anytime the MP executer is ready to pop
|
||||
* another trajectory point from the Talon's RAM,
|
||||
* but the buffer is empty. It can only be cleared
|
||||
* by using SetParam(eMotionProfileHasUnderrunErr,0);
|
||||
* IsUnderrun is set when the MP executer is ready for another
|
||||
* point, but the buffer is empty, and cleared when
|
||||
* the MP executer does not need another point.
|
||||
* HasUnderrun shadows this registor when this
|
||||
* register gets set, however HasUnderrun stays
|
||||
* asserted until application has process it, and
|
||||
* IsUnderrun auto-clears when the condition is
|
||||
* resolved.
|
||||
* IsLast is set/cleared based on the MP executer's current
|
||||
* trajectory point's IsLast value. This assumes
|
||||
* IsLast was set when PushMotionProfileTrajectory
|
||||
* was used to insert the currently processed trajectory
|
||||
* point.
|
||||
* VelOnly is set/cleared based on the MP executer's current
|
||||
* trajectory point's VelOnly value.
|
||||
*
|
||||
* @param [out] profileSlotSelect The currently processed trajectory point's
|
||||
* selected slot. This can differ in the currently selected slot used
|
||||
* for Position and Velocity servo modes.
|
||||
* @param [out] targPos The currently processed trajectory point's position
|
||||
* in native units. This param is zero if IsValid is zero.
|
||||
* @param [out] targVel The currently processed trajectory point's velocity
|
||||
* in native units. This param is zero if IsValid is zero.
|
||||
* @param [out] topBufferRem The remaining number of points in the top level
|
||||
* buffer.
|
||||
* @param [out] topBufferCnt The number of points in the top level buffer to
|
||||
* be sent to Talon.
|
||||
* @param [out] btmBufferCnt The number of points in the bottom level buffer
|
||||
* inside Talon.
|
||||
* @return CTR error code
|
||||
*/
|
||||
CTR_Code GetMotionProfileStatus(uint32_t &flags, uint32_t &profileSlotSelect,
|
||||
int32_t &targPos, int32_t &targVel,
|
||||
uint32_t &topBufferRemaining,
|
||||
uint32_t &topBufferCnt,
|
||||
uint32_t &btmBufferCnt,
|
||||
uint32_t &outputEnable);
|
||||
//------------------------ auto generated ------------------------------------//
|
||||
/* This API is optimal since it uses the fire-and-forget CAN interface.
|
||||
* These signals should cover the majority of all use cases.
|
||||
*/
|
||||
CTR_Code GetFault_OverTemp(int ¶m);
|
||||
CTR_Code GetFault_UnderVoltage(int ¶m);
|
||||
CTR_Code GetFault_ForLim(int ¶m);
|
||||
CTR_Code GetFault_RevLim(int ¶m);
|
||||
CTR_Code GetFault_HardwareFailure(int ¶m);
|
||||
CTR_Code GetFault_ForSoftLim(int ¶m);
|
||||
CTR_Code GetFault_RevSoftLim(int ¶m);
|
||||
CTR_Code GetStckyFault_OverTemp(int ¶m);
|
||||
CTR_Code GetStckyFault_UnderVoltage(int ¶m);
|
||||
CTR_Code GetStckyFault_ForLim(int ¶m);
|
||||
CTR_Code GetStckyFault_RevLim(int ¶m);
|
||||
CTR_Code GetStckyFault_ForSoftLim(int ¶m);
|
||||
CTR_Code GetStckyFault_RevSoftLim(int ¶m);
|
||||
CTR_Code GetAppliedThrottle(int ¶m);
|
||||
CTR_Code GetCloseLoopErr(int ¶m);
|
||||
CTR_Code GetFeedbackDeviceSelect(int ¶m);
|
||||
CTR_Code GetModeSelect(int ¶m);
|
||||
CTR_Code GetLimitSwitchEn(int ¶m);
|
||||
CTR_Code GetLimitSwitchClosedFor(int ¶m);
|
||||
CTR_Code GetLimitSwitchClosedRev(int ¶m);
|
||||
CTR_Code GetSensorPosition(int ¶m);
|
||||
CTR_Code GetSensorVelocity(int ¶m);
|
||||
CTR_Code GetCurrent(double ¶m);
|
||||
CTR_Code GetBrakeIsEnabled(int ¶m);
|
||||
CTR_Code GetEncPosition(int ¶m);
|
||||
CTR_Code GetEncVel(int ¶m);
|
||||
CTR_Code GetEncIndexRiseEvents(int ¶m);
|
||||
CTR_Code GetQuadApin(int ¶m);
|
||||
CTR_Code GetQuadBpin(int ¶m);
|
||||
CTR_Code GetQuadIdxpin(int ¶m);
|
||||
CTR_Code GetAnalogInWithOv(int ¶m);
|
||||
CTR_Code GetAnalogInVel(int ¶m);
|
||||
CTR_Code GetTemp(double ¶m);
|
||||
CTR_Code GetBatteryV(double ¶m);
|
||||
CTR_Code GetResetCount(int ¶m);
|
||||
CTR_Code GetResetFlags(int ¶m);
|
||||
CTR_Code GetFirmVers(int ¶m);
|
||||
CTR_Code GetPulseWidthPosition(int ¶m);
|
||||
CTR_Code GetPulseWidthVelocity(int ¶m);
|
||||
CTR_Code GetPulseWidthRiseToRiseUs(int ¶m);
|
||||
CTR_Code GetActTraj_IsValid(int ¶m);
|
||||
CTR_Code GetActTraj_ProfileSlotSelect(int ¶m);
|
||||
CTR_Code GetActTraj_VelOnly(int ¶m);
|
||||
CTR_Code GetActTraj_IsLast(int ¶m);
|
||||
CTR_Code GetOutputType(int ¶m);
|
||||
CTR_Code GetHasUnderrun(int ¶m);
|
||||
CTR_Code GetIsUnderrun(int ¶m);
|
||||
CTR_Code GetNextID(int ¶m);
|
||||
CTR_Code GetBufferIsFull(int ¶m);
|
||||
CTR_Code GetCount(int ¶m);
|
||||
CTR_Code GetActTraj_Velocity(int ¶m);
|
||||
CTR_Code GetActTraj_Position(int ¶m);
|
||||
CTR_Code SetDemand(int param);
|
||||
CTR_Code SetOverrideLimitSwitchEn(int param);
|
||||
CTR_Code SetFeedbackDeviceSelect(int param);
|
||||
CTR_Code SetRevMotDuringCloseLoopEn(int param);
|
||||
CTR_Code SetOverrideBrakeType(int param);
|
||||
CTR_Code SetModeSelect(int param);
|
||||
CTR_Code SetProfileSlotSelect(int param);
|
||||
CTR_Code SetRampThrottle(int param);
|
||||
CTR_Code SetRevFeedbackSensor(int param);
|
||||
};
|
||||
extern "C" {
|
||||
void *c_TalonSRX_Create3(int deviceNumber, int controlPeriodMs, int enablePeriodMs);
|
||||
void *c_TalonSRX_Create2(int deviceNumber, int controlPeriodMs);
|
||||
void *c_TalonSRX_Create1(int deviceNumber);
|
||||
void c_TalonSRX_Destroy(void *handle);
|
||||
void c_TalonSRX_Set(void *handle, double value);
|
||||
CTR_Code c_TalonSRX_SetParam(void *handle, int paramEnum, double value);
|
||||
CTR_Code c_TalonSRX_RequestParam(void *handle, int paramEnum);
|
||||
CTR_Code c_TalonSRX_GetParamResponse(void *handle, int paramEnum, double *value);
|
||||
CTR_Code c_TalonSRX_GetParamResponseInt32(void *handle, int paramEnum, int *value);
|
||||
CTR_Code c_TalonSRX_SetPgain(void *handle, int slotIdx, double gain);
|
||||
CTR_Code c_TalonSRX_SetIgain(void *handle, int slotIdx, double gain);
|
||||
CTR_Code c_TalonSRX_SetDgain(void *handle, int slotIdx, double gain);
|
||||
CTR_Code c_TalonSRX_SetFgain(void *handle, int slotIdx, double gain);
|
||||
CTR_Code c_TalonSRX_SetIzone(void *handle, int slotIdx, int zone);
|
||||
CTR_Code c_TalonSRX_SetCloseLoopRampRate(void *handle, int slotIdx, int closeLoopRampRate);
|
||||
CTR_Code c_TalonSRX_SetVoltageCompensationRate(void *handle, double voltagePerMs);
|
||||
CTR_Code c_TalonSRX_SetSensorPosition(void *handle, int pos);
|
||||
CTR_Code c_TalonSRX_SetForwardSoftLimit(void *handle, int forwardLimit);
|
||||
CTR_Code c_TalonSRX_SetReverseSoftLimit(void *handle, int reverseLimit);
|
||||
CTR_Code c_TalonSRX_SetForwardSoftEnable(void *handle, int enable);
|
||||
CTR_Code c_TalonSRX_SetReverseSoftEnable(void *handle, int enable);
|
||||
CTR_Code c_TalonSRX_GetPgain(void *handle, int slotIdx, double *gain);
|
||||
CTR_Code c_TalonSRX_GetIgain(void *handle, int slotIdx, double *gain);
|
||||
CTR_Code c_TalonSRX_GetDgain(void *handle, int slotIdx, double *gain);
|
||||
CTR_Code c_TalonSRX_GetFgain(void *handle, int slotIdx, double *gain);
|
||||
CTR_Code c_TalonSRX_GetIzone(void *handle, int slotIdx, int *zone);
|
||||
CTR_Code c_TalonSRX_GetCloseLoopRampRate(void *handle, int slotIdx, int *closeLoopRampRate);
|
||||
CTR_Code c_TalonSRX_GetVoltageCompensationRate(void *handle, double *voltagePerMs);
|
||||
CTR_Code c_TalonSRX_GetForwardSoftLimit(void *handle, int *forwardLimit);
|
||||
CTR_Code c_TalonSRX_GetReverseSoftLimit(void *handle, int *reverseLimit);
|
||||
CTR_Code c_TalonSRX_GetForwardSoftEnable(void *handle, int *enable);
|
||||
CTR_Code c_TalonSRX_GetReverseSoftEnable(void *handle, int *enable);
|
||||
CTR_Code c_TalonSRX_GetPulseWidthRiseToFallUs(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_IsPulseWidthSensorPresent(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_SetModeSelect2(void *handle, int modeSelect, int demand);
|
||||
CTR_Code c_TalonSRX_SetStatusFrameRate(void *handle, int frameEnum, int periodMs);
|
||||
CTR_Code c_TalonSRX_ClearStickyFaults(void *handle);
|
||||
void c_TalonSRX_ChangeMotionControlFramePeriod(void *handle, int periodMs);
|
||||
void c_TalonSRX_ClearMotionProfileTrajectories(void *handle);
|
||||
int c_TalonSRX_GetMotionProfileTopLevelBufferCount(void *handle);
|
||||
int c_TalonSRX_IsMotionProfileTopLevelBufferFull(void *handle);
|
||||
CTR_Code c_TalonSRX_PushMotionProfileTrajectory(void *handle, int targPos, int targVel, int profileSlotSelect, int timeDurMs, int velOnly, int isLastPoint, int zeroPos);
|
||||
void c_TalonSRX_ProcessMotionProfileBuffer(void *handle);
|
||||
CTR_Code c_TalonSRX_GetMotionProfileStatus(void *handle, int *flags, int *profileSlotSelect, int *targPos, int *targVel, int *topBufferRemaining, int *topBufferCnt, int *btmBufferCnt, int *outputEnable);
|
||||
CTR_Code c_TalonSRX_GetFault_OverTemp(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetFault_UnderVoltage(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetFault_ForLim(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetFault_RevLim(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetFault_HardwareFailure(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetFault_ForSoftLim(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetFault_RevSoftLim(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetStckyFault_OverTemp(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetStckyFault_UnderVoltage(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetStckyFault_ForLim(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetStckyFault_RevLim(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetStckyFault_ForSoftLim(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetStckyFault_RevSoftLim(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetAppliedThrottle(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetCloseLoopErr(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetFeedbackDeviceSelect(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetModeSelect(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetLimitSwitchEn(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetLimitSwitchClosedFor(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetLimitSwitchClosedRev(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetSensorPosition(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetSensorVelocity(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetCurrent(void *handle, double *param);
|
||||
CTR_Code c_TalonSRX_GetBrakeIsEnabled(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetEncPosition(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetEncVel(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetEncIndexRiseEvents(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetQuadApin(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetQuadBpin(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetQuadIdxpin(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetAnalogInWithOv(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetAnalogInVel(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetTemp(void *handle, double *param);
|
||||
CTR_Code c_TalonSRX_GetBatteryV(void *handle, double *param);
|
||||
CTR_Code c_TalonSRX_GetResetCount(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetResetFlags(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetFirmVers(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetPulseWidthPosition(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetPulseWidthVelocity(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetPulseWidthRiseToRiseUs(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetActTraj_IsValid(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetActTraj_ProfileSlotSelect(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetActTraj_VelOnly(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetActTraj_IsLast(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetOutputType(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetHasUnderrun(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetIsUnderrun(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetNextID(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetBufferIsFull(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetCount(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetActTraj_Velocity(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_GetActTraj_Position(void *handle, int *param);
|
||||
CTR_Code c_TalonSRX_SetDemand(void *handle, int param);
|
||||
CTR_Code c_TalonSRX_SetOverrideLimitSwitchEn(void *handle, int param);
|
||||
CTR_Code c_TalonSRX_SetFeedbackDeviceSelect(void *handle, int param);
|
||||
CTR_Code c_TalonSRX_SetRevMotDuringCloseLoopEn(void *handle, int param);
|
||||
CTR_Code c_TalonSRX_SetOverrideBrakeType(void *handle, int param);
|
||||
CTR_Code c_TalonSRX_SetModeSelect(void *handle, int param);
|
||||
CTR_Code c_TalonSRX_SetProfileSlotSelect(void *handle, int param);
|
||||
CTR_Code c_TalonSRX_SetRampThrottle(void *handle, int param);
|
||||
CTR_Code c_TalonSRX_SetRevFeedbackSensor(void *handle, int param);
|
||||
}
|
||||
#endif
|
||||
@@ -1,33 +0,0 @@
|
||||
/**
|
||||
* Compressor.h
|
||||
* Methods for interacting with a compressor with the CAN PCM device
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef __HAL_COMPRESSOR_H__
|
||||
#define __HAL_COMPRESSOR_H__
|
||||
|
||||
extern "C" {
|
||||
void *initializeCompressor(uint8_t module);
|
||||
bool checkCompressorModule(uint8_t module);
|
||||
|
||||
bool getCompressor(void *pcm_pointer, int32_t *status);
|
||||
|
||||
void setClosedLoopControl(void *pcm_pointer, bool value, int32_t *status);
|
||||
bool getClosedLoopControl(void *pcm_pointer, int32_t *status);
|
||||
|
||||
bool getPressureSwitch(void *pcm_pointer, int32_t *status);
|
||||
float getCompressorCurrent(void *pcm_pointer, int32_t *status);
|
||||
|
||||
bool getCompressorCurrentTooHighFault(void *pcm_pointer, int32_t *status);
|
||||
bool getCompressorCurrentTooHighStickyFault(void *pcm_pointer, int32_t *status);
|
||||
bool getCompressorShortedStickyFault(void *pcm_pointer, int32_t *status);
|
||||
bool getCompressorShortedFault(void *pcm_pointer, int32_t *status);
|
||||
bool getCompressorNotConnectedStickyFault(void *pcm_pointer, int32_t *status);
|
||||
bool getCompressorNotConnectedFault(void *pcm_pointer, int32_t *status);
|
||||
void clearAllPCMStickyFaults(void *pcm_pointer, int32_t *status);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,139 +0,0 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
#include "HAL/cpp/priority_mutex.h"
|
||||
|
||||
enum Mode
|
||||
{
|
||||
kTwoPulse = 0,
|
||||
kSemiperiod = 1,
|
||||
kPulseLength = 2,
|
||||
kExternalDirection = 3
|
||||
};
|
||||
|
||||
priority_recursive_mutex& spiGetSemaphore(uint8_t port);
|
||||
|
||||
extern "C"
|
||||
{
|
||||
void* initializeDigitalPort(void* port_pointer, int32_t *status);
|
||||
void freeDigitalPort(void* digital_port_pointer);
|
||||
bool checkPWMChannel(void* digital_port_pointer);
|
||||
bool checkRelayChannel(void* digital_port_pointer);
|
||||
|
||||
void setPWM(void* digital_port_pointer, unsigned short value, int32_t *status);
|
||||
bool allocatePWMChannel(void* digital_port_pointer, int32_t *status);
|
||||
void freePWMChannel(void* digital_port_pointer, int32_t *status);
|
||||
unsigned short getPWM(void* digital_port_pointer, int32_t *status);
|
||||
void latchPWMZero(void* digital_port_pointer, int32_t *status);
|
||||
void setPWMPeriodScale(void* digital_port_pointer, uint32_t squelchMask, int32_t *status);
|
||||
void* allocatePWM(int32_t *status);
|
||||
void freePWM(void* pwmGenerator, int32_t *status);
|
||||
void setPWMRate(double rate, int32_t *status);
|
||||
void setPWMDutyCycle(void* pwmGenerator, double dutyCycle, int32_t *status);
|
||||
void setPWMOutputChannel(void* pwmGenerator, uint32_t pin, int32_t *status);
|
||||
|
||||
void setRelayForward(void* digital_port_pointer, bool on, int32_t *status);
|
||||
void setRelayReverse(void* digital_port_pointer, bool on, int32_t *status);
|
||||
bool getRelayForward(void* digital_port_pointer, int32_t *status);
|
||||
bool getRelayReverse(void* digital_port_pointer, int32_t *status);
|
||||
|
||||
bool allocateDIO(void* digital_port_pointer, bool input, int32_t *status);
|
||||
void freeDIO(void* digital_port_pointer, int32_t *status);
|
||||
void setDIO(void* digital_port_pointer, short value, int32_t *status);
|
||||
bool getDIO(void* digital_port_pointer, int32_t *status);
|
||||
bool getDIODirection(void* digital_port_pointer, int32_t *status);
|
||||
void pulse(void* digital_port_pointer, double pulseLength, int32_t *status);
|
||||
bool isPulsing(void* digital_port_pointer, int32_t *status);
|
||||
bool isAnyPulsing(int32_t *status);
|
||||
|
||||
void setFilterSelect(void* digital_port_pointer, int filter_index,
|
||||
int32_t* status);
|
||||
int getFilterSelect(void* digital_port_pointer, int32_t* status);
|
||||
|
||||
void setFilterPeriod(int filter_index, uint32_t value, int32_t* status);
|
||||
uint32_t getFilterPeriod(int filter_index, int32_t* status);
|
||||
|
||||
void* initializeCounter(Mode mode, uint32_t *index, int32_t *status);
|
||||
void freeCounter(void* counter_pointer, int32_t *status);
|
||||
void setCounterAverageSize(void* counter_pointer, int32_t size, int32_t *status);
|
||||
void setCounterUpSource(void* counter_pointer, uint32_t pin, bool analogTrigger, int32_t *status);
|
||||
void setCounterUpSourceEdge(void* counter_pointer, bool risingEdge, bool fallingEdge,
|
||||
int32_t *status);
|
||||
void clearCounterUpSource(void* counter_pointer, int32_t *status);
|
||||
void setCounterDownSource(void* counter_pointer, uint32_t pin, bool analogTrigger, int32_t *status);
|
||||
void setCounterDownSourceEdge(void* counter_pointer, bool risingEdge, bool fallingEdge,
|
||||
int32_t *status);
|
||||
void clearCounterDownSource(void* counter_pointer, int32_t *status);
|
||||
void setCounterUpDownMode(void* counter_pointer, int32_t *status);
|
||||
void setCounterExternalDirectionMode(void* counter_pointer, int32_t *status);
|
||||
void setCounterSemiPeriodMode(void* counter_pointer, bool highSemiPeriod, int32_t *status);
|
||||
void setCounterPulseLengthMode(void* counter_pointer, double threshold, int32_t *status);
|
||||
int32_t getCounterSamplesToAverage(void* counter_pointer, int32_t *status);
|
||||
void setCounterSamplesToAverage(void* counter_pointer, int samplesToAverage, int32_t *status);
|
||||
void resetCounter(void* counter_pointer, int32_t *status);
|
||||
int32_t getCounter(void* counter_pointer, int32_t *status);
|
||||
double getCounterPeriod(void* counter_pointer, int32_t *status);
|
||||
void setCounterMaxPeriod(void* counter_pointer, double maxPeriod, int32_t *status);
|
||||
void setCounterUpdateWhenEmpty(void* counter_pointer, bool enabled, int32_t *status);
|
||||
bool getCounterStopped(void* counter_pointer, int32_t *status);
|
||||
bool getCounterDirection(void* counter_pointer, int32_t *status);
|
||||
void setCounterReverseDirection(void* counter_pointer, bool reverseDirection, int32_t *status);
|
||||
|
||||
void* initializeEncoder(uint8_t port_a_module, uint32_t port_a_pin, bool port_a_analog_trigger,
|
||||
uint8_t port_b_module, uint32_t port_b_pin, bool port_b_analog_trigger,
|
||||
bool reverseDirection, int32_t *index, int32_t *status); // TODO: fix routing
|
||||
void freeEncoder(void* encoder_pointer, int32_t *status);
|
||||
void resetEncoder(void* encoder_pointer, int32_t *status);
|
||||
int32_t getEncoder(void* encoder_pointer, int32_t *status); // Raw value
|
||||
double getEncoderPeriod(void* encoder_pointer, int32_t *status);
|
||||
void setEncoderMaxPeriod(void* encoder_pointer, double maxPeriod, int32_t *status);
|
||||
bool getEncoderStopped(void* encoder_pointer, int32_t *status);
|
||||
bool getEncoderDirection(void* encoder_pointer, int32_t *status);
|
||||
void setEncoderReverseDirection(void* encoder_pointer, bool reverseDirection, int32_t *status);
|
||||
void setEncoderSamplesToAverage(void* encoder_pointer, uint32_t samplesToAverage,
|
||||
int32_t *status);
|
||||
uint32_t getEncoderSamplesToAverage(void* encoder_pointer, int32_t *status);
|
||||
void setEncoderIndexSource(void *encoder_pointer, uint32_t pin, bool analogTrigger, bool activeHigh,
|
||||
bool edgeSensitive, int32_t *status);
|
||||
|
||||
uint16_t getLoopTiming(int32_t *status);
|
||||
|
||||
void spiInitialize(uint8_t port, int32_t *status);
|
||||
int32_t spiTransaction(uint8_t port, uint8_t *dataToSend, uint8_t *dataReceived, uint8_t size);
|
||||
int32_t spiWrite(uint8_t port, uint8_t* dataToSend, uint8_t sendSize);
|
||||
int32_t spiRead(uint8_t port, uint8_t *buffer, uint8_t count);
|
||||
void spiClose(uint8_t port);
|
||||
void spiSetSpeed(uint8_t port, uint32_t speed);
|
||||
void spiSetOpts(uint8_t port, int msb_first, int sample_on_trailing, int clk_idle_high);
|
||||
void spiSetChipSelectActiveHigh(uint8_t port, int32_t *status);
|
||||
void spiSetChipSelectActiveLow(uint8_t port, int32_t *status);
|
||||
int32_t spiGetHandle(uint8_t port);
|
||||
void spiSetHandle(uint8_t port, int32_t handle);
|
||||
|
||||
void spiInitAccumulator(uint8_t port, uint32_t period, uint32_t cmd,
|
||||
uint8_t xfer_size, uint32_t valid_mask,
|
||||
uint32_t valid_value, uint8_t data_shift,
|
||||
uint8_t data_size, bool is_signed, bool big_endian,
|
||||
int32_t *status);
|
||||
void spiFreeAccumulator(uint8_t port, int32_t *status);
|
||||
void spiResetAccumulator(uint8_t port, int32_t *status);
|
||||
void spiSetAccumulatorCenter(uint8_t port, int32_t center, int32_t *status);
|
||||
void spiSetAccumulatorDeadband(uint8_t port, int32_t deadband, int32_t *status);
|
||||
int32_t spiGetAccumulatorLastValue(uint8_t port, int32_t *status);
|
||||
int64_t spiGetAccumulatorValue(uint8_t port, int32_t *status);
|
||||
uint32_t spiGetAccumulatorCount(uint8_t port, int32_t *status);
|
||||
double spiGetAccumulatorAverage(uint8_t port, int32_t *status);
|
||||
void spiGetAccumulatorOutput(uint8_t port, int64_t *value, uint32_t *count,
|
||||
int32_t *status);
|
||||
|
||||
void i2CInitialize(uint8_t port, int32_t *status);
|
||||
int32_t i2CTransaction(uint8_t port, uint8_t deviceAddress, uint8_t *dataToSend, uint8_t sendSize, uint8_t *dataReceived, uint8_t receiveSize);
|
||||
int32_t i2CWrite(uint8_t port, uint8_t deviceAddress, uint8_t *dataToSend, uint8_t sendSize);
|
||||
int32_t i2CRead(uint8_t port, uint8_t deviceAddress, uint8_t *buffer, uint8_t count);
|
||||
void i2CClose(uint8_t port);
|
||||
|
||||
//// Float JNA Hack
|
||||
// double
|
||||
void setPWMRateIntHack(int rate, int32_t *status);
|
||||
void setPWMDutyCycleIntHack(void* pwmGenerator, int32_t dutyCycle, int32_t *status);
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#define CTR_RxTimeout_MESSAGE "CTRE CAN Recieve Timeout"
|
||||
#define CTR_TxTimeout_MESSAGE "CTRE CAN Transmit Timeout"
|
||||
#define CTR_InvalidParamValue_MESSAGE "CTRE CAN Invalid Parameter"
|
||||
#define CTR_UnexpectedArbId_MESSAGE "CTRE Unexpected Arbitration ID (CAN Node ID)"
|
||||
#define CTR_TxFailed_MESSAGE "CTRE CAN Transmit Error"
|
||||
#define CTR_SigNotUpdated_MESSAGE "CTRE CAN Signal Not Updated"
|
||||
|
||||
#define NiFpga_Status_FifoTimeout_MESSAGE "NIFPGA: FIFO timeout error"
|
||||
#define NiFpga_Status_TransferAborted_MESSAGE "NIFPGA: Transfer aborted error"
|
||||
#define NiFpga_Status_MemoryFull_MESSAGE "NIFPGA: Memory Allocation failed, memory full"
|
||||
#define NiFpga_Status_SoftwareFault_MESSAGE "NIFPGA: Unexepected software error"
|
||||
#define NiFpga_Status_InvalidParameter_MESSAGE "NIFPGA: Invalid Parameter"
|
||||
#define NiFpga_Status_ResourceNotFound_MESSAGE "NIFPGA: Resource not found"
|
||||
#define NiFpga_Status_ResourceNotInitialized_MESSAGE "NIFPGA: Resource not initialized"
|
||||
#define NiFpga_Status_HardwareFault_MESSAGE "NIFPGA: Hardware Fault"
|
||||
#define NiFpga_Status_IrqTimeout_MESSAGE "NIFPGA: Interrupt timeout"
|
||||
|
||||
#define ERR_CANSessionMux_InvalidBuffer_MESSAGE "CAN: Invalid Buffer"
|
||||
#define ERR_CANSessionMux_MessageNotFound_MESSAGE "CAN: Message not found"
|
||||
#define WARN_CANSessionMux_NoToken_MESSAGE "CAN: No token"
|
||||
#define ERR_CANSessionMux_NotAllowed_MESSAGE "CAN: Not allowed"
|
||||
#define ERR_CANSessionMux_NotInitialized_MESSAGE "CAN: Not initialized"
|
||||
|
||||
#define SAMPLE_RATE_TOO_HIGH 1001
|
||||
#define SAMPLE_RATE_TOO_HIGH_MESSAGE "HAL: Analog module sample rate is too high"
|
||||
#define VOLTAGE_OUT_OF_RANGE 1002
|
||||
#define VOLTAGE_OUT_OF_RANGE_MESSAGE "HAL: Voltage to convert to raw value is out of range [0; 5]"
|
||||
#define LOOP_TIMING_ERROR 1004
|
||||
#define LOOP_TIMING_ERROR_MESSAGE "HAL: Digital module loop timing is not the expected value"
|
||||
#define SPI_WRITE_NO_MOSI 1012
|
||||
#define SPI_WRITE_NO_MOSI_MESSAGE "HAL: Cannot write to SPI port with no MOSI output"
|
||||
#define SPI_READ_NO_MISO 1013
|
||||
#define SPI_READ_NO_MISO_MESSAGE "HAL: Cannot read from SPI port with no MISO input"
|
||||
#define SPI_READ_NO_DATA 1014
|
||||
#define SPI_READ_NO_DATA_MESSAGE "HAL: No data available to read from SPI"
|
||||
#define INCOMPATIBLE_STATE 1015
|
||||
#define INCOMPATIBLE_STATE_MESSAGE "HAL: Incompatible State: The operation cannot be completed"
|
||||
#define NO_AVAILABLE_RESOURCES -1004
|
||||
#define NO_AVAILABLE_RESOURCES_MESSAGE "HAL: No available resources to allocate"
|
||||
#define NULL_PARAMETER -1005
|
||||
#define NULL_PARAMETER_MESSAGE "HAL: A pointer parameter to a method is NULL"
|
||||
#define ANALOG_TRIGGER_LIMIT_ORDER_ERROR -1010
|
||||
#define ANALOG_TRIGGER_LIMIT_ORDER_ERROR_MESSAGE "HAL: AnalogTrigger limits error. Lower limit > Upper Limit"
|
||||
#define ANALOG_TRIGGER_PULSE_OUTPUT_ERROR -1011
|
||||
#define ANALOG_TRIGGER_PULSE_OUTPUT_ERROR_MESSAGE "HAL: Attempted to read AnalogTrigger pulse output."
|
||||
#define PARAMETER_OUT_OF_RANGE -1028
|
||||
#define PARAMETER_OUT_OF_RANGE_MESSAGE "HAL: A parameter is out of range."
|
||||
#define RESOURCE_IS_ALLOCATED -1029
|
||||
#define RESOURCE_IS_ALLOCATED_MESSAGE "HAL: Resource already allocated"
|
||||
|
||||
#define VI_ERROR_SYSTEM_ERROR_MESSAGE "HAL - VISA: System Error";
|
||||
#define VI_ERROR_INV_OBJECT_MESSAGE "HAL - VISA: Invalid Object"
|
||||
#define VI_ERROR_RSRC_LOCKED_MESSAGE "HAL - VISA: Resource Locked"
|
||||
#define VI_ERROR_RSRC_NFOUND_MESSAGE "HAL - VISA: Resource Not Found"
|
||||
#define VI_ERROR_INV_RSRC_NAME_MESSAGE "HAL - VISA: Invalid Resource Name"
|
||||
#define VI_ERROR_QUEUE_OVERFLOW_MESSAGE "HAL - VISA: Queue Overflow"
|
||||
#define VI_ERROR_IO_MESSAGE "HAL - VISA: General IO Error"
|
||||
#define VI_ERROR_ASRL_PARITY_MESSAGE "HAL - VISA: Parity Error"
|
||||
#define VI_ERROR_ASRL_FRAMING_MESSAGE "HAL - VISA: Framing Error"
|
||||
#define VI_ERROR_ASRL_OVERRUN_MESSAGE "HAL - VISA: Buffer Overrun Error"
|
||||
#define VI_ERROR_RSRC_BUSY_MESSAGE "HAL - VISA: Resource Busy"
|
||||
#define VI_ERROR_INV_PARAMETER_MESSAGE "HAL - VISA: Invalid Parameter"
|
||||
@@ -1,271 +0,0 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) FIRST 2013. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <cmath>
|
||||
|
||||
#include "Accelerometer.hpp"
|
||||
#include "Analog.hpp"
|
||||
#include "Compressor.hpp"
|
||||
#include "Digital.hpp"
|
||||
#include "Solenoid.hpp"
|
||||
#include "Notifier.hpp"
|
||||
#include "Interrupts.hpp"
|
||||
#include "Errors.hpp"
|
||||
#include "PDP.hpp"
|
||||
#include "Power.hpp"
|
||||
#include "SerialPort.hpp"
|
||||
|
||||
#include "Utilities.hpp"
|
||||
#include "Semaphore.hpp"
|
||||
#include "Task.hpp"
|
||||
|
||||
#define HAL_IO_CONFIG_DATA_SIZE 32
|
||||
#define HAL_SYS_STATUS_DATA_SIZE 44
|
||||
#define HAL_USER_STATUS_DATA_SIZE (984 - HAL_IO_CONFIG_DATA_SIZE - HAL_SYS_STATUS_DATA_SIZE)
|
||||
|
||||
#define HALFRC_NetworkCommunication_DynamicType_DSEnhancedIO_Input 17
|
||||
#define HALFRC_NetworkCommunication_DynamicType_DSEnhancedIO_Output 18
|
||||
#define HALFRC_NetworkCommunication_DynamicType_Kinect_Header 19
|
||||
#define HALFRC_NetworkCommunication_DynamicType_Kinect_Extra1 20
|
||||
#define HALFRC_NetworkCommunication_DynamicType_Kinect_Vertices1 21
|
||||
#define HALFRC_NetworkCommunication_DynamicType_Kinect_Extra2 22
|
||||
#define HALFRC_NetworkCommunication_DynamicType_Kinect_Vertices2 23
|
||||
#define HALFRC_NetworkCommunication_DynamicType_Kinect_Joystick 24
|
||||
#define HALFRC_NetworkCommunication_DynamicType_Kinect_Custom 25
|
||||
|
||||
namespace HALUsageReporting
|
||||
{
|
||||
enum tResourceType
|
||||
{
|
||||
kResourceType_Controller,
|
||||
kResourceType_Module,
|
||||
kResourceType_Language,
|
||||
kResourceType_CANPlugin,
|
||||
kResourceType_Accelerometer,
|
||||
kResourceType_ADXL345,
|
||||
kResourceType_AnalogChannel,
|
||||
kResourceType_AnalogTrigger,
|
||||
kResourceType_AnalogTriggerOutput,
|
||||
kResourceType_CANJaguar,
|
||||
kResourceType_Compressor,
|
||||
kResourceType_Counter,
|
||||
kResourceType_Dashboard,
|
||||
kResourceType_DigitalInput,
|
||||
kResourceType_DigitalOutput,
|
||||
kResourceType_DriverStationCIO,
|
||||
kResourceType_DriverStationEIO,
|
||||
kResourceType_DriverStationLCD,
|
||||
kResourceType_Encoder,
|
||||
kResourceType_GearTooth,
|
||||
kResourceType_Gyro,
|
||||
kResourceType_I2C,
|
||||
kResourceType_Framework,
|
||||
kResourceType_Jaguar,
|
||||
kResourceType_Joystick,
|
||||
kResourceType_Kinect,
|
||||
kResourceType_KinectStick,
|
||||
kResourceType_PIDController,
|
||||
kResourceType_Preferences,
|
||||
kResourceType_PWM,
|
||||
kResourceType_Relay,
|
||||
kResourceType_RobotDrive,
|
||||
kResourceType_SerialPort,
|
||||
kResourceType_Servo,
|
||||
kResourceType_Solenoid,
|
||||
kResourceType_SPI,
|
||||
kResourceType_Task,
|
||||
kResourceType_Ultrasonic,
|
||||
kResourceType_Victor,
|
||||
kResourceType_Button,
|
||||
kResourceType_Command,
|
||||
kResourceType_AxisCamera,
|
||||
kResourceType_PCVideoServer,
|
||||
kResourceType_SmartDashboard,
|
||||
kResourceType_Talon,
|
||||
kResourceType_HiTechnicColorSensor,
|
||||
kResourceType_HiTechnicAccel,
|
||||
kResourceType_HiTechnicCompass,
|
||||
kResourceType_SRF08,
|
||||
kResourceType_AnalogOutput,
|
||||
kResourceType_VictorSP,
|
||||
kResourceType_TalonSRX,
|
||||
kResourceType_CANTalonSRX,
|
||||
kResourceType_ADXL362,
|
||||
kResourceType_ADXRS450,
|
||||
kResourceType_RevSPARK,
|
||||
kResourceType_MindsensorsSD540,
|
||||
kResourceType_DigitalFilter,
|
||||
};
|
||||
|
||||
enum tInstances
|
||||
{
|
||||
kLanguage_LabVIEW = 1,
|
||||
kLanguage_CPlusPlus = 2,
|
||||
kLanguage_Java = 3,
|
||||
kLanguage_Python = 4,
|
||||
|
||||
kCANPlugin_BlackJagBridge = 1,
|
||||
kCANPlugin_2CAN = 2,
|
||||
|
||||
kFramework_Iterative = 1,
|
||||
kFramework_Sample = 2,
|
||||
kFramework_CommandControl = 3,
|
||||
|
||||
kRobotDrive_ArcadeStandard = 1,
|
||||
kRobotDrive_ArcadeButtonSpin = 2,
|
||||
kRobotDrive_ArcadeRatioCurve = 3,
|
||||
kRobotDrive_Tank = 4,
|
||||
kRobotDrive_MecanumPolar = 5,
|
||||
kRobotDrive_MecanumCartesian = 6,
|
||||
|
||||
kDriverStationCIO_Analog = 1,
|
||||
kDriverStationCIO_DigitalIn = 2,
|
||||
kDriverStationCIO_DigitalOut = 3,
|
||||
|
||||
kDriverStationEIO_Acceleration = 1,
|
||||
kDriverStationEIO_AnalogIn = 2,
|
||||
kDriverStationEIO_AnalogOut = 3,
|
||||
kDriverStationEIO_Button = 4,
|
||||
kDriverStationEIO_LED = 5,
|
||||
kDriverStationEIO_DigitalIn = 6,
|
||||
kDriverStationEIO_DigitalOut = 7,
|
||||
kDriverStationEIO_FixedDigitalOut = 8,
|
||||
kDriverStationEIO_PWM = 9,
|
||||
kDriverStationEIO_Encoder = 10,
|
||||
kDriverStationEIO_TouchSlider = 11,
|
||||
|
||||
kADXL345_SPI = 1,
|
||||
kADXL345_I2C = 2,
|
||||
|
||||
kCommand_Scheduler = 1,
|
||||
|
||||
kSmartDashboard_Instance = 1,
|
||||
};
|
||||
}
|
||||
|
||||
struct HALControlWord {
|
||||
uint32_t enabled : 1;
|
||||
uint32_t autonomous : 1;
|
||||
uint32_t test :1;
|
||||
uint32_t eStop : 1;
|
||||
uint32_t fmsAttached:1;
|
||||
uint32_t dsAttached:1;
|
||||
uint32_t control_reserved : 26;
|
||||
};
|
||||
|
||||
enum HALAllianceStationID {
|
||||
kHALAllianceStationID_red1,
|
||||
kHALAllianceStationID_red2,
|
||||
kHALAllianceStationID_red3,
|
||||
kHALAllianceStationID_blue1,
|
||||
kHALAllianceStationID_blue2,
|
||||
kHALAllianceStationID_blue3,
|
||||
};
|
||||
|
||||
/* The maximum number of axes that will be stored in a single HALJoystickAxes
|
||||
struct. This is used for allocating buffers, not bounds checking, since
|
||||
there are usually less axes in practice. */
|
||||
static const size_t kMaxJoystickAxes = 12;
|
||||
static const size_t kMaxJoystickPOVs = 12;
|
||||
|
||||
struct HALJoystickAxes {
|
||||
uint16_t count;
|
||||
int16_t axes[kMaxJoystickAxes];
|
||||
};
|
||||
|
||||
struct HALJoystickPOVs {
|
||||
uint16_t count;
|
||||
int16_t povs[kMaxJoystickPOVs];
|
||||
};
|
||||
|
||||
struct HALJoystickButtons {
|
||||
uint32_t buttons;
|
||||
uint8_t count;
|
||||
};
|
||||
|
||||
struct HALJoystickDescriptor {
|
||||
uint8_t isXbox;
|
||||
uint8_t type;
|
||||
char name[256];
|
||||
uint8_t axisCount;
|
||||
uint8_t axisTypes[kMaxJoystickAxes];
|
||||
uint8_t buttonCount;
|
||||
uint8_t povCount;
|
||||
};
|
||||
|
||||
inline float intToFloat(int value)
|
||||
{
|
||||
return (float)value;
|
||||
}
|
||||
|
||||
inline int floatToInt(float value)
|
||||
{
|
||||
return round(value);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
{
|
||||
extern const uint32_t dio_kNumSystems;
|
||||
extern const uint32_t solenoid_kNumDO7_0Elements;
|
||||
extern const uint32_t interrupt_kNumSystems;
|
||||
extern const uint32_t kSystemClockTicksPerMicrosecond;
|
||||
|
||||
void* getPort(uint8_t pin);
|
||||
void* getPortWithModule(uint8_t module, uint8_t pin);
|
||||
void freePort(void* port);
|
||||
const char* getHALErrorMessage(int32_t code);
|
||||
|
||||
uint16_t getFPGAVersion(int32_t *status);
|
||||
uint32_t getFPGARevision(int32_t *status);
|
||||
uint64_t getFPGATime(int32_t *status);
|
||||
|
||||
bool getFPGAButton(int32_t *status);
|
||||
|
||||
int HALSetErrorData(const char *errors, int errorsLength, int wait_ms);
|
||||
int HALSendError(int isError, int32_t errorCode, int isLVCode,
|
||||
const char *details, const char *location, const char *callStack,
|
||||
int printMsg);
|
||||
|
||||
int HALGetControlWord(HALControlWord *data);
|
||||
int HALGetAllianceStation(enum HALAllianceStationID *allianceStation);
|
||||
int HALGetJoystickAxes(uint8_t joystickNum, HALJoystickAxes *axes);
|
||||
int HALGetJoystickPOVs(uint8_t joystickNum, HALJoystickPOVs *povs);
|
||||
int HALGetJoystickButtons(uint8_t joystickNum, HALJoystickButtons *buttons);
|
||||
int HALGetJoystickDescriptor(uint8_t joystickNum, HALJoystickDescriptor *desc);
|
||||
int HALGetJoystickIsXbox(uint8_t joystickNum);
|
||||
int HALGetJoystickType(uint8_t joystickNum);
|
||||
char* HALGetJoystickName(uint8_t joystickNum);
|
||||
int HALGetJoystickAxisType(uint8_t joystickNum, uint8_t axis);
|
||||
int HALSetJoystickOutputs(uint8_t joystickNum, uint32_t outputs, uint16_t leftRumble, uint16_t rightRumble);
|
||||
int HALGetMatchTime(float *matchTime);
|
||||
|
||||
void HALSetNewDataSem(MULTIWAIT_ID sem);
|
||||
|
||||
bool HALGetSystemActive(int32_t *status);
|
||||
bool HALGetBrownedOut(int32_t *status);
|
||||
|
||||
int HALInitialize(int mode = 0);
|
||||
void HALNetworkCommunicationObserveUserProgramStarting();
|
||||
void HALNetworkCommunicationObserveUserProgramDisabled();
|
||||
void HALNetworkCommunicationObserveUserProgramAutonomous();
|
||||
void HALNetworkCommunicationObserveUserProgramTeleop();
|
||||
void HALNetworkCommunicationObserveUserProgramTest();
|
||||
|
||||
uint32_t HALReport(uint8_t resource, uint8_t instanceNumber, uint8_t context = 0,
|
||||
const char *feature = NULL);
|
||||
}
|
||||
|
||||
// TODO: HACKS for now...
|
||||
extern "C"
|
||||
{
|
||||
|
||||
void NumericArrayResize();
|
||||
void RTSetCleanupProc();
|
||||
void EDVR_CreateReference();
|
||||
void Occur();
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <iostream>
|
||||
#include "errno.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
typedef void (*InterruptHandlerFunction)(uint32_t interruptAssertedMask, void *param);
|
||||
|
||||
void* initializeInterrupts(uint32_t interruptIndex, bool watcher, int32_t *status);
|
||||
void cleanInterrupts(void* interrupt_pointer, int32_t *status);
|
||||
|
||||
uint32_t waitForInterrupt(void* interrupt_pointer, double timeout, bool ignorePrevious, int32_t *status);
|
||||
void enableInterrupts(void* interrupt_pointer, int32_t *status);
|
||||
void disableInterrupts(void* interrupt_pointer, int32_t *status);
|
||||
double readRisingTimestamp(void* interrupt_pointer, int32_t *status);
|
||||
double readFallingTimestamp(void* interrupt_pointer, int32_t *status);
|
||||
void requestInterrupts(void* interrupt_pointer, uint8_t routing_module, uint32_t routing_pin,
|
||||
bool routing_analog_trigger, int32_t *status);
|
||||
void attachInterruptHandler(void* interrupt_pointer, InterruptHandlerFunction handler,
|
||||
void* param, int32_t *status);
|
||||
void setInterruptUpSourceEdge(void* interrupt_pointer, bool risingEdge, bool fallingEdge,
|
||||
int32_t *status);
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
void* initializeNotifier(void (*process)(uint64_t, void*), void* param, int32_t *status);
|
||||
void cleanNotifier(void* notifier_pointer, int32_t *status);
|
||||
void* getNotifierParam(void* notifier_pointer, int32_t *status);
|
||||
void updateNotifierAlarm(void* notifier_pointer, uint64_t triggerTime, int32_t *status);
|
||||
void stopNotifierAlarm(void* notifier_pointer, int32_t *status);
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
void initializePDP(uint8_t module);
|
||||
double getPDPTemperature(uint8_t module, int32_t *status);
|
||||
double getPDPVoltage(uint8_t module, int32_t *status);
|
||||
double getPDPChannelCurrent(uint8_t module, uint8_t channel, int32_t *status);
|
||||
double getPDPTotalCurrent(uint8_t module, int32_t *status);
|
||||
double getPDPTotalPower(uint8_t module, int32_t *status);
|
||||
double getPDPTotalEnergy(uint8_t module, int32_t *status);
|
||||
void resetPDPTotalEnergy(uint8_t module, int32_t *status);
|
||||
void clearPDPStickyFaults(uint8_t module, int32_t *status);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user