test-util.h 8.91 KB
Newer Older
Kenton Varda's avatar
Kenton Varda committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
// Copyright (c) 2013, Kenton Varda <temporal@gmail.com>
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
// 2. 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.
//
// 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.

Kenton Varda's avatar
Kenton Varda committed
24 25
#ifndef CAPNP_TEST_UTIL_H_
#define CAPNP_TEST_UTIL_H_
Kenton Varda's avatar
Kenton Varda committed
26

27
#include <capnp/test.capnp.h>
Kenton Varda's avatar
Kenton Varda committed
28 29
#include <iostream>
#include "blob.h"
30
#include "dynamic.h"
31
#include <gtest/gtest.h>
Kenton Varda's avatar
Kenton Varda committed
32

33 34 35 36 37 38 39 40 41 42 43 44 45 46
#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

47
namespace capnp {
Kenton Varda's avatar
Kenton Varda committed
48 49

inline std::ostream& operator<<(std::ostream& os, const Data::Reader& value) {
50
  return os.write(reinterpret_cast<const char*>(value.begin()), value.size());
Kenton Varda's avatar
Kenton Varda committed
51 52
}
inline std::ostream& operator<<(std::ostream& os, const Data::Builder& value) {
53
  return os.write(reinterpret_cast<const char*>(value.begin()), value.size());
Kenton Varda's avatar
Kenton Varda committed
54 55
}
inline std::ostream& operator<<(std::ostream& os, const Text::Reader& value) {
56
  return os.write(value.begin(), value.size());
Kenton Varda's avatar
Kenton Varda committed
57 58
}
inline std::ostream& operator<<(std::ostream& os, const Text::Builder& value) {
59
  return os.write(value.begin(), value.size());
Kenton Varda's avatar
Kenton Varda committed
60 61 62 63 64
}
inline std::ostream& operator<<(std::ostream& os, Void) {
  return os << "void";
}

65
namespace _ {  // private
Kenton Varda's avatar
Kenton Varda committed
66

67 68 69 70
inline Data::Reader data(const char* str) {
  return Data::Reader(reinterpret_cast<const byte*>(str), strlen(str));
}

71
namespace test = capnproto_test::capnp::test;
Kenton Varda's avatar
Kenton Varda committed
72

73 74
// 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.
75 76 77 78 79 80 81 82
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
83

84 85
void initTestMessage(TestAllTypes::Builder builder);
void initTestMessage(TestDefaults::Builder builder);
86
void initTestMessage(TestListDefaults::Builder builder);
Kenton Varda's avatar
Kenton Varda committed
87

88 89
void checkTestMessage(TestAllTypes::Builder builder);
void checkTestMessage(TestDefaults::Builder builder);
90
void checkTestMessage(TestListDefaults::Builder builder);
91

92 93
void checkTestMessage(TestAllTypes::Reader reader);
void checkTestMessage(TestDefaults::Reader reader);
94
void checkTestMessage(TestListDefaults::Reader reader);
95 96 97

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

99 100 101 102 103 104 105 106 107
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);

108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
template <typename T, typename U>
void checkList(T reader, std::initializer_list<U> expected) {
  ASSERT_EQ(expected.size(), reader.size());
  for (uint i = 0; i < expected.size(); i++) {
    EXPECT_EQ(expected.begin()[i], reader[i]);
  }
}

template <typename T>
void checkList(T reader, std::initializer_list<float> expected) {
  ASSERT_EQ(expected.size(), reader.size());
  for (uint i = 0; i < expected.size(); i++) {
    EXPECT_FLOAT_EQ(expected.begin()[i], reader[i]);
  }
}

template <typename T>
void checkList(T reader, std::initializer_list<double> expected) {
  ASSERT_EQ(expected.size(), reader.size());
  for (uint i = 0; i < expected.size(); i++) {
    EXPECT_DOUBLE_EQ(expected.begin()[i], reader[i]);
  }
}

// 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); }

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]);
  }
}

#undef as

158 159 160 161 162 163 164
// =======================================================================================
// Interface implementations.

class TestInterfaceImpl final: public test::TestInterface::Server {
public:
  TestInterfaceImpl(int& callCount);

165
  kj::Promise<void> foo(FooContext context) override;
166

167
  kj::Promise<void> baz(BazContext context) override;
168 169 170 171 172 173 174 175 176

private:
  int& callCount;
};

class TestExtendsImpl final: public test::TestExtends::Server {
public:
  TestExtendsImpl(int& callCount);

177
  kj::Promise<void> foo(FooContext context) override;
178

179
  kj::Promise<void> grault(GraultContext context) override;
180 181 182 183 184 185 186 187 188

private:
  int& callCount;
};

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

189
  kj::Promise<void> getCap(GetCapContext context) override;
190 191 192 193 194

private:
  int& callCount;
};

195 196
class TestCallOrderImpl final: public test::TestCallOrder::Server {
public:
197
  kj::Promise<void> getCallSequence(GetCallSequenceContext context) override;
198 199 200 201 202 203 204 205 206

private:
  uint count = 0;
};

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

207
  kj::Promise<void> foo(FooContext context) override;
208 209 210 211 212 213 214 215 216

private:
  int& callCount;
};

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

217
  kj::Promise<void> foo(FooContext context) override;
218 219 220 221 222

private:
  int& callCount;
};

223 224 225 226
class TestMoreStuffImpl final: public test::TestMoreStuff::Server {
public:
  TestMoreStuffImpl(int& callCount);

227
  kj::Promise<void> getCallSequence(GetCallSequenceContext context) override;
228

229
  kj::Promise<void> callFoo(CallFooContext context) override;
230

231
  kj::Promise<void> callFooWhenResolved(CallFooWhenResolvedContext context) override;
232

233
  kj::Promise<void> neverReturn(NeverReturnContext context) override;
234

235
  kj::Promise<void> hold(HoldContext context) override;
236

237
  kj::Promise<void> callHeld(CallHeldContext context) override;
238

239
  kj::Promise<void> getHeld(GetHeldContext context) override;
240

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

243
  kj::Promise<void> expectCancel(ExpectCancelContext context) override;
244

245 246
private:
  int& callCount;
247
  test::TestInterface::Client clientToHold = nullptr;
248

249
  kj::Promise<void> loop(uint depth, test::TestInterface::Client cap, ExpectCancelContext context);
250 251 252 253 254 255 256 257 258 259 260 261 262
};

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();
  }

263 264
  kj::Promise<void> foo(FooContext context) {
    return impl.foo(context);
265 266 267 268 269 270
  }

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

273
}  // namespace _ (private)
274
}  // namespace capnp
Kenton Varda's avatar
Kenton Varda committed
275 276

#endif  // TEST_UTIL_H_