Skip to content

Commit

Permalink
Test: add unit testing and some tests
Browse files Browse the repository at this point in the history
* jsonutil stringsplit
* location/section parser inheritance for empty child rules
  • Loading branch information
black-sliver committed May 8, 2024
1 parent aafe839 commit 797bdcd
Show file tree
Hide file tree
Showing 7 changed files with 175 additions and 15 deletions.
7 changes: 4 additions & 3 deletions .github/workflows/binaries.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
- name: Install dependencies
run: |
sudo apt-get update -y -qq
sudo apt-get install coreutils build-essential libsdl2-dev libsdl2-image-dev libsdl2-ttf-dev p7zip
sudo apt-get install coreutils build-essential libsdl2-dev libsdl2-image-dev libsdl2-ttf-dev p7zip libgtest-dev
- uses: actions/checkout@v4
with:
submodules: recursive
Expand All @@ -48,7 +48,7 @@ jobs:
- name: Install dependencies
run: |
sudo apt-get update -y -qq
sudo apt-get install coreutils build-essential libsdl2-dev libsdl2-image-dev libsdl2-ttf-dev p7zip wget
sudo apt-get install coreutils build-essential libsdl2-dev libsdl2-image-dev libsdl2-ttf-dev p7zip wget libgtest-dev
- uses: actions/checkout@v4
with:
submodules: recursive
Expand All @@ -74,7 +74,7 @@ jobs:
steps:
- name: Install dependencies
run: |
brew install coreutils SDL2 sdl2_ttf sdl2_image [email protected] automake libtool autoconf
brew install coreutils SDL2 sdl2_ttf sdl2_image [email protected] automake libtool autoconf googletest
- uses: actions/checkout@v4
with:
submodules: recursive
Expand Down Expand Up @@ -123,6 +123,7 @@ jobs:
mingw64/mingw-w64-x86_64-SDL2_ttf
mingw64/mingw-w64-x86_64-freetype
mingw64/mingw-w64-x86_64-openssl
mingw64/mingw-w64-x86_64-gtest
p7zip
- uses: actions/checkout@v4
with:
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ jobs:
- name: Install dependencies
run: |
sudo apt-get update -y -qq
sudo apt-get install coreutils build-essential libsdl2-dev libsdl2-image-dev libsdl2-ttf-dev p7zip wget
sudo apt-get install coreutils build-essential libsdl2-dev libsdl2-image-dev libsdl2-ttf-dev p7zip wget libgtest-dev
- uses: actions/checkout@v4
with:
submodules: recursive
Expand Down Expand Up @@ -77,7 +77,7 @@ jobs:
- name: Install dependencies
run: |
sudo apt-get update -y -qq
sudo apt-get install coreutils build-essential libsdl2-dev libsdl2-image-dev libsdl2-ttf-dev p7zip wget
sudo apt-get install coreutils build-essential libsdl2-dev libsdl2-image-dev libsdl2-ttf-dev p7zip wget libgtest-dev
- uses: actions/checkout@v4
with:
submodules: recursive
Expand Down Expand Up @@ -106,7 +106,7 @@ jobs:
steps:
- name: Install dependencies
run: |
brew install coreutils SDL2 sdl2_ttf sdl2_image [email protected] automake libtool autoconf
brew install coreutils SDL2 sdl2_ttf sdl2_image [email protected] automake libtool autoconf googletest
- uses: actions/checkout@v4
with:
submodules: recursive
Expand Down
5 changes: 3 additions & 2 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,11 @@ jobs:
if: ${{ startsWith(matrix.os, 'ubuntu') }}
run: |
sudo apt-get update -y -qq
sudo apt-get install coreutils build-essential libsdl2-dev libsdl2-image-dev libsdl2-ttf-dev
sudo apt-get install coreutils build-essential libsdl2-dev libsdl2-image-dev libsdl2-ttf-dev libgtest-dev
- name: Install dependencies (brew)
if: ${{ startsWith(matrix.os, 'macos') }}
run: |
brew install coreutils SDL2 sdl2_ttf sdl2_image [email protected]
brew install coreutils SDL2 sdl2_ttf sdl2_image [email protected] googletest
- name: Install dependencies (msys2)
if: ${{ startsWith(matrix.os, 'windows') }}
uses: msys2/setup-msys2@v2
Expand All @@ -68,6 +68,7 @@ jobs:
mingw64/mingw-w64-x86_64-SDL2_ttf
mingw64/mingw-w64-x86_64-freetype
mingw64/mingw-w64-x86_64-openssl
mingw64/mingw-w64-x86_64-gtest
p7zip
- uses: actions/checkout@v4
with:
Expand Down
43 changes: 36 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# for now we use SDL2_image GIF support only
CONF ?= RELEASE # make CONF=DEBUG for debug, CONF=DIST for .zip
SRC_DIR = src
TEST_DIR = test
LIB_DIR = lib
SRC = $(wildcard $(SRC_DIR)/*.cpp) \
$(wildcard $(SRC_DIR)/uilib/*.cpp) \
Expand All @@ -28,6 +29,8 @@ HDR = $(wildcard $(SRC_DIR)/*.h) \
$(wildcard $(SRC_DIR)/http/*.h) \
$(wildcard $(SRC_DIR)/packmanager/*.h) \
$(wildcard $(LIB_DIR)/tinyfiledialogs/*)
TEST_SRC = $(filter-out $(SRC_DIR)/main.cpp,$(SRC)) \
$(wildcard $(TEST_DIR)/*/*.cpp)
INCLUDE_DIRS = -Ilib -Ilib/lua -Ilib/asio/include -DASIO_STANDALONE -Ilib/miniz -Ilib/json/include -Ilib/valijson/include -Ilib/tinyfiledialogs -Ilib/wswrap/include #-Ilib/gifdec
WIN32_INCLUDE_DIRS = -Iwin32-lib/i686/include
WIN32_LIB_DIRS = -L./win32-lib/i686/bin -L./win32-lib/i686/lib
Expand Down Expand Up @@ -74,13 +77,17 @@ UNAME = $(shell uname -sm | tr -s ' ' '-' | tr A-Z a-z )
DIST_DIR ?= dist
BUILD_DIR ?= build
EXE_NAME = poptracker
TEST_EXE_NAME = poptracker-test
NIX_BUILD_DIR = $(BUILD_DIR)/$(UNAME)
WIN32_BUILD_DIR = $(BUILD_DIR)/win32
WIN64_BUILD_DIR = $(BUILD_DIR)/win64
WASM_BUILD_DIR = $(BUILD_DIR)/wasm
WIN32_EXE = $(WIN32_BUILD_DIR)/$(EXE_NAME).exe
WIN32_TEST_EXE = $(WIN32_BUILD_DIR)/$(TEST_EXE_NAME).exe
WIN64_EXE = $(WIN64_BUILD_DIR)/$(EXE_NAME).exe
WIN64_TEST_EXE = $(WIN64_BUILD_DIR)/$(TEST_EXE_NAME).exe
NIX_EXE = $(NIX_BUILD_DIR)/$(EXE_NAME)
NIX_TEST_EXE = $(NIX_BUILD_DIR)/$(TEST_EXE_NAME)
HTML = $(WASM_BUILD_DIR)/$(EXE_NAME).html

