File Coverage

t/svapi/sub.cc
Criterion Covered Total %
statement 204 204 100.0
branch 964 2032 47.4
condition n/a
subroutine n/a
pod n/a
total 1168 2236 52.2


line stmt bran cond sub pod time code
1             #include "test.h"
2             #include
3             #include
4              
5             using Test = TestSv;
6              
7 16           void cmp_array (const Array& a, const std::initializer_list& l) {
8 16 50         REQUIRE(a.size() == l.size());
    50          
    50          
    50          
    50          
    50          
    0          
    0          
9 16           auto chk = l.begin();
10 48 100         for (size_t i = 0; i < l.size(); ++i) CHECK(a[i] == chk[i]);
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
11 16           }
12              
13             template
14 3           void cmp_array (const std::array& a, const std::initializer_list& l) {
15 3 50         REQUIRE(a.size() == l.size());
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
16 3           auto chk = l.begin();
17 12 100         for (size_t i = 0; i < l.size(); ++i) CHECK(a[i] == chk[i]);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    100          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    100          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
18 3           }
19              
20 137           TEST_CASE("Sub", "[Sv]") {
21 206 50         perlvars vars;
22 206 50         Sub my(vars.cv);
23 206           Sv oth_valid(vars.cv), oth_invalid(vars.gv);
24              
25 137 50         SECTION("ctor") {
    50          
    50          
    50          
    100          
26 35 50         SECTION("empty") {
    50          
    50          
    50          
    100          
27 2           Sub o;
28 1 50         REQUIRE(!o);
    50          
    50          
    50          
    0          
    0          
29             }
30 58 50         SECTION("SV") {
    50          
    50          
    50          
    100          
31 24 50         SECTION("undef SV") { Test::ctor(vars.undef, behaviour_t::EMPTY); }
    50          
    50          
    50          
    100          
    50          
32 24 50         SECTION("number SV") { Test::ctor(vars.iv, behaviour_t::THROWS); }
    50          
    50          
    50          
    100          
    50          
33 24 50         SECTION("string SV") { Test::ctor(vars.pv, behaviour_t::THROWS); }
    50          
    50          
    50          
    100          
    50          
34 24 50         SECTION("RV") { Test::ctor(vars.rv, behaviour_t::THROWS); }
    50          
    50          
    50          
    100          
    50          
35 24 50         SECTION("RV-OAV") { Test::ctor(vars.oavr, behaviour_t::THROWS); }
    50          
    50          
    50          
    100          
    50          
36 24 50         SECTION("RV-OHV") { Test::ctor(vars.ohvr, behaviour_t::THROWS); }
    50          
    50          
    50          
    100          
    50          
37 24 50         SECTION("RV-CV") { Test::ctor(vars.cvr, behaviour_t::VALID, (SV*)vars.cv); }
    50          
    50          
    50          
    100          
    50          
38 24 50         SECTION("AV") { Test::ctor((SV*)vars.av, behaviour_t::THROWS); }
    50          
    50          
    50          
    100          
    50          
39 24 50         SECTION("HV") { Test::ctor((SV*)vars.hv, behaviour_t::THROWS); }
    50          
    50          
    50          
    100          
    50          
40 24 50         SECTION("CV") { Test::ctor((SV*)vars.cv, behaviour_t::VALID); }
    50          
    50          
    50          
    100          
    50          
41 24 50         SECTION("GV") { Test::ctor((SV*)vars.gv, behaviour_t::THROWS); }
    50          
    50          
    50          
    100          
    50          
42 24 50         SECTION("IO") { Test::ctor((SV*)vars.io, behaviour_t::THROWS); }
    50          
    50          
    50          
    100          
    50          
43             }
44 34 50         SECTION("CV") { Test::ctor(vars.cv, behaviour_t::VALID); }
    50          
    50          
    50          
    100          
    50          
45              
46 34 50         SECTION("Sub") { Test::ctor(my, behaviour_t::VALID); }
    50          
    50          
    50          
    100          
    50          
47 34 50         SECTION("valid Sv") { Test::ctor(oth_valid, behaviour_t::VALID); }
    50          
    50          
    50          
    100          
    50          
48 34 50         SECTION("invalid Sv") { Test::ctor(oth_invalid, behaviour_t::THROWS); }
    50          
    50          
    50          
    100          
    50          
49              
50 35 50         SECTION("from string") {
    50          
    50          
    50          
    100          
51 2 50         Sub c("M1::dummy2");
52 1 50         REQUIRE(c);
    50          
    50          
    50          
    0          
    0          
53 1 50         REQUIRE(c.get() == get_cv("M1::dummy2", 0));
    50          
    50          
    50          
    50          
    50          
    0          
    0          
54 2 50         Sub c2("M1::nonexistent");
55 1 50         REQUIRE(!c2);
    50          
    50          
    50          
    0          
    0          
56 2 50         Sub c3("M1::nonexistent", GV_ADD);
57 1 50         REQUIRE(c3);
    50          
    50          
    50          
    0          
    0          
58 1 50         REQUIRE(c3.get() == get_cv("M1::nonexistent", 0));
    50          
    50          
    50          
    50          
    50          
    0          
    0          
59             }
60             }
61              
62 141 50         SECTION("operator=") {
    50          
    50          
    50          
    100          
63 76 50         Sub o("M1::dummy2");
64 62 50         SECTION("SV") {
    50          
    50          
    50          
    100          
65 24 50         SECTION("undef SV") { Test::assign(o, vars.undef, behaviour_t::EMPTY); }
    50          
    50          
    50          
    100          
    50          
66 24 50         SECTION("number SV") { Test::assign(o, vars.iv, behaviour_t::THROWS); }
    50          
    50          
    50          
    100          
    50          
67 24 50         SECTION("string SV") { Test::assign(o, vars.pv, behaviour_t::THROWS); }
    50          
    50          
    50          
    100          
    50          
68 24 50         SECTION("RV") { Test::assign(o, vars.rv, behaviour_t::THROWS); }
    50          
    50          
    50          
    100          
    50          
69 24 50         SECTION("RV-OAV") { Test::assign(o, vars.oavr, behaviour_t::THROWS); }
    50          
    50          
    50          
    100          
    50          
70 24 50         SECTION("RV-OHV") { Test::assign(o, vars.ohvr, behaviour_t::THROWS); }
    50          
    50          
    50          
    100          
    50          
71 24 50         SECTION("RV-CV") { Test::assign(o, vars.cvr, behaviour_t::VALID, (SV*)vars.cv); }
    50          
    50          
    50          
    100          
    50          
72 24 50         SECTION("AV") { Test::assign(o, (SV*)vars.av, behaviour_t::THROWS); }
    50          
    50          
    50          
    100          
    50          
73 24 50         SECTION("HV") { Test::assign(o, (SV*)vars.hv, behaviour_t::THROWS); }
    50          
    50          
    50          
    100          
    50          
74 24 50         SECTION("CV") { Test::assign(o, (SV*)vars.cv, behaviour_t::VALID); }
    50          
    50          
    50          
    100          
    50          
75 24 50         SECTION("GV") { Test::assign(o, (SV*)vars.gv, behaviour_t::THROWS); }
    50          
    50          
    50          
    100          
    50          
76 24 50         SECTION("IO") { Test::assign(o, (SV*)vars.io, behaviour_t::THROWS); }
    50          
    50          
    50          
    100          
    50          
77             }
78 38 50         SECTION("CV") { Test::assign(o, vars.cv, behaviour_t::VALID); }
    50          
    50          
    50          
    100          
    50          
79 38 50         SECTION("Sub") { Test::assign(o, my, behaviour_t::VALID); }
    50          
    50          
    50          
    100          
    50          
80 38 50         SECTION("valid Sv") { Test::assign(o, oth_valid, behaviour_t::VALID); }
    50          
    50          
    50          
    100          
    50          
81 38 50         SECTION("invalid Sv") { Test::assign(o, oth_invalid, behaviour_t::THROWS); }
    50          
    50          
    50          
    100          
    50          
82             }
83              
84 104 50         SECTION("set") {
    50          
    50          
    50          
    100          
85 2           Sub o;
86 1 50         o.set(vars.iv); // no checks
87 1 50         REQUIRE(o);
    50          
    50          
    50          
    0          
    0          
88 1 50         REQUIRE(SvREFCNT(vars.iv) == 2);
    50          
    50          
    50          
    50          
    0          
    0          
89 1 50         REQUIRE(o.get() == vars.iv);
    50          
    50          
    50          
    50          
    0          
    0          
90             }
91              
92 105 50         SECTION("cast") {
    50          
    50          
    50          
    100          
93 4 50         Sub o(vars.cv);
94 2           auto rcnt = SvREFCNT(vars.cv);
95 3 50         SECTION("to SV") {
    50          
    50          
    50          
    100          
96 1           SV* sv = o;
97 1 50         REQUIRE(sv == (SV*)vars.cv);
    50          
    50          
    50          
    50          
    0          
    0          
98 1 50         REQUIRE(SvREFCNT(vars.cv) == rcnt);
    50          
    50          
    50          
    50          
    0          
    0          
99             }
100 3 50         SECTION("to CV") {
    50          
    50          
    50          
    100          
101 1           CV* sv = o;
102 1 50         REQUIRE(sv == vars.cv);
    50          
    50          
    50          
    50          
    0          
    0          
103 1 50         REQUIRE(SvREFCNT(vars.cv) == rcnt);
    50          
    50          
    50          
    50          
    0          
    0          
104             }
105             }
106              
107 104 50         SECTION("get") {
    50          
    50          
    50          
    100          
108 2 50         Sub o(vars.cv);
109 1           auto rcnt = SvREFCNT(vars.cv);
110 1 50         REQUIRE(o.get<>() == (SV*)vars.cv);
    50          
    50          
    50          
    50          
    0          
    0          
111 1 50         REQUIRE(o.get() == (SV*)vars.cv);
    50          
    50          
    50          
    50          
    0          
    0          
112 1 50         REQUIRE(o.get() == vars.cv);
    50          
    50          
    50          
    50          
    0          
    0          
113 1 50         REQUIRE(SvREFCNT(vars.cv) == rcnt);
    50          
    50          
    50          
    50          
    0          
    0          
114             }
115              
116 104 50         SECTION("stash") {
    50          
    50          
    50          
    100          
117 2 50         Sub o("M1::dummy");
118 1 50         REQUIRE(o.stash());
    50          
    50          
    50          
    50          
    0          
    0          
119 1 50         REQUIRE(o.stash() == gv_stashpvs("M1", 0));
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
120             }
121              
122 104 50         SECTION("glob") {
    50          
    50          
    50          
    100          
123 2 50         Sub o("M1::dummy");
124 1 50         REQUIRE(o.glob());
    50          
    50          
    50          
    50          
    0          
    0          
125 1 50         REQUIRE(o.glob() == Stash("M1")["dummy"]);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
126             }
127              
128 104 50         SECTION("name") {
    50          
    50          
    50          
    100          
129 2 50         Sub o("M1::dummy");
130 1 50         REQUIRE(o.name() == "dummy");
    50          
    50          
    50          
    50          
    50          
    0          
    0          
131             }
132              
133 104 50         SECTION("named") {
    50          
    50          
    50          
    100          
134 2 50         Sub o("M1::dummy");
135 1 50         REQUIRE(!o.named());
    50          
    50          
    50          
    0          
    0          
136             }
137              
138 125 50         SECTION("call") {
    50          
    50          
    50          
    100          
139 44 50         Stash s("M1");
140 44 50         Simple call_cnt = s.scalar("call_cnt");
    50          
141 44 50         Simple call_ret = s.scalar("call_ret");
    50          
142 22 50         call_cnt = 0;
143              
144 35 50         SECTION("args") {
    50          
    50          
    50          
    100          
145 26 50         auto sub = s.sub("check_args");
146 14 50         SECTION("empty") {
    50          
    50          
    50          
    100          
147 1 50         cmp_array(sub.call(), {});
    50          
    50          
148 1 50         CHECK(call_cnt == 1);
    50          
    50          
    50          
    50          
    0          
    0          
149 1 50         cmp_array(sub(), {});
    50          
    50          
150 1 50         CHECK(call_cnt == 2);
    50          
    50          
    50          
    50          
    0          
    0          
151             }
152 14 50         SECTION("SV*") {
    50          
    50          
    50          
    100          
153 1 50         cmp_array(sub.call(Simple(999).get()), {999});
    50          
    50          
    50          
154             }
155 14 50         SECTION("SV**") {
    50          
    50          
    50          
    100          
156 2 50         Simple arg1(100), arg2(200);
    50          
157 1           SV* args[] = {arg1, arg2};
158 1 50         cmp_array(sub.call(args, 2), {100, 200});
    50          
    50          
159             }
160 14 50         SECTION("SV* + SV**") {
    50          
    50          
    50          
    100          
161 2 50         Simple arg1(100), arg2(200), arg3(300);
    50          
    50          
162 1           SV* args[] = {arg2, arg3};
163 1 50         cmp_array(sub.call(Simple(100).get(), args, 2), {100, 200, 300});
    50          
    50          
    50          
164             }
165 14 50         SECTION("const Scalar*") {
    50          
    50          
    50          
    100          
    0          
166 4 50         Scalar args[] = {Simple(111), Simple(222)};
    50          
    100          
    0          
    0          
167 1 50         cmp_array(sub.call(args, 2), {111, 222});
    50          
    50          
168             }
169 14 50         SECTION("SV* + const Scalar*") {
    50          
    50          
    50          
    100          
    0          
170 4 50         Scalar args[] = {Simple(111), Simple(222)};
    50          
    100          
    0          
    0          
171 1 50         cmp_array(sub.call(Simple(666).get(), args, 2), {666, 111, 222});
    50          
    50          
    50          
172             }
173 14 50         SECTION("ilist") {
    50          
    50          
    50          
    100          
    0          
174 4 50         std::initializer_list l = {Simple(123), Simple(321)};
    50          
    100          
    0          
    0          
175 1 50         cmp_array(sub.call(l), {123, 321});
    50          
    50          
176             }
177 14 50         SECTION("SV* + ilist") {
    50          
    50          
    50          
    100          
    0          
178 4 50         std::initializer_list l = {Simple(300), Simple(400)};
    50          
    100          
    0          
    0          
179 1 50         cmp_array(sub.call(Simple(7).get(), l), {7, 300, 400});
    50          
    50          
    50          
180             }
181 14 50         SECTION("variadic-1") {
    50          
    50          
    50          
    100          
182 2 50         Simple arg(10);
183 1 50         cmp_array(sub.call(arg), {10});
    50          
    50          
184 1 50         CHECK(arg.use_count() == 1); // check for argument leaks
    50          
    50          
    50          
    50          
    0          
    0          
185             }
186 14 50         SECTION("variadic-2") {
    50          
    50          
    50          
    100          
187 1 50         cmp_array(sub.call(Simple(10), Simple(20)), {10, 20});
    50          
    50          
    50          
    50          
188             }
189 14 50         SECTION("variadic-3") {
    50          
    50          
    50          
    100          
190 1 50         cmp_array(sub.call(Simple(10), Simple(20), Scalar(Simple(100))), {10, 20, 100});
    50          
    50          
    50          
    50          
    50          
191             }
192 14 50         SECTION("variadic-4") {
    50          
    50          
    50          
    100          
193 1 50         cmp_array(sub.call(Simple(10), Simple(20), Scalar(Simple(100)), Sv(Simple(200))), {10, 20, 100, 200});
    50          
    50          
    50          
    50          
    50          
    50          
194             }
195 14 50         SECTION("empty/nullptr -> undef") {
    50          
    50          
    50          
    100          
196 2 50         Array ret = sub.call(Simple(10), nullptr, Simple());
    50          
    50          
197 1 50         CHECK(ret.use_count() == 1); // check for retval leaks
    50          
    50          
    50          
    50          
    0          
    0          
198 1 50         REQUIRE(ret.size() == 3);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
199 1 50         CHECK(ret[0] == 10);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
200 1 50         CHECK(!ret[1].defined());
    50          
    50          
    50          
    50          
    0          
    0          
201 1 50         CHECK(!ret[2].defined());
    50          
    50          
    50          
    50          
    0          
    0          
202             }
203             }
204              
205 30 50         SECTION("context") {
    50          
    50          
    50          
    100          
206 16 50         auto sub = s.sub("check_context");
207 9 50         SECTION("void") {
    50          
    50          
    50          
    100          
208             static_assert(std::is_same()),void>::value, "wrong signature");
209 1 50         sub.call(Simple(333));
    50          
210 1 50         CHECK(call_cnt == 1);
    50          
    50          
    50          
    50          
    0          
    0          
211 1 50         CHECK(call_ret == 333);
    50          
    50          
    50          
    50          
    0          
    0          
212             }
213 9 50         SECTION("scalar") {
    50          
    50          
    50          
    100          
214             static_assert(std::is_same::value, "wrong signature");
215             static_assert(std::is_same()),Scalar>::value, "wrong signature");
216             static_assert(std::is_same()),Simple>::value, "wrong signature");
217 1 50         CHECK(sub.call(Simple(999)) == 999);
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
218 1 50         CHECK(sub.call(Simple(999), Simple(111)) == 999);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
219 1 50         CHECK(!sub.call().defined());
    50          
    50          
    50          
    50          
    0          
    0          
220             }
221 9 50         SECTION("fixed-list array") {
    50          
    50          
    50          
    100          
222             static_assert(std::is_same>()),std::array>::value, "wrong signature");
223 1 50         cmp_array(sub.call>(Simple(1), Simple(2), Simple(3)), {1,2,3});
    50          
    50          
    50          
    50          
