test-util.h 10.1 KB
Newer Older
Kenton Varda's avatar
Kenton Varda committed
1 2
// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
Kenton Varda's avatar
Kenton Varda committed
3
//
Kenton Varda's avatar
Kenton Varda committed
4 5 6 7 8 9
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
Kenton Varda's avatar
Kenton Varda committed
10
//
Kenton Varda's avatar
Kenton Varda committed
11 12
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
Kenton Varda's avatar
Kenton Varda committed
13
//
Kenton Varda's avatar
Kenton Varda committed
14 15 16 17 18 19 20
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
Kenton Varda's avatar
Kenton Varda committed
21

Kenton Varda's avatar
Kenton Varda committed
22 23
#ifndef CAPNP_TEST_UTIL_H_
#define CAPNP_TEST_UTIL_H_
Kenton Varda's avatar
Kenton Varda committed
24

25
#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS)
26 27 28
#pragma GCC system_header
#endif

29
#include <capnp/test.capnp.h>
Kenton Varda's avatar
Kenton Varda committed
30 31
#include <iostream>
#include "blob.h"
32
#include <kj/compat/gtest.h>
Kenton Varda's avatar
Kenton Varda committed
33

34 35 36 37
#if !CAPNP_LITE
#include "dynamic.h"
#endif  // !CAPNP_LITE

38 39 40 41 42 43 44 45 46 47 48 49 50 51
#if KJ_NO_EXCEPTIONS
#undef EXPECT_ANY_THROW
#define EXPECT_ANY_THROW(code) EXPECT_DEATH(code, ".")
#endif

#define EXPECT_NONFATAL_FAILURE(code) \
  EXPECT_TRUE(kj::runCatchingExceptions([&]() { code; }) != nullptr);

#ifdef KJ_DEBUG
#define EXPECT_DEBUG_ANY_THROW EXPECT_ANY_THROW
#else
#define EXPECT_DEBUG_ANY_THROW(EXP)
#endif

52 53
// TODO(cleanup): Auto-generate stringification functions for union discriminants.
namespace capnproto_test {
54
namespace capnp {
55 56 57 58 59 60
namespace test {
inline kj::String KJ_STRINGIFY(TestUnion::Union0::Which which) {
  return kj::str(static_cast<uint16_t>(which));
}
inline kj::String KJ_STRINGIFY(TestUnion::Union1::Which which) {
  return kj::str(static_cast<uint16_t>(which));
Kenton Varda's avatar
Kenton Varda committed
61
}
62 63
inline kj::String KJ_STRINGIFY(TestUnion::Union2::Which which) {
  return kj::str(static_cast<uint16_t>(which));
Kenton Varda's avatar
Kenton Varda committed
64
}
65 66
inline kj::String KJ_STRINGIFY(TestUnion::Union3::Which which) {
  return kj::str(static_cast<uint16_t>(which));
Kenton Varda's avatar
Kenton Varda committed
67
}
68 69
inline kj::String KJ_STRINGIFY(TestUnnamedUnion::Which which) {
  return kj::str(static_cast<uint16_t>(which));
Kenton Varda's avatar
Kenton Varda committed
70
}
71 72
inline kj::String KJ_STRINGIFY(TestGroups::Groups::Which which) {
  return kj::str(static_cast<uint16_t>(which));
Kenton Varda's avatar
Kenton Varda committed
73
}
74 75 76 77 78 79
inline kj::String KJ_STRINGIFY(TestInterleavedGroups::Group1::Which which) {
  return kj::str(static_cast<uint16_t>(which));
}
}  // namespace test
}  // namespace capnp
}  // namespace capnproto_test
Kenton Varda's avatar
Kenton Varda committed
80

