cannam@134
|
1 // Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors
|
cannam@134
|
2 // Licensed under the MIT License:
|
cannam@134
|
3 //
|
cannam@134
|
4 // Permission is hereby granted, free of charge, to any person obtaining a copy
|
cannam@134
|
5 // of this software and associated documentation files (the "Software"), to deal
|
cannam@134
|
6 // in the Software without restriction, including without limitation the rights
|
cannam@134
|
7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
cannam@134
|
8 // copies of the Software, and to permit persons to whom the Software is
|
cannam@134
|
9 // furnished to do so, subject to the following conditions:
|
cannam@134
|
10 //
|
cannam@134
|
11 // The above copyright notice and this permission notice shall be included in
|
cannam@134
|
12 // all copies or substantial portions of the Software.
|
cannam@134
|
13 //
|
cannam@134
|
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
cannam@134
|
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
cannam@134
|
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
cannam@134
|
17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
cannam@134
|
18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
cannam@134
|
19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
cannam@134
|
20 // THE SOFTWARE.
|
cannam@134
|
21
|
cannam@134
|
22 #ifndef CAPNP_TEST_UTIL_H_
|
cannam@134
|
23 #define CAPNP_TEST_UTIL_H_
|
cannam@134
|
24
|
cannam@134
|
25 #if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS)
|
cannam@134
|
26 #pragma GCC system_header
|
cannam@134
|
27 #endif
|
cannam@134
|
28
|
cannam@134
|
29 #include <capnp/test.capnp.h>
|
cannam@134
|
30 #include <iostream>
|
cannam@134
|
31 #include "blob.h"
|
cannam@134
|
32 #include <kj/compat/gtest.h>
|
cannam@134
|
33
|
cannam@134
|
34 #if !CAPNP_LITE
|
cannam@134
|
35 #include "dynamic.h"
|
cannam@134
|
36 #endif // !CAPNP_LITE
|
cannam@134
|
37
|
cannam@134
|
38 #if KJ_NO_EXCEPTIONS
|
cannam@134
|
39 #undef EXPECT_ANY_THROW
|
cannam@134
|
40 #define EXPECT_ANY_THROW(code) EXPECT_DEATH(code, ".")
|
cannam@134
|
41 #endif
|
cannam@134
|
42
|
cannam@134
|
43 #define EXPECT_NONFATAL_FAILURE(code) \
|
cannam@134
|
44 EXPECT_TRUE(kj::runCatchingExceptions([&]() { code; }) != nullptr);
|
cannam@134
|
45
|
cannam@134
|
46 #ifdef KJ_DEBUG
|
cannam@134
|
47 #define EXPECT_DEBUG_ANY_THROW EXPECT_ANY_THROW
|
cannam@134
|
48 #else
|
cannam@134
|
49 #define EXPECT_DEBUG_ANY_THROW(EXP)
|
cannam@134
|
50 #endif
|
cannam@134
|
51
|
cannam@134
|
52 // TODO(cleanup): Auto-generate stringification functions for union discriminants.
|
cannam@134
|
53 namespace capnproto_test {
|
cannam@134
|
54 namespace capnp {
|
cannam@134
|
55 namespace test {
|
cannam@134
|
56 inline kj::String KJ_STRINGIFY(TestUnion::Union0::Which which) {
|
cannam@134
|
57 return kj::str(static_cast<uint16_t>(which));
|
cannam@134
|
58 }
|
cannam@134
|
59 inline kj::String KJ_STRINGIFY(TestUnion::Union1::Which which) {
|
cannam@134
|
60 return kj::str(static_cast<uint16_t>(which));
|
cannam@134
|
61 }
|
cannam@134
|
62 inline kj::String KJ_STRINGIFY(TestUnion::Union2::Which which) {
|
cannam@134
|
63 return kj::str(static_cast<uint16_t>(which));
|
cannam@134
|
64 }
|
cannam@134
|
65 inline kj::String KJ_STRINGIFY(TestUnion::Union3::Which which) {
|
cannam@134
|
66 return kj::str(static_cast<uint16_t>(which));
|
cannam@134
|
67 }
|
cannam@134
|
68 inline kj::String KJ_STRINGIFY(TestUnnamedUnion::Which which) {
|
cannam@134
|
69 return kj::str(static_cast<uint16_t>(which));
|
cannam@134
|
70 }
|
cannam@134
|
71 inline kj::String KJ_STRINGIFY(TestGroups::Groups::Which which) {
|
cannam@134
|
72 return kj::str(static_cast<uint16_t>(which));
|
cannam@134
|
73 }
|
cannam@134
|
74 inline kj::String KJ_STRINGIFY(TestInterleavedGroups::Group1::Which which) {
|
cannam@134
|
75 return kj::str(static_cast<uint16_t>(which));
|
cannam@134
|
76 }
|
cannam@134
|
77 } // namespace test
|
cannam@134
|
78 } // namespace capnp
|
cannam@134
|
79 } // namespace capnproto_test
|
cannam@134
|
80
|
cannam@134
|
81 namespace capnp {
|
cannam@134
|
82 namespace _ { // private
|
cannam@134
|
83
|
cannam@134
|
84 inline Data::Reader data(const char* str) {
|
cannam@134
|
85 return Data::Reader(reinterpret_cast<const byte*>(str), strlen(str));
|
cannam@134
|
86 }
|
cannam@134
|
87
|
cannam@134
|
88 namespace test = capnproto_test::capnp::test;
|
cannam@134
|
89
|
cannam@134
|
90 // We don't use "using namespace" to pull these in because then things would still compile
|
cannam@134
|
91 // correctly if they were generated in the global namespace.
|
cannam@134
|
92 using ::capnproto_test::capnp::test::TestAllTypes;
|
cannam@134
|
93 using ::capnproto_test::capnp::test::TestDefaults;
|
cannam@134
|
94 using ::capnproto_test::capnp::test::TestEnum;
|
cannam@134
|
95 using ::capnproto_test::capnp::test::TestUnion;
|
cannam@134
|
96 using ::capnproto_test::capnp::test::TestUnionDefaults;
|
cannam@134
|
97 using ::capnproto_test::capnp::test::TestNestedTypes;
|
cannam@134
|
98 using ::capnproto_test::capnp::test::TestUsing;
|
cannam@134
|
99 using ::capnproto_test::capnp::test::TestListDefaults;
|
cannam@134
|
100
|
cannam@134
|
101 void initTestMessage(TestAllTypes::Builder builder);
|
cannam@134
|
102 void initTestMessage(TestDefaults::Builder builder);
|
cannam@134
|
103 void initTestMessage(TestListDefaults::Builder builder);
|
cannam@134
|
104
|
cannam@134
|
105 void checkTestMessage(TestAllTypes::Builder builder);
|
cannam@134
|
106 void checkTestMessage(TestDefaults::Builder builder);
|
cannam@134
|
107 void checkTestMessage(TestListDefaults::Builder builder);
|
cannam@134
|
108
|
cannam@134
|
109 void checkTestMessage(TestAllTypes::Reader reader);
|
cannam@134
|
110 void checkTestMessage(TestDefaults::Reader reader);
|
cannam@134
|
111 void checkTestMessage(TestListDefaults::Reader reader);
|
cannam@134
|
112
|
cannam@134
|
113 void checkTestMessageAllZero(TestAllTypes::Builder builder);
|
cannam@134
|
114 void checkTestMessageAllZero(TestAllTypes::Reader reader);
|
cannam@134
|
115
|
cannam@134
|
116 #if !CAPNP_LITE
|
cannam@134
|
117 void initDynamicTestMessage(DynamicStruct::Builder builder);
|
cannam@134
|
118 void initDynamicTestLists(DynamicStruct::Builder builder);
|
cannam@134
|
119 void checkDynamicTestMessage(DynamicStruct::Builder builder);
|
cannam@134
|
120 void checkDynamicTestLists(DynamicStruct::Builder builder);
|
cannam@134
|
121 void checkDynamicTestMessage(DynamicStruct::Reader reader);
|
cannam@134
|
122 void checkDynamicTestLists(DynamicStruct::Reader reader);
|
cannam@134
|
123 void checkDynamicTestMessageAllZero(DynamicStruct::Builder builder);
|
cannam@134
|
124 void checkDynamicTestMessageAllZero(DynamicStruct::Reader reader);
|
cannam@134
|
125 #endif // !CAPNP_LITE
|
cannam@134
|
126
|
cannam@134
|
127 template <typename T>
|
cannam@134
|
128 inline void checkElement(T a, T b) {
|
cannam@134
|
129 EXPECT_EQ(a, b);
|
cannam@134
|
130 }
|
cannam@134
|
131
|
cannam@134
|
132 template <>
|
cannam@134
|
133 inline void checkElement<float>(float a, float b) {
|
cannam@134
|
134 EXPECT_FLOAT_EQ(a, b);
|
cannam@134
|
135 }
|
cannam@134
|
136
|
cannam@134
|
137 template <>
|
cannam@134
|
138 inline void checkElement<double>(double a, double b) {
|
cannam@134
|
139 EXPECT_DOUBLE_EQ(a, b);
|
cannam@134
|
140 }
|
cannam@134
|
141
|
cannam@134
|
142 template <typename T, typename L = typename T::Reads>
|
cannam@134
|
143 void checkList(T reader, std::initializer_list<decltype(reader[0])> expected) {
|
cannam@134
|
144 ASSERT_EQ(expected.size(), reader.size());
|
cannam@134
|
145 for (uint i = 0; i < expected.size(); i++) {
|
cannam@134
|
146 checkElement<decltype(reader[0])>(expected.begin()[i], reader[i]);
|
cannam@134
|
147 }
|
cannam@134
|
148 }
|
cannam@134
|
149
|
cannam@134
|
150 template <typename T, typename L = typename T::Builds, bool = false>
|
cannam@134
|
151 void checkList(T reader, std::initializer_list<decltype(typename L::Reader()[0])> expected) {
|
cannam@134
|
152 ASSERT_EQ(expected.size(), reader.size());
|
cannam@134
|
153 for (uint i = 0; i < expected.size(); i++) {
|
cannam@134
|
154 checkElement<decltype(typename L::Reader()[0])>(expected.begin()[i], reader[i]);
|
cannam@134
|
155 }
|
cannam@134
|
156 }
|
cannam@134
|
157
|
cannam@134
|
158 inline void checkList(List<test::TestOldVersion>::Reader reader,
|
cannam@134
|
159 std::initializer_list<int64_t> expectedData,
|
cannam@134
|
160 std::initializer_list<Text::Reader> expectedPointers) {
|
cannam@134
|
161 ASSERT_EQ(expectedData.size(), reader.size());
|
cannam@134
|
162 for (uint i = 0; i < expectedData.size(); i++) {
|
cannam@134
|
163 EXPECT_EQ(expectedData.begin()[i], reader[i].getOld1());
|
cannam@134
|
164 EXPECT_EQ(expectedPointers.begin()[i], reader[i].getOld2());
|
cannam@134
|
165 }
|
cannam@134
|
166 }
|
cannam@134
|
167
|
cannam@134
|
168 // Hack because as<>() is a template-parameter-dependent lookup everywhere below...
|
cannam@134
|
169 #define as template as
|
cannam@134
|
170
|
cannam@134
|
171 template <typename T> void expectPrimitiveEq(T a, T b) { EXPECT_EQ(a, b); }
|
cannam@134
|
172 inline void expectPrimitiveEq(float a, float b) { EXPECT_FLOAT_EQ(a, b); }
|
cannam@134
|
173 inline void expectPrimitiveEq(double a, double b) { EXPECT_DOUBLE_EQ(a, b); }
|
cannam@134
|
174 inline void expectPrimitiveEq(Text::Reader a, Text::Builder b) { EXPECT_EQ(a, b); }
|
cannam@134
|
175 inline void expectPrimitiveEq(Data::Reader a, Data::Builder b) { EXPECT_EQ(a, b); }
|
cannam@134
|
176
|
cannam@134
|
177 #if !CAPNP_LITE
|
cannam@134
|
178 template <typename Element, typename T>
|
cannam@134
|
179 void checkList(T reader, std::initializer_list<ReaderFor<Element>> expected) {
|
cannam@134
|
180 auto list = reader.as<DynamicList>();
|
cannam@134
|
181 ASSERT_EQ(expected.size(), list.size());
|
cannam@134
|
182 for (uint i = 0; i < expected.size(); i++) {
|
cannam@134
|
183 expectPrimitiveEq(expected.begin()[i], list[i].as<Element>());
|
cannam@134
|
184 }
|
cannam@134
|
185
|
cannam@134
|
186 auto typed = reader.as<List<Element>>();
|
cannam@134
|
187 ASSERT_EQ(expected.size(), typed.size());
|
cannam@134
|
188 for (uint i = 0; i < expected.size(); i++) {
|
cannam@134
|
189 expectPrimitiveEq(expected.begin()[i], typed[i]);
|
cannam@134
|
190 }
|
cannam@134
|
191 }
|
cannam@134
|
192 #endif // !CAPNP_LITE
|
cannam@134
|
193
|
cannam@134
|
194 #undef as
|
cannam@134
|
195
|
cannam@134
|
196 // =======================================================================================
|
cannam@134
|
197 // Interface implementations.
|
cannam@134
|
198
|
cannam@134
|
199 #if !CAPNP_LITE
|
cannam@134
|
200
|
cannam@134
|
201 class TestInterfaceImpl final: public test::TestInterface::Server {
|
cannam@134
|
202 public:
|
cannam@134
|
203 TestInterfaceImpl(int& callCount);
|
cannam@134
|
204
|
cannam@134
|
205 kj::Promise<void> foo(FooContext context) override;
|
cannam@134
|
206
|
cannam@134
|
207 kj::Promise<void> baz(BazContext context) override;
|
cannam@134
|
208
|
cannam@134
|
209 private:
|
cannam@134
|
210 int& callCount;
|
cannam@134
|
211 };
|
cannam@134
|
212
|
cannam@134
|
213 class TestExtendsImpl final: public test::TestExtends2::Server {
|
cannam@134
|
214 public:
|
cannam@134
|
215 TestExtendsImpl(int& callCount);
|
cannam@134
|
216
|
cannam@134
|
217 kj::Promise<void> foo(FooContext context) override;
|
cannam@134
|
218
|
cannam@134
|
219 kj::Promise<void> grault(GraultContext context) override;
|
cannam@134
|
220
|
cannam@134
|
221 private:
|
cannam@134
|
222 int& callCount;
|
cannam@134
|
223 };
|
cannam@134
|
224
|
cannam@134
|
225 class TestPipelineImpl final: public test::TestPipeline::Server {
|
cannam@134
|
226 public:
|
cannam@134
|
227 TestPipelineImpl(int& callCount);
|
cannam@134
|
228
|
cannam@134
|
229 kj::Promise<void> getCap(GetCapContext context) override;
|
cannam@134
|
230
|
cannam@134
|
231 private:
|
cannam@134
|
232 int& callCount;
|
cannam@134
|
233 };
|
cannam@134
|
234
|
cannam@134
|
235 class TestCallOrderImpl final: public test::TestCallOrder::Server {
|
cannam@134
|
236 public:
|
cannam@134
|
237 kj::Promise<void> getCallSequence(GetCallSequenceContext context) override;
|
cannam@134
|
238
|
cannam@134
|
239 private:
|
cannam@134
|
240 uint count = 0;
|
cannam@134
|
241 };
|
cannam@134
|
242
|
cannam@134
|
243 class TestTailCallerImpl final: public test::TestTailCaller::Server {
|
cannam@134
|
244 public:
|
cannam@134
|
245 TestTailCallerImpl(int& callCount);
|
cannam@134
|
246
|
cannam@134
|
247 kj::Promise<void> foo(FooContext context) override;
|
cannam@134
|
248
|
cannam@134
|
249 private:
|
cannam@134
|
250 int& callCount;
|
cannam@134
|
251 };
|
cannam@134
|
252
|
cannam@134
|
253 class TestTailCalleeImpl final: public test::TestTailCallee::Server {
|
cannam@134
|
254 public:
|
cannam@134
|
255 TestTailCalleeImpl(int& callCount);
|
cannam@134
|
256
|
cannam@134
|
257 kj::Promise<void> foo(FooContext context) override;
|
cannam@134
|
258
|
cannam@134
|
259 private:
|
cannam@134
|
260 int& callCount;
|
cannam@134
|
261 };
|
cannam@134
|
262
|
cannam@134
|
263 class TestMoreStuffImpl final: public test::TestMoreStuff::Server {
|
cannam@134
|
264 public:
|
cannam@134
|
265 TestMoreStuffImpl(int& callCount, int& handleCount);
|
cannam@134
|
266
|
cannam@134
|
267 kj::Promise<void> getCallSequence(GetCallSequenceContext context) override;
|
cannam@134
|
268
|
cannam@134
|
269 kj::Promise<void> callFoo(CallFooContext context) override;
|
cannam@134
|
270
|
cannam@134
|
271 kj::Promise<void> callFooWhenResolved(CallFooWhenResolvedContext context) override;
|
cannam@134
|
272
|
cannam@134
|
273 kj::Promise<void> neverReturn(NeverReturnContext context) override;
|
cannam@134
|
274
|
cannam@134
|
275 kj::Promise<void> hold(HoldContext context) override;
|
cannam@134
|
276
|
cannam@134
|
277 kj::Promise<void> callHeld(CallHeldContext context) override;
|
cannam@134
|
278
|
cannam@134
|
279 kj::Promise<void> getHeld(GetHeldContext context) override;
|
cannam@134
|
280
|
cannam@134
|
281 kj::Promise<void> echo(EchoContext context) override;
|
cannam@134
|
282
|
cannam@134
|
283 kj::Promise<void> expectCancel(ExpectCancelContext context) override;
|
cannam@134
|
284
|
cannam@134
|
285 kj::Promise<void> getHandle(GetHandleContext context) override;
|
cannam@134
|
286
|
cannam@134
|
287 kj::Promise<void> getNull(GetNullContext context) override;
|
cannam@134
|
288
|
cannam@134
|
289 private:
|
cannam@134
|
290 int& callCount;
|
cannam@134
|
291 int& handleCount;
|
cannam@134
|
292 test::TestInterface::Client clientToHold = nullptr;
|
cannam@134
|
293
|
cannam@134
|
294 kj::Promise<void> loop(uint depth, test::TestInterface::Client cap, ExpectCancelContext context);
|
cannam@134
|
295 };
|
cannam@134
|
296
|
cannam@134
|
297 class TestCapDestructor final: public test::TestInterface::Server {
|
cannam@134
|
298 // Implementation of TestInterface that notifies when it is destroyed.
|
cannam@134
|
299
|
cannam@134
|
300 public:
|
cannam@134
|
301 TestCapDestructor(kj::Own<kj::PromiseFulfiller<void>>&& fulfiller)
|
cannam@134
|
302 : fulfiller(kj::mv(fulfiller)), impl(dummy) {}
|
cannam@134
|
303
|
cannam@134
|
304 ~TestCapDestructor() {
|
cannam@134
|
305 fulfiller->fulfill();
|
cannam@134
|
306 }
|
cannam@134
|
307
|
cannam@134
|
308 kj::Promise<void> foo(FooContext context) {
|
cannam@134
|
309 return impl.foo(context);
|
cannam@134
|
310 }
|
cannam@134
|
311
|
cannam@134
|
312 private:
|
cannam@134
|
313 kj::Own<kj::PromiseFulfiller<void>> fulfiller;
|
cannam@134
|
314 int dummy = 0;
|
cannam@134
|
315 TestInterfaceImpl impl;
|
cannam@134
|
316 };
|
cannam@134
|
317
|
cannam@134
|
318 #endif // !CAPNP_LITE
|
cannam@134
|
319
|
cannam@134
|
320 } // namespace _ (private)
|
cannam@134
|
321 } // namespace capnp
|
cannam@134
|
322
|
cannam@134
|
323 #endif // TEST_UTIL_H_
|