224 1 50         cmp_array(sub.call>(Simple(4), Simple(5), Simple(6)), {4,5});
    50          
    50          
    50          
    50          
225 1 50         cmp_array(sub.call>(Simple(7), Simple(8), Simple(9)), {7,8,9,0});
    50          
    50          
    50          
    50          
226             }
227 10 50         SECTION("fixed-list tuple") {
    50          
    50          
    50          
    100          
228             using Tuple = std::tuple;
229             static_assert(std::is_same()),Tuple>::value, "wrong signature");
230             static_assert(std::is_same()),Tuple>::value, "wrong signature");
231 3 50         SECTION("explicit") {
    50          
    50          
    50          
    100          
232 2 50         Tuple res = sub.call(Simple(10), Simple(20), Simple(30));
    50          
    50          
    50          
233 1 50         CHECK(Simple(std::get<0>(res)) == 10);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
234 1 50         CHECK(std::get<1>(res) == 20);
    50          
    50          
    50          
    50          
    0          
    0          
235 1 50         CHECK(std::get<2>(res) == 30);
    50          
    50          
    50          
    50          
    0          
    0          
236 1 50         CHECK(!std::get<3>(res));
    50          
    50          
    50          
    0          
    0          
237             }
238 3 50         SECTION("implicit") {
    50          
    50          
    50          
    100          
239 2 50         Tuple res = sub.call(Simple(50), Simple(60), Simple(70), Ref::create(Simple(111)), Simple(999));
    50          
    50          
    50          
    50          
    50          
    50          
240 1 50         CHECK(Simple(std::get<0>(res)) == 50);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
241 1 50         CHECK(std::get<1>(res) == 60);
    50          
    50          
    50          
    50          
    0          
    0          
242 1 50         CHECK(std::get<2>(res) == 70);
    50          
    50          
    50          
    50          
    0          
    0          
243 2 50         auto ref = std::get<3>(res);
244 1 50         CHECK(ref);
    50          
    50          
    50          
    0          
    0          
245 1 50         CHECK(ref.value() == 111);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
246             }
247             }
248 9 50         SECTION("unlimited-list") {
    50          
    50          
    50          
    100          
249             static_assert(std::is_same()),List>::value, "wrong signature");
250 1 50         cmp_array(sub.call(Simple(10), Simple(20), Simple(30)), {10, 20, 30});
    50          
    50          
    50          
    50          