81
namespace capnp {
82
namespace _ {  // private
Kenton Varda's avatar
Kenton Varda committed
83

84 85 86 87
inline Data::Reader data(const char* str) {
  return Data::Reader(reinterpret_cast<const byte*>(str), strlen(str));
}

88
namespace test = capnproto_test::capnp::test;
Kenton Varda's avatar
Kenton Varda committed
89

90 91
// We don't use "using namespace" to pull these in because then things would still compile
// correctly if they were generated in the global namespace.
92 93 94 95 96 97 98 99
using ::capnproto_test::capnp::test::TestAllTypes;
using ::capnproto_test::capnp::test::TestDefaults;
using ::capnproto_test::capnp::test::TestEnum;
using ::capnproto_test::capnp::test::TestUnion;
using ::capnproto_test::capnp::test::TestUnionDefaults;
using ::capnproto_test::capnp::test::TestNestedTypes;
using ::capnproto_test::capnp::test::TestUsing;
using ::capnproto_test::capnp::test::TestListDefaults;
Kenton Varda's avatar
Kenton Varda committed
100

101 102
void initTestMessage(TestAllTypes::Builder builder);
void initTestMessage(TestDefaults::Builder builder);
103
void initTestMessage(TestListDefaults::Builder builder);
Kenton Varda's avatar
Kenton Varda committed
104

105 106
void checkTestMessage(TestAllTypes::Builder builder);
void checkTestMessage(TestDefaults::Builder builder);
107
void checkTestMessage(TestListDefaults::Builder builder);
108

109 110
void checkTestMessage(TestAllTypes::Reader reader);
void checkTestMessage(TestDefaults::Reader reader);
111
void checkTestMessage(TestListDefaults::Reader reader);
112 113 114

void checkTestMessageAllZero(TestAllTypes::Builder builder);
void checkTestMessageAllZero(TestAllTypes::Reader reader);
115

116
#if !CAPNP_LITE
117 118 119 120 121 122 123 124
void initDynamicTestMessage(DynamicStruct::Builder builder);
void initDynamicTestLists(DynamicStruct::Builder builder);
void checkDynamicTestMessage(DynamicStruct::Builder builder);
void checkDynamicTestLists(DynamicStruct::Builder builder);
void checkDynamicTestMessage(DynamicStruct::Reader reader);
void checkDynamicTestLists(DynamicStruct::Reader reader);
void checkDynamicTestMessageAllZero(DynamicStruct::Builder builder);
void checkDynamicTestMessageAllZero(DynamicStruct::Reader reader);
125
#endif  // !CAPNP_LITE
126

127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
template <typename T>
inline void checkElement(T a, T b) {
  EXPECT_EQ(a, b);
}

template <>
inline void checkElement<float>(float a, float b) {
  EXPECT_FLOAT_EQ(a, b);
}

template <>
inline void checkElement<double>(double a, double b) {
  EXPECT_DOUBLE_EQ(a, b);
}

142
template <typename T, typename L = typename T::Reads>
143
void checkList(T reader, std::initializer_list<decltype(reader[0])> expected) {
144 145
  ASSERT_EQ(expected.size(), reader.size());
  for (uint i = 0; i < expected.size(); i++) {
146
    checkElement<decltype(reader[0])>(expected.begin()[i], reader[i]);
147 148 149
  }
}

150 151
template <typename T, typename L = typename T::Builds, bool = false>
void checkList(T reader, std::initializer_list<decltype(typename L::Reader()[0])> expected) {
152 153
  ASSERT_EQ(expected.size(), reader.size());
  for (uint i = 0; i < expected.size(); i++) {
154
    checkElement<decltype(typename L::Reader()[0])>(expected.begin()[i], reader[i]);
155 156 157
  }
}

158 159 160 161 162 163 164
inline void checkList(List<test::TestOldVersion>::Reader reader,
                      std::initializer_list<int64_t> expectedData,
                      std::initializer_list<Text::Reader> expectedPointers) {
  ASSERT_EQ(expectedData.size(), reader.size());
  for (uint i = 0; i < expectedData.size(); i++) {
    EXPECT_EQ(expectedData.begin()[i], reader[i].getOld1());
    EXPECT_EQ(expectedPointers.begin()[i], reader[i].getOld2());
165 166 167 168 169 170 171 172 173 174 175 176
  }
}

// Hack because as<>() is a template-parameter-dependent lookup everywhere below...
#define as template as

template <typename T> void expectPrimitiveEq(T a, T b) { EXPECT_EQ(a, b); }
inline void expectPrimitiveEq(float a, float b) { EXPECT_FLOAT_EQ(a, b); }
inline void expectPrimitiveEq(double a, double b) { EXPECT_DOUBLE_EQ(a, b); }
inline void expectPrimitiveEq(Text::Reader a, Text::Builder b) { EXPECT_EQ(a, b); }
inline void expectPrimitiveEq(Data::Reader a, Data::Builder b) { EXPECT_EQ(a, b); }

177
#if !CAPNP_LITE
178 179 180 181 182 183 184 185 186 187 188 189 190 191
template <typename Element, typename T>
void checkList(T reader, std::initializer_list<ReaderFor<Element>> expected) {
  auto list = reader.as<DynamicList>();
  ASSERT_EQ(expected.size(), list.size());
  for (uint i = 0; i < expected.size(); i++) {
    expectPrimitiveEq(expected.begin()[i], list[i].as<Element>());
  }

  auto typed = reader.as<List<Element>>();
  ASSERT_EQ(expected.size(), typed.size());
  for (uint i = 0; i < expected.size(); i++) {
    expectPrimitiveEq(expected.begin()[i], typed[i]);
  }
}
192
#endif  // !CAPNP_LITE
193 194 195

#undef as

196 197 198
// =======================================================================================
// Interface implementations.

199 200
#if !CAPNP_LITE

201 202 203 204
class TestInterfaceImpl final: public test::TestInterface::Server {
public:
  TestInterfaceImpl(int& callCount);

205
  kj::Promise<void> foo(FooContext context) override;
206

207
  kj::Promise<void> baz(BazContext context) override;
208 209 210 211 212

private:
  int& callCount;
};

213
class TestExtendsImpl final: public test::TestExtends2::Server {
214 215 216
public:
  TestExtendsImpl(int& callCount);

217
  kj::Promise<void> foo(FooContext context) override;
218

219
  kj::Promise<void> grault(GraultContext context) override;
220 221 222 223 224 225 226 227 228

private:
  int& callCount;
};

class TestPipelineImpl final: public test::TestPipeline::Server {
public:
  TestPipelineImpl(int& callCount);

229
  kj::Promise<void> getCap(GetCapContext context) override;
230 231 232 233 234

private:
  int& callCount;
};

235 236
class TestCallOrderImpl final: public test::TestCallOrder::Server {
public:
237
  kj::Promise<void> getCallSequence(GetCallSequenceContext context) override;
238 239 240 241 242 243 244 245 246

private:
  uint count = 0;
};

class TestTailCallerImpl final: public test::TestTailCaller::Server {
public:
  TestTailCallerImpl(int& callCount);

247
  kj::Promise<void> foo(FooContext context) override;
248 249 250 251 252 253 254 255 256

private:
  int& callCount;
};

class TestTailCalleeImpl final: public test::TestTailCallee::Server {
public:
  TestTailCalleeImpl(int& callCount);

257
  kj::Promise<void> foo(FooContext context) override;
258 259 260 261 262

private:
  int& callCount;
};

263 264
class TestMoreStuffImpl final: public test::TestMoreStuff::Server {
public:
265
  TestMoreStuffImpl(int& callCount, int& handleCount);
266

267
  kj::Promise<void> getCallSequence(GetCallSequenceContext context) override;
268

269
  kj::Promise<void> callFoo(CallFooContext context) override;
270

271
  kj::Promise<void> callFooWhenResolved(CallFooWhenResolvedContext context) override;
272

273
  kj::Promise<void> neverReturn(NeverReturnContext context) override;
274

275
  kj::Promise<void> hold(HoldContext context) override;
276

277
  kj::Promise<void> callHeld(CallHeldContext context) override;
278

279
  kj::Promise<void> getHeld(GetHeldContext context) override;
280

281
  kj::Promise<void> echo(EchoContext context) override;
Kenton Varda's avatar
Kenton Varda committed
282

283
  kj::Promise<void> expectCancel(ExpectCancelContext context) override;
284

285 286
  kj::Promise<void> getHandle(GetHandleContext context) override;

287 288
  kj::Promise<void> getNull(GetNullContext context) override;

289 290
private:
  int& callCount;
291
  int& handleCount;
292
  test::TestInterface::Client clientToHold = nullptr;
293

294
  kj::Promise<void> loop(uint depth, test::TestInterface::Client cap, ExpectCancelContext context);
295 296 297 298 299 300 301 302 303 304 305 306 307
};

class TestCapDestructor final: public test::TestInterface::Server {
  // Implementation of TestInterface that notifies when it is destroyed.

public:
  TestCapDestructor(kj::Own<kj::PromiseFulfiller<void>>&& fulfiller)
      : fulfiller(kj::mv(fulfiller)), impl(dummy) {}

  ~TestCapDestructor() {
    fulfiller->fulfill();
  }

308 309
  kj::Promise<void> foo(FooContext context) {
    return impl.foo(context);
310 311 312 313 314 315
  }

private:
  kj::Own<kj::PromiseFulfiller<void>> fulfiller;
  int dummy = 0;
  TestInterfaceImpl impl;
316 317
};

318 319
#endif  // !CAPNP_LITE

320
}  // namespace _ (private)
321
}  // namespace capnp
Kenton Varda's avatar
Kenton Varda committed
322 323

#endif  // TEST_UTIL_H_