# dist/zip
Expand All @@ -99,11 +106,14 @@ endif

# fragments
NIX_OBJ := $(patsubst %.cpp, $(NIX_BUILD_DIR)/%.o, $(SRC))
NIX_OBJ_DIRS := $(sort $(dir $(NIX_OBJ)))
NIX_TEST_OBJ := $(patsubst %.cpp, $(NIX_BUILD_DIR)/%.o, $(TEST_SRC))
NIX_OBJ_DIRS := $(sort $(dir $(NIX_OBJ)) $(dir $(NIX_TEST_OBJ)))
WIN32_OBJ := $(patsubst %.cpp, $(WIN32_BUILD_DIR)/%.o, $(SRC))
WIN32_OBJ_DIRS := $(sort $(dir $(WIN32_OBJ)))
WIN32_TEST_OBJ := $(patsubst %.cpp, $(WIN32_BUILD_DIR)/%.o, $(TEST_SRC))
WIN32_OBJ_DIRS := $(sort $(dir $(WIN32_OBJ)) $(dir $(WIN32_TEST_OBJ)))
WIN64_OBJ := $(patsubst %.cpp, $(WIN64_BUILD_DIR)/%.o, $(SRC))
WIN64_OBJ_DIRS := $(sort $(dir $(WIN64_OBJ)))
WIN64_TEST_OBJ := $(patsubst %.cpp, $(WIN64_BUILD_DIR)/%.o, $(TEST_SRC))
WIN64_OBJ_DIRS := $(sort $(dir $(WIN64_OBJ)) $(dir $(WIN64_TEST_OBJ)))

