1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 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
|
/* Copyright 2017-present Facebook, Inc.
* Licensed under the Apache License, Version 2.0 */
#include "watchman_system.h"
#include <string>
#include "Result.h"
#include "thirdparty/tap.h"
using namespace watchman;
void test_empty() {
Result<bool> b;
ok(b.empty(), "default constructed and empty");
try {
b.throwIfError();
ok(false, "expected to throw");
} catch (const std::logic_error&) {
ok(true, "throwIfError throws logic error for empty result");
}
try {
b.value();
ok(false, "expected to throw");
} catch (const std::logic_error&) {
ok(true, "throwIfError throws logic error for empty result");
}
try {
b.error();
ok(false, "expected to throw");
} catch (const std::logic_error&) {
ok(true, "throwIfError throws logic error for empty result");
}
}
void test_simple_value() {
auto b = makeResult(true);
ok(!b.empty(), "b is not empty");
ok(b.hasValue(), "b has a value");
ok(b.value(), "b holds true");
Result<bool> copyOfB(b);
ok(!b.empty(), "b is not empty after being copied");
ok(!copyOfB.empty(), "copyOfB is not empty");
ok(copyOfB.hasValue(), "copyOfB has a value");
ok(copyOfB.value(), "copyOfB holds true");
Result<bool> movedB(std::move(b));
ok(b.empty(), "b empty after move");
ok(!movedB.empty(), "movedB is not empty");
ok(movedB.hasValue(), "movedB has a value");
ok(movedB.value(), "movedB holds true");
b = movedB;
ok(!b.empty(), "b is not empty after copying");
ok(b.hasValue(), "b has a value");
ok(b.value(), "b holds true");
b = std::move(copyOfB);
ok(!b.empty(), "b is not empty after copying");
ok(b.hasValue(), "b has a value");
ok(b.value(), "b holds true");
ok(copyOfB.empty(), "copyOfB is empty after being moved");
}
void test_error() {
auto a = makeResultWith([] { return std::string("noice"); });
ok(a.hasValue(), "got a value");
ok(a.value() == "noice", "got our string out");
using atype = decltype(a);
auto is_string = std::is_same<typename atype::value_type, std::string>::value;
ok(is_string, "a has std::string as a value type");
auto b = makeResultWith([] { throw std::runtime_error("w00t"); });
ok(b.hasError(), "we got an exception contained");
try {
b.throwIfError();
ok(false, "should not get here");
} catch (const std::logic_error&) {
ok(false, "should not have caught logic_error");
} catch (const std::runtime_error& exc) {
ok(!strcmp(exc.what(), "w00t"), "have our exception message in the error");
}
using btype = decltype(b);
auto is_unit = std::is_same<typename btype::value_type, Unit>::value;
ok(is_unit, "b has Unit as a value type");
auto c = makeResultWith([] {
if (false) {
return 42;
}
throw std::runtime_error("gah");
});
using ctype = decltype(c);
auto is_int = std::is_same<typename ctype::value_type, int>::value;
ok(is_int, "c has int as a value type");
ok(c.hasError(), "c has an error");
}
void test_non_exception_error_type() {
Result<std::string, int> result("hello");
ok(result.hasValue(), "has value");
ok(result.value() == "hello", "has hello string");
result = Result<std::string, int>(42);
ok(result.hasError(), "holding error");
ok(result.error() == 42, "holding 42");
try {
result.throwIfError();
ok(false, "should not get here");
} catch (const std::logic_error&) {
ok(true, "got logic error");
}
}
int main() {
plan_tests(35);
test_empty();
test_simple_value();
test_error();
test_non_exception_error_type();
return exit_status();
}
|