Prompt file imported from jerarn/jaql (
.github/prompts/new-test.prompt.md). Fill in{{headerPath}}before use. Copyright stays with the author.
Generate a unit test file for the public header {{headerPath}}
(e.g. include/jaql/core/strong_type.hpp).
The test file lives at the mirrored path under tests/unit/:
include/jaql/<module>/<header>.hpp → tests/unit/<module>/test_<header>.cpp
Read the target header now to understand the types, functions, and failure modes before generating any tests.
Also consult docs/testing-strategy.md for the full testing strategy.
Structure to follow
#include "jaql/<module>/<header>.hpp"
#include <gtest/gtest.h>
#include <gmock/gmock.h>
namespace jaql::<module>::test {
// --- Fixture (only if multiple tests share state) ---
class <ClassName>Test : public ::testing::Test {
protected:
// shared setup
};
// --- Success paths ---
TEST_F(<ClassName>Test, <Method>_<Scenario>_<ExpectedOutcome>) {
// Arrange
// Act
// Assert
}
// --- Error paths (one test per Result<T> failure mode) ---
TEST_F(<ClassName>Test, <Method>_<ErrorScenario>_ReturnsError) {
auto result = /* call that should fail */;
ASSERT_FALSE(result.has_value());
EXPECT_EQ(result.error().code(), Code::<ExpectedCode>);
}
// --- Compile-time invariants ---
// Use static_assert to document and enforce type constraints.
static_assert(!std::is_convertible_v<double, MyStrongType>,
"<MyStrongType> must not be implicitly constructible from double");
} // namespace jaql::<module>::test
Rules
- One test per logical behaviour, not one test per function.
- Naming:
TEST(ClassName, MethodName_Scenario_ExpectedOutcome)— three underscore-separated parts. - Every
Result<T>function must have at least one explicit error-path test. - Never use
EXPECT_EQor==to comparedouble. Use:EXPECT_NEAR(actual, expected, abs_tolerance)for known absolute precision.JAQL_EXPECT_NEAR_REL(actual, expected, rel_tolerance)for scale-varying results.
- Use
static_assertto verify compile-time type constraints (implicit conversion, move semantics, triviality, etc.). - Use
ASSERT_TRUE(result.has_value()) << result.error().message();before dereferencing aResult<T>in a test — a failingASSERTstops the test and prints the error. - No
using namespaceat file scope. Use the fulljaql::<module>::prefix or a localusinginside the test body.
Checklist before finishing
- File placed at
tests/unit/<module>/test_<header>.cpp. - All public functions have at least one success-path test.
- All
Result<T>error codes are covered by at least one test. - No bare
==comparisons on floating-point values. -
static_assertused to document compile-time invariants where applicable. - Corresponding
CMakeLists.txtupdated to add the newtest_<header>.cppsource (or a newadd_executableif this is the first test in the module).