AsmGrader 0.0.0
Loading...
Searching...
No Matches
macros.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <asmgrader/api/assignment.hpp> // IWYU pragma: export
4#include <asmgrader/api/test_base.hpp> // IWYU pragma: export
7#include <asmgrader/grading_session.hpp> // IWYU pragma: export
9#include <asmgrader/registrars/auto_registrars.hpp> // IWYU pragma: export
10
11// Some macros to substantially simplify test case development
12
13#define ASSIGNMENT(cpp_identifier, name, executable) \
14 const static Assignment& cpp_identifier = /* NOLINT(misc-use-anonymous-namespace)*/ \
15 ::asmgrader::GlobalRegistrar::get().add(Assignment{name, executable});
16
17#define TEST_IMPL(ident, name, /*metadata attributes*/...) \
18 namespace { \
19 class ident final : public ::asmgrader::TestBase \
20 { \
21 public: \
22 using TestBase::TestBase; \
23 void run(::asmgrader::TestContext& ctx) override; \
24 }; \
25 using namespace ::asmgrader::metadata; /*NOLINT(google-build-using-namespace)*/ \
26 constexpr auto CONCAT(ident, \
27 __metadata) = ::asmgrader::metadata::create(::asmgrader::metadata::DEFAULT_METADATA, \
28 ::asmgrader::metadata::global_file_metadata() \
29 __VA_OPT__(, ) __VA_ARGS__); \
30 const ::asmgrader::TestAutoRegistrar<ident> CONCAT(ident, __registrar){name, CONCAT(ident, __metadata)}; \
31 } \
32 void ident::run([[maybe_unused]] ::asmgrader::TestContext& ctx)
33
34#define TEST(name, ...) TEST_IMPL(CONCAT(TEST__, __COUNTER__), name __VA_OPT__(, ) __VA_ARGS__)
35
36// Simple way to ensure that no instructions are generated for prof-only tests when
37// compiling for the students' version
38#ifdef PROFESSOR_VERSION
39#define PROF_ONLY_TEST(name, ...) TEST(name, ProfOnly __VA_OPT__(, ) __VA_ARGS__)
40#else
41#define PROF_ONLY_TEST(name, ...) [[maybe_unused]] static void CONCAT(prof_test_unused, __COUNTER__)(TestContext & ctx)
42#endif // PROFESSOR_VERSION
43
44#define REQUIRE(condition, ...) \
45 __extension__({ \
46 auto cond__var = condition; \
47 bool cond__bool__val = static_cast<bool>(cond__var); \
48 if (!cond__bool__val) { \
49 LOG_DEBUG("Requirement failed: {}", cond__var); \
50 } \
51 ctx.require(cond__bool__val, __VA_ARGS__ __VA_OPT__(, )::asmgrader::RequirementResult::DebugInfo{#condition}); \
52 })
53
54#define REQUIRE_EQ(lhs, rhs, ...) \
55 __extension__({ \
56 const auto& req_eq_lhs__ = (lhs); \
57 const auto& req_eq_rhs__ = (rhs); \
58 bool req_eq_res__ = \
59 ctx.require(req_eq_lhs__ == req_eq_rhs__, \
60 __VA_ARGS__ __VA_OPT__(, )::asmgrader::RequirementResult::DebugInfo{#lhs " == " #rhs}); \
61 if (!req_eq_res__) { \
62 LOG_DEBUG("{} != {}", (req_eq_lhs__), (req_eq_rhs__)); \
63 } \
64 req_eq_res__; \
65 })
66
67#define FILE_METADATA(...) \
68 namespace asmgrader::metadata { \
69 consteval auto global_file_metadata() { \
70 using ::asmgrader::metadata::Assignment, metadata::Weight, metadata::ProfOnly; \
71 return ::asmgrader::metadata::Metadata{__VA_ARGS__}; \
72 } \
73 } // namespace metadata
Defines data classes to store result data for the current run session.