251             }
252 9 50         SECTION("panda::string") {
    50          
    50          
    50          
    100          
253             static_assert(std::is_same()),panda::string>::value, "wrong signature");
254 2 50         auto str = sub.call(Simple("suka"));
    50          
255 1 50         CHECK(str == "suka");
    50          
    50          
    50          
    50          
    0          
    0          
256             }
257 9 50         SECTION("numeric") {
    50          
    50          
    50          
    100          
258             static_assert(std::is_same()),int>::value, "wrong signature");
259             static_assert(std::is_same()),double>::value, "wrong signature");
260 1 50         CHECK(sub.call(Simple(200)) == 200);
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
261 1 50         CHECK(sub.call(Simple(1.234)) == 1.234);
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
262 1 50         CHECK(sub.call(Simple(1.234)) == 1);
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
263             }
264             }
265              
266 23 50         SECTION("call result as argument") {
    50          
    50          
    50          
    100          
267 2 50         auto sub = s.sub("check_args");
268 2 50         Array ret = sub.call( sub.call(Simple(999)), sub.call(Simple(888), Simple(777)) );
    50          
    50          
    50          
    50          
    50          
    50          
269 1 50         cmp_array(ret[0], {999});
    50          
    50          
270 1 50         cmp_array(ret[1], {888, 777});
    50          
    50          
271             }
272             }
273              
274 104 50         SECTION("super/super_strict") {
    50          
    50          
    50          
    100          
275 2 50         Sub sub("M4::meth");
276 1 50         sub = sub.SUPER();
277 1 50         REQUIRE(sub == Sub("M2::meth"));
    50          
    50          
    50          
    50          
    50          
    0          
    0          
278 1 50         sub = sub.SUPER_strict();
279 1 50         REQUIRE(sub == Sub("M1::meth"));
    50          
    50          
    50          
    50          
    50          
    0          
    0          
280 1 50         REQUIRE(!sub.SUPER());
    50          
    50          
    50          
    50          
    0          
    0          
281 1 50         REQUIRE_THROWS(sub.SUPER_strict());
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
282             }
283 239 50         }
    50