# tools
CC = gcc # TODO: use ?=
Expand Down Expand Up @@ -179,6 +189,7 @@ endif
# default target: "native"
ifdef IS_WIN32
EXE = $(WIN32_EXE)
TEST_EXE = $(WIN32_TEST_EXE)
WIN32CC = $(CC)
WIN32CPP = $(CPP)
WIN32AR = $(AR)
Expand All @@ -193,6 +204,7 @@ ifdef IS_WIN32
endif
else ifdef IS_WIN64
EXE = $(WIN64_EXE)
TEST_EXE = $(WIN64_TEST_EXE)
WIN64CC = $(CC)
WIN64CPP = $(CPP)
WIN64AR = $(AR)
Expand All @@ -207,6 +219,7 @@ else ifdef IS_WIN64
endif
else ifdef IS_OSX
EXE = $(NIX_EXE)
TEST_EXE = $(NIX_TEST_EXE)
ifeq ($(CONF), DIST) # TODO dmg?
native: $(OSX_APP) $(OSX_ZIP) test_osx_app
else
Expand All @@ -216,6 +229,7 @@ else
WIN32_LIBS += -lbrotlidec-static -lbrotlicommon-static # brotli is a mess
WIN64_LIBS += -lbrotlidec-static -lbrotlicommon-static
EXE = $(NIX_EXE)
TEST_EXE = $(NIX_TEST_EXE)
ifeq ($(CONF), DIST) # TODO deb?
native: $(NIX_XZ)
else
Expand All @@ -232,6 +246,8 @@ cross: $(WIN32_ZIP) $(WIN64_ZIP)
else
cross: $(WIN32_EXE) $(WIN64_EXE)
endif
cross-test: $(WIN32_TEST_EXE) $(WIN64_TEST_EXE)
# TODO: run tests with wine

# Project Targets
$(HTML): $(SRC) $(WASM_BUILD_DIR)/liblua.a $(HDR) | $(WASM_BUILD_DIR)
Expand All @@ -243,19 +259,28 @@ $(HTML): $(SRC) $(WASM_BUILD_DIR)/liblua.a $(HDR) | $(WASM_BUILD_DIR)
$(NIX_EXE): $(NIX_OBJ) $(NIX_BUILD_DIR)/liblua.a $(HDR) | $(NIX_BUILD_DIR)
$(CPP) -std=c++1z $(NIX_OBJ) $(NIX_BUILD_DIR)/liblua.a -ldl $(NIX_LD_FLAGS) `sdl2-config --libs` $(NIX_LIBS) -o $@

$(NIX_TEST_EXE): $(NIX_TEST_OBJ) $(NIX_BUILD_DIR)/liblua.a $(HDR) | $(NIX_BUILD_DIR)
$(CPP) -std=c++1z $(NIX_TEST_OBJ) -l gtest -l gtest_main $(NIX_BUILD_DIR)/liblua.a -ldl $(NIX_LD_FLAGS) `sdl2-config --libs` $(NIX_LIBS) -o $@

$(WIN32_EXE): $(WIN32_OBJ) $(WIN32_BUILD_DIR)/app.res $(WIN32_BUILD_DIR)/liblua.a $(HDR) | $(WIN32_BUILD_DIR)
# FIXME: static 32bit exe does not work for some reason
$(WIN32CPP) -o $@ -std=c++17 -static -Wl,-Bstatic $(WIN32_OBJ) $(WIN32_BUILD_DIR)/app.res $(WIN32_BUILD_DIR)/liblua.a $(WIN32_LIB_DIRS) $(WIN32_LD_FLAGS) $(WIN32_LIBS)
ifneq ($(CONF), DEBUG)
$(WIN32STRIP) $@
endif

$(WIN32_TEST_EXE): $(WIN32_TEST_OBJ) $(WIN32_BUILD_DIR)/app.res $(WIN32_BUILD_DIR)/liblua.a $(HDR) | $(WIN32_BUILD_DIR)
$(WIN32CPP) -o $@ -std=c++17 $(WIN32_TEST_OBJ) -l gtest -l gtest_main $(WIN32_BUILD_DIR)/liblua.a $(WIN32_LIB_DIRS) $(WIN32_LD_FLAGS) $(WIN32_LIBS)

$(WIN64_EXE): $(WIN64_OBJ) $(WIN64_BUILD_DIR)/app.res $(WIN64_BUILD_DIR)/liblua.a $(HDR) | $(WIN64_BUILD_DIR)
$(WIN64CPP) -o $@ -std=c++17 -static -Wl,-Bstatic $(WIN64_OBJ) $(WIN64_BUILD_DIR)/app.res $(WIN64_BUILD_DIR)/liblua.a $(WIN64_LIB_DIRS) $(WIN64_LD_FLAGS) $(WIN64_LIBS)
ifneq ($(CONF), DEBUG)
$(WIN64STRIP) $@
endif

$(WIN64_TEST_EXE): $(WIN64_TEST_OBJ) $(WIN64_BUILD_DIR)/app.res $(WIN64_BUILD_DIR)/liblua.a $(HDR) | $(WIN64_BUILD_DIR)
$(WIN64CPP) -o $@ -std=c++17 $(WIN64_TEST_OBJ) -l gtest -l gtest_main $(WIN64_BUILD_DIR)/liblua.a $(WIN64_LIB_DIRS) $(WIN64_LD_FLAGS) $(WIN64_LIBS)

$(WIN32_ZIP): $(WIN32_EXE) | $(DIST_DIR)
$(WIN64_ZIP): $(WIN64_EXE) | $(DIST_DIR)
$(WIN32_ZIP) $(WIN64_ZIP):
Expand Down Expand Up @@ -369,12 +394,16 @@ $(WIN64_BUILD_DIR)/%.o: %.c* $(HDR) | $(WIN64_OBJ_DIRS)
# Avoid detection/auto-cleanup of intermediates
.OBJ_DIRS: $(NIX_OBJ_DIRS) $(WIN32_OBJ_DIRS) $(WIN64_OBJ_DIRS)

test: $(EXE)
# TODO: implement and run actual tests
@echo "Testing $(EXE)"
test: $(EXE) ${TEST_EXE}
@echo "Running $(TEST_EXE)"
@$(TEST_EXE)
@echo "Checking $(EXE)"
@echo -n "Size: "
@du -h $(EXE) | cut -f -1
@echo -n "Version: "
@timeout 5 $(EXE) --version
@timeout 9 $(EXE) --list-packs
@echo "HTTP Test ..."
@timeout 9 $(EXE) --list-packs > /dev/null

clean:
(cd lib/lua && make -f makefile clean)
Expand Down
38 changes: 38 additions & 0 deletions test/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Automated PopTracker Tests

PRs to add tests are welcome.

We have 3 types of tests in mind:
- **Unit tests:** test individual code fragments using googletest, see [How to add Unit Tests](#how-to-add-unit-tests).
- **Render tests:** load packs and verify render output using `SDL_VIDEODRIVER=dummy` and a screenshot
- **High level tests:** stuff that should be tested end-to-end may be hard to do with googletest because we'd need to
mock all of PopTracker. Those will probably use an external test script that waits for e.g. a specific print from Lua.

Tests should be run on both 64bit and 32bit to see if any integer size assumptions are wrong.

Tests that should be done:
- Render tests for all example packs
- High level tests for AP
- 64bit onItem
- 64bit onLocationScout
- 64bit onLocationCheck
- 64bit CheckedLocations
- 64bit MissingLocations
- 64bit data storage
- unicode data storage
- 64bit slot data
- unicode slot data

## How to add Unit Tests

We compile `test/*/*.cpp` together with googletest and `src/**` into a test binary. To add tests, simply pick a folder
and add a `test_*.cpp` file that uses googletest API.

## How to run Unit Tests

* install `googltest`, sometimes called `gtest` or `libgtest-dev`, via pacman, apt, brew, etc. or from source
* `make test`

## Other Tests

We have not decided on a solution for non unit tests yet.
51 changes: 51 additions & 0 deletions test/core/test_locations_parser.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#include <gtest/gtest.h>
#include <nlohmann/json.hpp>
#include "../../src/core/location.h"


using namespace std;
using nlohmann::json;


TEST(LocationsParserTest, LocationRulesInheritAndEmpty) {
// TODO: validate indirectly by checcking accessibility/visibilty via Tracker
const list<list<string>> parentAccessRules = {{"a"}};
const list<list<string>> parentVisibilityRules = {{"b"}};
json childNode = R"(
{
"name": "child",
"access_rules": [],
"visibility_rules": []
}
)"_json;

auto location = Location::FromJSON(childNode, {}, parentAccessRules, parentVisibilityRules).front();
EXPECT_EQ(location.getAccessRules(),
parentAccessRules);
EXPECT_EQ(location.getVisibilityRules(),
parentVisibilityRules);
}

TEST(LocationsParserTest, SectionRulesInheritAndEmpty) {
// TODO: validate indirectly by checcking accessibility/visibilty via Tracker
json locationNode = R"(
{
"name": "location",
"access_rules": [["a"]],
"visibility_rules": [["b"]],
"sections": [
{
"name": "section",
"access_rules": [],
"visibility_rules": []
}
]
}
)"_json;

auto section = Location::FromJSON(locationNode, {}, {}, {}).front().getSections().front();
EXPECT_EQ(section.getAccessRules(),
list<list<string>>({{"a"}}));
EXPECT_EQ(section.getVisibilityRules(),
list<list<string>>({{"b"}}));
}
40 changes: 40 additions & 0 deletions test/jsonutil/test_commasplit.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#include <gtest/gtest.h>
#include <list>
#include <string>
#include "../../src/core/jsonutil.h"


using namespace std;


// Living standard :TM:
// only trailing empty fields should be dropped

TEST(CommaSplitTest, Empty) {
EXPECT_EQ(commasplit(""),
list<string>({}));
}

TEST(CommaSplitTest, TrailingComma) {
// Trailing empty values should be dropped
EXPECT_EQ(commasplit("a,"),
list<string>({"a"}));
}

TEST(CommaSplitTest, LeadingEmpty) {
// Leading empty values should be kept
EXPECT_EQ(commasplit(",b"),
list<string>({"", "b"}));
}

TEST(CommaSplitTest, MiddleEmpty) {
// Empty values in the middle should be kept
EXPECT_EQ(commasplit("a,,b"),
list<string>({"a", "", "b"}));
}

TEST(CommaSplitTest, TrailingWhitespace) {
// If trailing whitespace results in trailing comma, it should behave the same as TrailingComma
EXPECT_EQ(commasplit("a, "),
list<string>({"a"}));
}

0 comments on commit 797bdcd

Please sign in to comment.