Hegel 0.13.3
Property-based testing for C++
Loading...
Searching...
No Matches
hegel.h
1#pragma once
2
333
334#include "core.h"
335#include "settings.h"
336#include "test_case.h"
337
338#include "generators/builds.h"
339#include "generators/collections.h"
340#include "generators/combinators.h"
341#include "generators/default.h"
342#include "generators/formats.h"
343#include "generators/numeric.h"
344#include "generators/primitives.h"
345#include "generators/random.h"
346#include "generators/stateful.h"
347#include "generators/strings.h"
348
349#include <functional>
350
351#if defined(__GNUC__) || defined(__clang__) || \
352 (defined(_MSC_VER) && _MSC_VER >= 1927)
353#define HEGEL_CALLER_FILE __builtin_FILE()
354#define HEGEL_CALLER_FUNCTION __builtin_FUNCTION()
355#define HEGEL_CALLER_LINE __builtin_LINE()
356#else
357#define HEGEL_CALLER_FILE ""
358#define HEGEL_CALLER_FUNCTION ""
359#define HEGEL_CALLER_LINE 0
360#endif
361
365namespace hegel {
366
393 class FailureOrigin {
394 public:
395 FailureOrigin() = default;
396 virtual ~FailureOrigin() = default;
398 FailureOrigin(const FailureOrigin&) = default;
401 FailureOrigin& operator=(const FailureOrigin&) = default;
402
407 virtual std::string failure_origin() const = 0;
408 };
409
421 std::string name;
423 std::string file;
425 int line = 0;
426 };
427
476 void test(const std::function<void(TestCase&)>& test_fn,
477 const Settings& settings = {},
478 const std::vector<std::string>& failure_blobs = {},
479 const char* caller_file = HEGEL_CALLER_FILE,
480 const char* caller_function = HEGEL_CALLER_FUNCTION,
481 int caller_line = HEGEL_CALLER_LINE);
482
503 void test(const std::function<void(TestCase&)>& test_fn,
504 const TestLocation& location, const Settings& settings = {},
505 const std::vector<std::string>& failure_blobs = {});
506
508 namespace internal {
509 // How a test framework passes information to Hegel
510 struct FrameworkHooks {
511 // Names the framework test that runs now, or "" outside one.
512 std::string (*current_test_name)() = nullptr;
513 // Runs one test-case body, raising the failed assertions the
514 // framework recorded.
515 void (*run_case)(const std::function<void()>&) = nullptr;
516 };
517
518 // Makes `hooks` the integration every later run uses. Returns true, so
519 // an integration header can install from a variable initializer and
520 // have it happen before main().
521 bool install_framework_hooks(const FrameworkHooks& hooks);
522
523 // add a blob for a test to run
524 bool register_blob(const char* name, std::vector<const char*> blobs);
525 // look up the failure blobs associated with a test
526 std::vector<std::string> reproduce_blobs_for(const char* name);
527
528 // What HEGEL_TEST expands to.
529 void test_from_macro(const std::function<void(TestCase&)>& test_fn,
530 const TestLocation& location,
531 const Settings& settings,
532 const std::vector<std::string>& failure_blobs);
533 } // namespace internal
535} // namespace hegel
536
542
579#define HEGEL_TEST(name, ...) \
580 static void hegel_test_body_##name(::hegel::TestCase&); \
581 static void name(::hegel::Settings settings = \
582 ::hegel::Settings(__VA_ARGS__)) { \
583 if (!settings.database_key.has_value()) { \
584 settings.database_key = __FILE__ "::" #name; \
585 } \
586 ::hegel::internal::test_from_macro( \
587 hegel_test_body_##name, \
588 ::hegel::TestLocation{#name, __FILE__, __LINE__}, settings, \
589 ::hegel::internal::reproduce_blobs_for(__FILE__ "::" #name)); \
590 } \
591 static void hegel_test_body_##name
592
617#define HEGEL_REPRODUCE_FAILURE(name, blob, ...) \
618 [[maybe_unused]] static const bool hegel_reproduce_registered_##name = \
619 ::hegel::internal::register_blob(__FILE__ "::" #name, \
620 {blob, __VA_ARGS__});
621
622
623// GoogleTest integration, picked up when <gtest/gtest.h> is already visible.
624// Include <hegel/gtest.h> yourself if this header comes first.
625#if defined(GTEST_TEST)
626#include "gtest.h"
627#endif
FailureOrigin(const FailureOrigin &)=default
Copy-constructs. An origin holds no state of its own.
virtual std::string failure_origin() const =0
The origin grouping this failure.
FailureOrigin & operator=(const FailureOrigin &)=default
Handle to the currently-executing test case.
Definition test_case.h:40
Main namespace.
Definition config.h:29
void test(const std::function< void(TestCase &)> &test_fn, const Settings &settings={}, const std::vector< std::string > &failure_blobs={}, const char *caller_file=HEGEL_CALLER_FILE, const char *caller_function=HEGEL_CALLER_FUNCTION, int caller_line=HEGEL_CALLER_LINE)
Run a Hegel test.
Configuration options for hegel::test().
Definition settings.h:212
Where a test is defined.
Definition hegel.h:419
int line
Line the test is defined on.
Definition hegel.h:425
std::string name
Test name, as it appears in the report header.
Definition hegel.h:421
std::string file
Source file the test is defined in.
Definition hegel.h:423