From bf9b23b5478b94d25c048d5fe26a0a9c6f7043d7 Mon Sep 17 00:00:00 2001 From: Perry Gibson Date: Wed, 29 Oct 2025 13:57:05 +0000 Subject: [PATCH 1/5] feat: add basic gtest --- .gitignore | 9 +++++++ .gitmodules | 3 +++ Makefile | 40 +++++++++++++++++++++++++++++- tests/README.md | 56 ++++++++++++++++++++++++++++++++++++++++++ tests/test_basic.cpp | 11 +++++++++ third_party/googletest | 1 + 6 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 tests/README.md create mode 100644 tests/test_basic.cpp create mode 160000 third_party/googletest diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..58750c4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +Makefile.inc +dstar/Makefile.inc +**/*.o +**/*.a +starev +dstar/Normalisation +dstar/SeBa +**/*.data +build/ diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..5a4e85a --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "third_party/googletest"] + path = third_party/googletest + url = https://github.com/google/googletest.git diff --git a/Makefile b/Makefile index 290352b..232a3f2 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ DIRS = node std sstar dstar rdc all: lib $(EXE) -test: +test-compiler: echo $(CXX) echo `which $(CXX)` @@ -22,3 +22,41 @@ lib: Makefile.inc clean: Makefile.inc @for d in $(DIRS) ; do echo '\nmake' $@ in $$d; make -C $$d $@ ; done /bin/rm -f *~ $(EXE) Makefile.inc + +# --- Test support --- +CXXFLAGS += -std=c++23 +TESTDIR = tests +BUILDDIR = build +TESTBIN = $(BUILDDIR)/run_tests +TESTSRC = $(wildcard $(TESTDIR)/*.cpp) +TESTOBJ = $(patsubst $(TESTDIR)/%.cpp,$(BUILDDIR)/%.o,$(TESTSRC)) + +GTEST_DIR = third_party/googletest/googletest +GTEST_SRC = $(GTEST_DIR)/src/gtest-all.cc +GTEST_OBJ = $(BUILDDIR)/gtest-all.o +GTEST_INC = -I$(GTEST_DIR)/include -I$(GTEST_DIR) + +# Ensure build directory exists +$(BUILDDIR): + mkdir -p $(BUILDDIR) + +# Compile gtest from source +$(GTEST_OBJ): $(GTEST_SRC) | $(BUILDDIR) + $(CXX) $(CXXFLAGS) $(GTEST_INC) -c $< -o $@ + +# Compile test sources +$(BUILDDIR)/%.o: $(TESTDIR)/%.cpp | $(BUILDDIR) + $(CXX) $(CXXFLAGS) $(GTEST_INC) -I./include -c $< -o $@ + +# Link final test binary +$(TESTBIN): $(TESTOBJ) $(GTEST_OBJ) + $(CXX) $(CXXFLAGS) $(GTEST_INC) -I./include $^ $(LDLIBS) -lpthread -o $@ + +# Run tests +test: $(TESTBIN) + @echo "Running unit tests..." + @./$(TESTBIN) + +# Clean test artifacts +clean-tests: + /bin/rm -rf $(BUILDDIR) diff --git a/tests/README.md b/tests/README.md new file mode 100644 index 0000000..910bf50 --- /dev/null +++ b/tests/README.md @@ -0,0 +1,56 @@ +# Tests + +## Overview + +Unit tests live in the `tests/` directory. +They use **GoogleTest (gtest)**, a lightweight C++ testing framework. +Tests are built and executed by running: + +``` sh +make test +``` + + +This compiles all test files (`tests/*.cpp`), links them against project libraries and gtest, and runs them automatically. +Passing tests will print `[ PASSED ]` lines in the terminal. + +## Getting GoogleTest Source + +This project vendors GoogleTest to make the test build self-contained. +Ensure the submodules are cloned so that the GoogleTest code is included: + +```sh +git submodule update --init --recursive +``` + +This will populate `third_party/googletest/`, which contains the GoogleTest source built automatically when running `make test`. + +## Cleaning Up + +To remove test binaries: + +``` sh +make clean-tests +``` + +## Writing a Test + +Each test file is a small C++ program that includes both gtest and your project +headers. + +You want to define test cases using the `TEST` macro provided by gtest, and +ensure that your functions behave as expected using assertions like `EXPECT_EQ`, `ASSERT_TRUE`, etc. + +Example: + +``` cpp +#include "util_math.h +#include + +TEST(Math, Add) { EXPECT_EQ(add(2, 2), 4); } + +int main(int argc, char **argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} +``` diff --git a/tests/test_basic.cpp b/tests/test_basic.cpp new file mode 100644 index 0000000..dc6f143 --- /dev/null +++ b/tests/test_basic.cpp @@ -0,0 +1,11 @@ +#include "util_math.h" +#include + +int add(int a, int b) { return a + b; } + +TEST(Math, Add) { EXPECT_EQ(add(2, 2), 4); } + +int main(int argc, char **argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/third_party/googletest b/third_party/googletest new file mode 160000 index 0000000..b2b9072 --- /dev/null +++ b/third_party/googletest @@ -0,0 +1 @@ +Subproject commit b2b9072ecbe874f5937054653ef8f2731eb0f010 From 3ff5d8317ee12cdfc9c3c579fadb3e5ac53314d3 Mon Sep 17 00:00:00 2001 From: Perry Gibson Date: Wed, 29 Oct 2025 14:08:21 +0000 Subject: [PATCH 2/5] feat: add test for util_math --- Makefile | 23 +++++++++++++++-------- tests/README.md | 5 ----- tests/test_basic.cpp | 5 ----- 3 files changed, 15 insertions(+), 18 deletions(-) diff --git a/Makefile b/Makefile index 232a3f2..a9abfd5 100644 --- a/Makefile +++ b/Makefile @@ -24,7 +24,7 @@ clean: Makefile.inc /bin/rm -f *~ $(EXE) Makefile.inc # --- Test support --- -CXXFLAGS += -std=c++23 +TEST_CXXFLAGS = $(CXXFLAGS) -std=c++23 TESTDIR = tests BUILDDIR = build TESTBIN = $(BUILDDIR)/run_tests @@ -35,28 +35,35 @@ GTEST_DIR = third_party/googletest/googletest GTEST_SRC = $(GTEST_DIR)/src/gtest-all.cc GTEST_OBJ = $(BUILDDIR)/gtest-all.o GTEST_INC = -I$(GTEST_DIR)/include -I$(GTEST_DIR) +GTEST_MAIN_SRC = $(GTEST_DIR)/src/gtest_main.cc +GTEST_MAIN_OBJ = $(BUILDDIR)/gtest_main.o -# Ensure build directory exists +# Create build directory $(BUILDDIR): mkdir -p $(BUILDDIR) -# Compile gtest from source +# Compile Google Test source $(GTEST_OBJ): $(GTEST_SRC) | $(BUILDDIR) - $(CXX) $(CXXFLAGS) $(GTEST_INC) -c $< -o $@ + $(CXX) $(TEST_CXXFLAGS) $(GTEST_INC) -c $< -o $@ # Compile test sources $(BUILDDIR)/%.o: $(TESTDIR)/%.cpp | $(BUILDDIR) - $(CXX) $(CXXFLAGS) $(GTEST_INC) -I./include -c $< -o $@ + $(CXX) $(TEST_CXXFLAGS) $(GTEST_INC) -I./include -c $< -o $@ + +# Compile Google Test main +$(GTEST_MAIN_OBJ): $(GTEST_MAIN_SRC) | $(BUILDDIR) + $(CXX) $(TEST_CXXFLAGS) $(GTEST_INC) -c $< -o $@ # Link final test binary -$(TESTBIN): $(TESTOBJ) $(GTEST_OBJ) - $(CXX) $(CXXFLAGS) $(GTEST_INC) -I./include $^ $(LDLIBS) -lpthread -o $@ +$(TESTBIN): $(TESTOBJ) $(GTEST_OBJ) $(GTEST_MAIN_OBJ) + $(CXX) $(TEST_CXXFLAGS) $(GTEST_INC) -I./include $^ \ + $(LDLIBS) -lpthread -o $@ # Run tests test: $(TESTBIN) @echo "Running unit tests..." @./$(TESTBIN) -# Clean test artifacts +# Optional cleanup clean-tests: /bin/rm -rf $(BUILDDIR) diff --git a/tests/README.md b/tests/README.md index 910bf50..95dde82 100644 --- a/tests/README.md +++ b/tests/README.md @@ -48,9 +48,4 @@ Example: #include TEST(Math, Add) { EXPECT_EQ(add(2, 2), 4); } - -int main(int argc, char **argv) { - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} ``` diff --git a/tests/test_basic.cpp b/tests/test_basic.cpp index dc6f143..96046f9 100644 --- a/tests/test_basic.cpp +++ b/tests/test_basic.cpp @@ -4,8 +4,3 @@ int add(int a, int b) { return a + b; } TEST(Math, Add) { EXPECT_EQ(add(2, 2), 4); } - -int main(int argc, char **argv) { - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} From 18c34e8524006474171ccfbf8ad3ed1abd305872 Mon Sep 17 00:00:00 2001 From: Perry Gibson Date: Wed, 29 Oct 2025 14:14:55 +0000 Subject: [PATCH 3/5] feat: add support to run specific tests --- Makefile | 5 +++++ tests/README.md | 29 ++++++++++++++++++++++++++++- tests/test_basic.cpp | 3 +-- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index a9abfd5..8e76218 100644 --- a/Makefile +++ b/Makefile @@ -64,6 +64,11 @@ test: $(TESTBIN) @echo "Running unit tests..." @./$(TESTBIN) +# Run specific tests matching a pattern +test_%: $(TESTBIN) + @echo "Running tests matching '$*'..." + @./$(TESTBIN) --gtest_filter=*${*}* + # Optional cleanup clean-tests: /bin/rm -rf $(BUILDDIR) diff --git a/tests/README.md b/tests/README.md index 95dde82..63b0e36 100644 --- a/tests/README.md +++ b/tests/README.md @@ -47,5 +47,32 @@ Example: #include "util_math.h #include -TEST(Math, Add) { EXPECT_EQ(add(2, 2), 4); } +TEST(Basic, Add) { EXPECT_EQ(add(2, 2), 4); } +``` + +## Running Tests + +Run all tests: + +``` sh +make test +``` + +Run a specific test suite or test case: + +``` sh +make test_[pattern] +``` + +E.g., run all tests marked `UtilMath`, run: + +``` sh +make test_UtilMath + +``` + +Run a specific test case within a suite: + +``` sh +make test_UtilMath.Twiddles ``` diff --git a/tests/test_basic.cpp b/tests/test_basic.cpp index 96046f9..f753908 100644 --- a/tests/test_basic.cpp +++ b/tests/test_basic.cpp @@ -1,6 +1,5 @@ -#include "util_math.h" #include int add(int a, int b) { return a + b; } -TEST(Math, Add) { EXPECT_EQ(add(2, 2), 4); } +TEST(Basic, Add) { EXPECT_EQ(add(2, 2), 4); } From bb97ebedab157e89fa0d78932bea6197e23dade5 Mon Sep 17 00:00:00 2001 From: Perry Gibson Date: Wed, 29 Oct 2025 14:17:48 +0000 Subject: [PATCH 4/5] ci: add testing to workflow --- .github/workflows/build.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 03cb235..bdd92c3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,4 +1,4 @@ -name: Build SeBa +name: Build and test SeBa on: push: @@ -19,3 +19,7 @@ jobs: run: | cd dstar make + - name: Build and run unit tests + run: | + git submodule update --init --recursive + make test \ No newline at end of file From ca96a7849db214347393f8d709f4ee41b7866cc3 Mon Sep 17 00:00:00 2001 From: Perry Gibson Date: Wed, 29 Oct 2025 14:19:29 +0000 Subject: [PATCH 5/5] fix: forgot to commit util_math test --- tests/test_util_math.cpp | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 tests/test_util_math.cpp diff --git a/tests/test_util_math.cpp b/tests/test_util_math.cpp new file mode 100644 index 0000000..f640961 --- /dev/null +++ b/tests/test_util_math.cpp @@ -0,0 +1,30 @@ +#include "util_math.h" +#include + +// basic numerical tolerance for comparisons +static constexpr real EPS = 1e-12; + +TEST(UtilMath, Twiddles) { + EXPECT_TRUE(twiddles(1.0, 1.0 + 1e-13, EPS)); + EXPECT_FALSE(twiddles(1.0, 1.1, EPS)); +} + +TEST(UtilMath, Sign) { + EXPECT_EQ(sign(3.5), 1); + EXPECT_EQ(sign(-2.1), -1); + EXPECT_EQ(sign(0.0), 0); +} + +TEST(UtilMath, AdjustNumberToPower) { + // result should not exceed max_step_size + real result = adjust_number_to_power(5.5, 4.0); + EXPECT_LE(result, 4.0); +} + +TEST(UtilMath, AsinhAcoshConsistency) { + real x = 1.5; + real s = sinh(x); + real c = cosh(x); + EXPECT_NEAR(asinh(s), x, 1e-12); + EXPECT_NEAR(acosh(c), x, 1e-12); +}