Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion include/kota/deco/deco.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
#include "kota/deco/facade/config.h"
#include "kota/deco/facade/decl.h"
#include "kota/deco/facade/descriptor.h"
#include "kota/deco/facade/macro.h"
#include "kota/deco/facade/runtime.h"
#include "kota/deco/facade/serialize.h"
#include "kota/deco/facade/trait.h"
#include "kota/deco/facade/ty.h"
#include "kota/deco/macro.h"
12 changes: 9 additions & 3 deletions include/kota/deco/facade/macro.h → include/kota/deco/macro.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
#pragma once
#include <type_traits>

#include "decl.h"
#include "trait.h"
// The deco declaration macros, and nothing else — this header includes nothing,
// by design. Modules cannot export macros, so a downstream consuming kotatsu as
// a module still has to pick these up textually, and anything included here
// would duplicate declarations the module already provides.
Comment thread
16bit-ykiko marked this conversation as resolved.
//
// The names an expansion refers to only have to be visible where the macro is
// used, not here: kota::deco::decl and kota::deco::trait, plus std::string,
// std::vector, std::uint32_t and std::remove_cvref_t. Including
// "kota/deco/deco.h" or importing the module covers all of them.

#define DECO_CONCAT_IMPL(a, b) a##b
#define DECO_CONCAT(a, b) DECO_CONCAT_IMPL(a, b)
Expand Down
15 changes: 10 additions & 5 deletions include/kota/zest/macro.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
#pragma once

#include "kota/zest/assert/check.h"
#include "kota/zest/assert/trace.h"
#include "kota/zest/runner/suite.h"
#include "kota/zest/snapshot/snapshot.h"
// The zest test macros, and nothing else — this header includes nothing, by
// design. Modules cannot export macros, so a downstream consuming kotatsu as a
// module still has to pick these up textually, and anything included here would
// duplicate declarations the module already provides.
Comment thread
16bit-ykiko marked this conversation as resolved.
//
// The kota::zest entities an expansion refers to only have to be visible where
// the macro is used, not here. Include "kota/zest/zest.h" or import the module.

#define TEST_SUITE(name, ...) \
struct name##TEST : __VA_OPT__(__VA_ARGS__, )::kota::zest::TestSuiteDef<name##TEST>
Expand Down Expand Up @@ -171,8 +174,10 @@

#endif

// Gated on the header being reachable, but deliberately not including it — the
// snapshot-JSON macros need ::kota::codec::json visible at the use site, which
// "kota/zest/zest.h" arranges under the same condition.
#if __has_include("kota/codec/json/json.h")
#include "kota/codec/json/json.h"

// clang-format off
#define ZEST_SNAPSHOT_JSON_IMPL(return_action, value, ...) \
Expand Down
10 changes: 10 additions & 0 deletions include/kota/zest/zest.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
#pragma once

#include "kota/zest/assert/check.h"
#include "kota/zest/assert/trace.h"
#include "kota/zest/macro.h"
#include "kota/zest/runner/run.h"
#include "kota/zest/runner/suite.h"
#include "kota/zest/snapshot/snapshot.h"

// Matches the guard "kota/zest/macro.h" uses for the snapshot-JSON macros, which
// name ::kota::codec::json but cannot include it themselves.
#if __has_include("kota/codec/json/json.h")
#include "kota/codec/json/json.h"
#endif
2 changes: 1 addition & 1 deletion tests/unit/deco/demos.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include <vector>

#include "kota/deco/deco.h"
#include "kota/zest/macro.h"
#include "kota/zest/zest.h"

namespace kota::deco {
namespace {
Expand Down
47 changes: 47 additions & 0 deletions tests/unit/deco/macro_standalone.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// "kota/deco/macro.h" is what a downstream consuming kotatsu as a module has to
// include: modules cannot export macros, so the Deco* macros must arrive through
// a textual include that drags in no deco declarations of its own. Including it
// as the very first header here keeps that contract honest — if it ever grows a
// dependency on a facade header, this translation unit stops compiling.
#include "kota/deco/macro.h"

#if !defined(DECO_CFG) || !defined(DecoFlag) || !defined(DecoKV) || !defined(DecoInput) || \
!defined(DecoPack) || !defined(DecoMulti) || !defined(DecoComma) || !defined(DecoFlagAlias)
#error "kota/deco/macro.h must define the deco declaration macros on its own"
#endif

#include <string>
#include <vector>

#include "kota/deco/deco.h"
Comment thread
coderabbitai[bot] marked this conversation as resolved.
#include "kota/zest/zest.h"

namespace kota::deco {
namespace {

// Declared with the macros already in scope from the standalone include above,
// which is the order a module consumer ends up with.
struct StandaloneCfg {
DecoFlag(names = {"-v", "--verbose"}; help = "verbose")
verbose;
DecoKV(help = "output")
<std::string> output = "a.out";
};

TEST_SUITE(deco_macro_standalone) {

TEST_CASE(DeclaresOptions) {
auto cmd = cli::command<StandaloneCfg>("app [OPTIONS]");

std::vector<std::string> args = {"--verbose", "--output", "b.out"};
auto res = cmd.invoke(args);
ASSERT_TRUE(res.has_value());

EXPECT_TRUE(res->options.verbose.value());
EXPECT_EQ(res->options.output.value(), "b.out");
}

}; // TEST_SUITE(deco_macro_standalone)

} // namespace
} // namespace kota::deco
2 changes: 1 addition & 1 deletion tests/unit/http/manual_request.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#include "kota/http/http.h"
#include "kota/zest/macro.h"
#include "kota/zest/zest.h"
#include "kota/async/io/loop.h"

TEST_SUITE(http_manual_request) {
Expand Down
33 changes: 33 additions & 0 deletions tests/unit/zest/macro_standalone_tests.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// "kota/zest/macro.h" is what a downstream consuming kotatsu as a module has to
// include: modules cannot export macros, so the test macros must arrive through
// a textual include that drags in no zest declarations of its own. Including it
// as the very first header here keeps that contract honest — if it ever grows a
// dependency on another zest header, this translation unit stops compiling.
#include "kota/zest/macro.h"

#if !defined(TEST_SUITE) || !defined(TEST_CASE) || !defined(EXPECT_TRUE) || !defined(EXPECT_EQ) || \
!defined(ASSERT_TRUE) || !defined(EXPECT_SNAPSHOT) || !defined(STATIC_EXPECT_EQ)
#error "kota/zest/macro.h must define the zest test macros on its own"
#endif

#include "kota/zest/zest.h"

namespace kota::zest {

namespace {

// Written against the macros already in scope from the standalone include above,
// which is the order a module consumer ends up with.
TEST_SUITE(zest_macro_standalone) {

TEST_CASE(macros_usable_without_declaration_headers) {
STATIC_EXPECT_EQ(1 + 1, 2);
ASSERT_TRUE(true);
EXPECT_EQ(std::string("a"), std::string("a"));
}

}; // TEST_SUITE(zest_macro_standalone)

} // namespace

} // namespace kota::zest
1 change: 1 addition & 0 deletions xmake.lua
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ if has_config("deco") then
add_headerfiles(
"include/(kota/deco/option.h)",
"include/(kota/deco/deco.h)",
"include/(kota/deco/macro.h)",
"include/(kota/deco/option/**.h)",
"include/(kota/deco/facade/**.h)"
)
Expand Down
Loading