Commit 554e7a0e authored by Kenton Varda's avatar Kenton Varda

Add KJ-test macros for expecting exceptions and log messages.

parent 3864b685
......@@ -57,6 +57,41 @@ TestCase::~TestCase() {
namespace _ { // private
bool hasSubstring(kj::StringPtr haystack, kj::StringPtr needle) {
// TODO(perf): This is not the best algorithm for substring matching.
for (size_t i = 0; i <= haystack.size() - needle.size(); i++) {
if (haystack.slice(i).startsWith(needle)) {
return true;
}
}
return false;
}
LogExpectation::LogExpectation(LogSeverity severity, StringPtr substring)
: severity(severity), substring(substring), seen(false) {}
LogExpectation::~LogExpectation() {
if (!unwindDetector.isUnwinding()) {
KJ_ASSERT(seen, "expected log message not seen", severity, substring);
}
}
void LogExpectation::logMessage(
LogSeverity severity, const char* file, int line, int contextDepth,
String&& text) {
if (!seen && severity == this->severity) {
if (hasSubstring(text, substring)) {
// Match. Ignore it.
seen = true;
return;
}
}
// Pass up the chain.
ExceptionCallback::logMessage(severity, file, line, contextDepth, kj::mv(text));
}
// =======================================================================================
GlobFilter::GlobFilter(const char* pattern): pattern(heapString(pattern)) {}
GlobFilter::GlobFilter(ArrayPtr<const char> pattern): pattern(heapString(pattern)) {}
......
......@@ -73,10 +73,52 @@ private:
if (cond); else KJ_FAIL_EXPECT("failed: expected " #cond, ##__VA_ARGS__)
#endif
#define KJ_EXPECT_THROW(type, code) \
do { \
KJ_IF_MAYBE(e, ::kj::runCatchingExceptions([&]() { code; })) { \
KJ_EXPECT(e->getType() == ::kj::Exception::Type::type, \
"code threw wrong exception type: " #code, e->getType()); \
} else { \
KJ_FAIL_EXPECT("code did not throw: " #code); \
} \
} while (false)
#define KJ_EXPECT_THROW_MESSAGE(message, code) \
do { \
KJ_IF_MAYBE(e, ::kj::runCatchingExceptions([&]() { code; })) { \
KJ_EXPECT(::kj::_::hasSubstring(e->getDescription(), message), \
"exception description didn't contain expected substring", e->getDescription()); \
} else { \
KJ_FAIL_EXPECT("code did not throw: " #code); \
} \
} while (false)
#define KJ_EXPECT_LOG(level, substring) \
::kj::_::LogExpectation KJ_UNIQUE_NAME(_kjLogExpectation)(::kj::LogSeverity::level, substring)
// Expects that a log message with the given level and substring text will be printed within
// the current scope. This message will not cause the test to fail, even if it is an error.
// =======================================================================================
namespace _ { // private
bool hasSubstring(kj::StringPtr haystack, kj::StringPtr needle);
class LogExpectation: public ExceptionCallback {
public:
LogExpectation(LogSeverity severity, StringPtr substring);
~LogExpectation();
void logMessage(LogSeverity severity, const char* file, int line, int contextDepth,
String&& text) override;
private:
LogSeverity severity;
StringPtr substring;
bool seen;
UnwindDetector unwindDetector;
};
class GlobFilter {
// Implements glob filters for the --filter flag.
//
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment