mirror of
https://github.com/sebastiandine/Card-Collection-Manager-3.git
synced 2026-08-28 23:01:09 +00:00
55ace147bc
* initial development * pipeline * pipeline * pipeline * pipeline * pipeline * pipeline * pipeline * pipeline * pipeline * pipeline * pipeline * pipeline * pipeline * pipeline * ci/cd * ci/cd * ci/cd * ci/cd * ci/cd * ci/cd * ci/cd * pokemon * pokemon * pokemon * pokemon * pokemon * pokemon * improvements * improvements * ci/cd * ci/cd * improvements * improvements * improvements * improvements * improvements * improvements * improvements * improvements * improvements --------- Co-authored-by: sdine <sdine@sdine.com>
5.6 KiB
5.6 KiB
tests/AGENTS.md
ccm_core_tests — doctest unit tests for ccm_core. Hermetic, fast, no real network or disk. Read the root AGENTS.md first.
File pointers
main.cpp— doctest entry point withDOCTEST_CONFIG_IMPLEMENT_WITH_MAIN. Do not put tests here.fakes/InMemoryFileSystem.{hpp,cpp}—IFileSystemimplementation backed bystd::map. Normalizes paths vialexically_normal().generic_string()(always/separators).fs_names_tests.cpp—formatTextForFs+parseIndexFromFilename. Both are compatibility ports of the original Rust path rules.domain_json_tests.cpp— JSON round-trip tests for every domain type. Update this file whenever a domain type changes.image_service_tests.cpp—ImageService(uses inlineRecordingImageStorefake).collection_service_tests.cpp—CollectionService<MagicCard>(uses inlineInMemoryRepo+StubImageStore).config_service_tests.cpp—ConfigServiceagainstInMemoryFileSystem.json_collection_repository_tests.cpp,json_set_repository_tests.cpp— repository round-trips againstInMemoryFileSystem.set_service_tests.cpp—SetServicewithFakeSetSource+InMemSetRepo.magic_set_source_tests.cpp—MagicSetSource::parseResponse(Scryfall mapping). DrivesfetchAllviaFixedHttpClientfake.magic_card_preview_source_tests.cpp—MagicCardPreviewSource::buildSearchUrlURL-encoding rules +parseResponse(data[0].image_uris.normal). DrivesfetchImageUrlviaFixedHttpClient.card_preview_service_tests.cpp—CardPreviewServiceregistry/orchestration throughregisterModule(IGameModule&)with an inlineFakeGameModulereturning aFakeSource : ICardPreviewSourceand aFixedHttpClient. Pin-down for the "module returning nullptr is silently skipped" rule.pokemon_set_source_tests.cpp—PokemonSetSource::parseResponse(api.pokemontcg.io/v2/sets shape —data[].id,name,releaseDatealready inYYYY/MM/DD) + sort-by-release-date stability. DrivesfetchAllviaFixedHttpClientand asserts the public endpoint URL.pokemon_card_preview_source_tests.cpp—PokemonCardPreviewSource::buildSearchUrl(percent-encodedname:/set.id:/number:triple, with collector-number4/102->4normalization) +parseResponse(data[0].images.largewithimages.smallfallback). DrivesfetchImageUrlviaFixedHttpClient.card_sorter_tests.cpp—sortMagicCards/sortPokemonCardsper-column behavior. Pin-down tests forbyField-equivalent semantics: case-insensitive strings, chronological set sort viaset.releaseDate, numericamount,false < trueboolean order, stable composition (sort by name then by set keeps inner-name order). Update this file whenever you add a new column / sort key.card_filter_tests.cpp—matchesMagicFilter/matchesPokemonFilterrow-matcher behavior. Pin-down tests forapplyFilter-equivalent semantics: case-insensitive substring match acrosstableFieldsvalueKeys (name, set.name, language, condition, amount-as-string, note; Pokemon addssetNo), boolean flag columns (foil/signed/altered/holo/firstEdition) intentionally excluded, empty filter matches everything. Update this file whenever you add a new searchable column.CMakeLists.txt— explicit list of every.cpp(no glob).
Conventions
- Framework: doctest. Each test file
#include <doctest/doctest.h>and usesTEST_SUITE("...")+TEST_CASE("..."). Asserts:CHECK,REQUIRE,CHECK_THROWS. - No real I/O. Everything goes through
ccm::testing::InMemoryFileSystemor an inline test-local fake. If you need HTTP, write a fakeIHttpClientlikeFixedHttpClientinmagic_set_source_tests.cpp. - Fakes for narrow concerns stay in the test file as anonymous-namespace classes (e.g.
RecordingImageStore,InMemoryRepo). Promote a fake totests/fakes/only when more than one test file needs it. - Path strings in expectations must use forward slashes. The fake normalizes everything to
generic_string(). Do not hard-code\separators. - Test names describe behavior, not implementation. Prefer "missing file is created with defaults" over "test_init_no_file".
- Add a
.cppto theadd_executablecall intests/CMakeLists.txt. No glob.
Required follow-ups
- After modifying any domain type field or alias you must extend the matching test in
domain_json_tests.cpp. - After modifying
formatTextForFsorparseIndexFromFilenameyou must extendfs_names_tests.cpp— these are byte-compatibility shims with the original Rust code. - After adding a new service in
core/you must add a corresponding<name>_service_tests.cppwith at least the happy-path and one error-path test. - After adding a new game's set source / card preview source you must add
tests/<name>_set_source_tests.cppand (if applicable)tests/<name>_card_preview_source_tests.cppmirroring the Magic and Pokemon files. Add them totests/CMakeLists.txt.
Commands
- Configure with tests on:
cmake -S . -B build -DCCM_BUILD_TESTS=ON - Build the suite:
cmake --build build --target ccm_core_tests - Run all tests:
ctest --test-dir build --output-on-failure - Run a single test by name pattern:
./build/bin/ccm_core_tests --test-case="*nextImageIndex*" - Run a single suite:
./build/bin/ccm_core_tests --test-suite="MagicSetSource::parseResponse"
Anti-patterns
- Don't depend on
ccm_ui_wxfrom tests. UI is out of scope here. - Don't rely on file paths existing on the host (no
/tmp, noC:\Users\...). UseInMemoryFileSystem. - Don't add tests that require network access. The Pokemon stub test checks the message, not a real API call.