Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
9dfb113
Merge pull request #33 from ASWSoftware/asw/release-1.4.0
AnthonySWest Oct 15, 2026
a182646
Bump version to 1.5.0-dev.1
AnthonySWest Oct 15, 2026
41539b1
Coding standards
AnthonySWest Oct 15, 2026
5e23bac
Add app bits and build OS to banner log in TTestHandler::Initialize()
AnthonySWest Oct 15, 2026
fedf589
Bump version to 1.5.0-dev.2
AnthonySWest Oct 15, 2026
d988aab
Update .gitignore to ignore plans folder
AnthonySWest Oct 15, 2026
2d161fa
Coding standards
AnthonySWest Oct 26, 2026
cdca25f
Bump version to 1.5.0-dev.3
AnthonySWest Oct 26, 2026
462069c
Move toolkit-neutral GUI units to gui/src
AnthonySWest Oct 26, 2026
f025ff3
Move the GUI test selection to gui/src
AnthonySWest Oct 26, 2026
65dc9b7
Read and write the GUI layout without the VCL
AnthonySWest Oct 26, 2026
1e90264
Share the GUI test tree logic
AnthonySWest Oct 26, 2026
361a648
Share the GUI command enable rules
AnthonySWest Oct 26, 2026
7aa73fe
Fix the VCL GUI progress bar after a failure
AnthonySWest Oct 26, 2026
e44565d
Fix doubled shortcuts in the VCL GUI's tooltips
AnthonySWest Oct 26, 2026
8ad1555
Share the GUI's displayed text and run summary
AnthonySWest Oct 26, 2026
84a6fbe
Add a minimal Win32 GUI runner with CMake and RAD Studio projects
AnthonySWest Oct 27, 2026
c608ca4
Add the Win32 GUI's system access unit
AnthonySWest Oct 27, 2026
86ef15d
Show the Win32 GUI's command-line help and errors in a text dialog
AnthonySWest Oct 27, 2026
c9812ba
Add the Win32 GUI's main window layout, menu and hot keys
AnthonySWest Oct 27, 2026
cba282c
Implement test tree, filter and selection
AnthonySWest Oct 27, 2026
c541f00
Build the GUI's test tree once at start when --filter is present
AnthonySWest Oct 27, 2026
5227251
Implement run tests, with results, progress and log
AnthonySWest Oct 28, 2026
3f42b93
Implement JUnit report export, and keep the focus usable through a run
AnthonySWest Oct 28, 2026
45456d5
Add the Win32 GUI's Shuffle Seed dialog and shuffle check mark
AnthonySWest Oct 28, 2026
ea487df
Give each Win32 GUI System test its own scratch folder
AnthonySWest Oct 28, 2026
27deb59
Save and restore the Win32 GUI's layout and test selection
AnthonySWest Oct 28, 2026
c15013a
Turn off MinGW wildcard expansion in the Win32 GUI
AnthonySWest Oct 28, 2026
fb842c9
Give the MinGW Win32 GUI the padded window frame
AnthonySWest Oct 28, 2026
7cb44da
Match the VCL GUI's tab order, Ctrl+Tab and tooltips in the Win32 GUI
AnthonySWest Oct 28, 2026
6a922af
Ignore an empty command line in the Win32 GUI's argument splitting
AnthonySWest Oct 28, 2026
8f9d1dd
Add CMake sources files for the shared GUI core and the Win32 GUI runner
AnthonySWest Oct 28, 2026
2cd8465
Build and smoke-test the Win32 GUI in CI
AnthonySWest Oct 28, 2026
8c8e334
Document the Win32 GUI runner
AnthonySWest Oct 28, 2026
d0bf865
Compile in parallel with MSVC's /MP
AnthonySWest Oct 28, 2026
5c974fb
Update README.md to say that the GUI filter box ignores only ASCII case
AnthonySWest Oct 28, 2026
54db24d
Merge pull request #34 from ASWSoftware/asw/win32-gui
AnthonySWest Oct 28, 2026
f2cc71e
Bump version to 1.5.0-dev.4
AnthonySWest Oct 28, 2026
489e943
Overflow the stack on a fresh thread in the crash guard test
AnthonySWest Oct 28, 2026
64b4860
Crash through a volatile pointer in the deep access violation test
AnthonySWest Oct 28, 2026
ae59589
Release the recording lock after a caught crash
AnthonySWest Oct 28, 2026
c50a89f
Read Windows arguments as UTF-16 and show UTF-8 in the console
AnthonySWest Oct 28, 2026
9fa448a
Reword the console code page test's skip message
AnthonySWest Oct 28, 2026
1c1c0f4
Let the string checks compare texts of different types
AnthonySWest Oct 28, 2026
90a461e
Update coding standards in AGENTS.md
AnthonySWest Oct 28, 2026
a624719
Let the Empty checks take C strings and character arrays
AnthonySWest Oct 28, 2026
e117f01
Change Near checks to take mixed types and reject invalid tolerances
AnthonySWest Oct 29, 2026
f3c5895
Run timed tests with the caller's floating-point environment
AnthonySWest Oct 29, 2026
fb8c984
Let the exception checks expect any C++ type
AnthonySWest Oct 29, 2026
5f3fc48
Catch a pointer to const in CheckThrows on MSVC
AnthonySWest Oct 29, 2026
2aa06b1
Merge pull request #35 from ASWSoftware/asw/code-review
AnthonySWest Oct 29, 2026
cd041b8
Bump version to 1.5.0-dev.5
AnthonySWest Oct 29, 2026
e315041
Add a dark theme to the VCL GUI runner, with a remembered override
AnthonySWest Oct 29, 2026
6c6802b
Merge pull request #36 from ASWSoftware/asw/theme-vcl
AnthonySWest Oct 29, 2026
9f0f2a1
Add icon resource image files and ImageMagick script
AnthonySWest Oct 29, 2026
6a90a27
Give the console and GUI runners the ASWUnitTests icon
AnthonySWest Oct 29, 2026
922e8a7
Merge pull request #37 from ASWSoftware/asw/icon
AnthonySWest Oct 29, 2026
8b367e8
Bump version to 1.5.0-dev.6
AnthonySWest Oct 29, 2026
46ffff9
Add a dark theme to the Win32 GUI runner, painted in Carbon's colors
AnthonySWest Oct 29, 2026
2087759
Leave disabled dark menu items unhighlighted, give text dialog the ic…
AnthonySWest Oct 29, 2026
e905b2e
Paint the results tabs' scroll arrows in the dark theme
AnthonySWest Oct 29, 2026
dcdb267
Dim disabled scroll bars' arrows in the dark theme
AnthonySWest Oct 29, 2026
d172ee8
Give dark theme's bordered controls their own border, so light one ne…
AnthonySWest Oct 29, 2026
e3dd566
Paint the dark theme's scroll bar corner
AnthonySWest Oct 29, 2026
5043d58
Keep a disabled dark scroll bar's arrows dark after the mouse leaves it
AnthonySWest Oct 29, 2026
3864a76
Stop the bordered controls' frames and a growing tree or list from fl…
AnthonySWest Oct 29, 2026
f8b1fb3
Don't repaint the dark progress bar on the themed bar's animation timer
AnthonySWest Oct 29, 2026
6526f6f
Merge pull request #38 from ASWSoftware/asw/theme-win-gui
AnthonySWest Oct 29, 2026
8ea3eef
Bump version to 1.5.0-dev.7
AnthonySWest Oct 29, 2026
e46b718
Add theme files for GUI runners' dark look (View > Theme > Dark Theme)
AnthonySWest Oct 30, 2026
b8c7730
Keep GUI tests out of the real layout and Themes files, and widen Win…
AnthonySWest Oct 30, 2026
1c90002
Keep Win32 GUI's menus' captions when switching from dark to light
AnthonySWest Oct 30, 2026
fdedc9a
Merge pull request #39 from ASWSoftware/asw/theme-files
AnthonySWest Oct 30, 2026
2626313
Bump version to 1.5.0-dev.8
AnthonySWest Oct 30, 2026
7ba6906
Add four Carbon-tinted dark themes to the Win32 GUI: Ember, Forest, M…
AnthonySWest Oct 30, 2026
6e067b5
Add four of RAD Studio's dark VCL styles to both GUIs as built-in dar…
AnthonySWest Oct 30, 2026
9522608
Apply the VCL GUI's theme after the menu click that chose it, not dur…
AnthonySWest Oct 30, 2026
ae5fd7f
Merge pull request #40 from ASWSoftware/asw/builtin-themes
AnthonySWest Oct 30, 2026
3597954
Bump version to 1.5.0
AnthonySWest Oct 30, 2026
12df17e
Roll up the 1.5.0 CHANGELOG and update the docs for the release
AnthonySWest Oct 30, 2026
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
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@
*.jpg -text
*.png -text
*.gif -text
*.ico -text
*.pdf -text
56 changes: 55 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,13 @@ jobs:
generator: ""
build_args: "--config Release"
exe_path: build/bin/Release/ASWUnitTests.exe
gui_exe_path: build/bin/Release/ASWUnitTests_Win32_GUI.exe
- name: Windows (MinGW)
os: windows-latest
generator: "MinGW Makefiles"
build_args: ""
exe_path: build/bin/ASWUnitTests.exe
gui_exe_path: build/bin/ASWUnitTests_Win32_GUI.exe
- name: Linux (GCC)
os: ubuntu-latest
generator: ""
Expand Down Expand Up @@ -79,8 +81,11 @@ jobs:

- name: Build
shell: bash
# Four jobs, one per core of a hosted runner. The Windows jobs build the Win32 GUI runner too, which
# compiles the self-tests again; built one file at a time, that would take the MinGW job close to its
# timeout. A bare --parallel would let make start a compiler for every file at once.
run: |
cmake --build build ${{ matrix.build_args }}
cmake --build build ${{ matrix.build_args }} --parallel 4
if [ $? -ne 0 ]; then
echo "Build failed!"
exit 1
Expand Down Expand Up @@ -142,3 +147,52 @@ jobs:
run: |
./${{ matrix.exe_path }} --project-name "ASWUnitTests-CI-Partition1" --partition-index 1 --partition-count 2
./${{ matrix.exe_path }} --project-name "ASWUnitTests-CI-Partition2" --partition-index 2 --partition-count 2

- name: Run self-tests in the Win32 GUI
# Smoke test for the Win32 GUI runner (Windows jobs only): it opens its window, runs every test (--run),
# writes the same JUnit report as the console runner, then closes and exits with the console runner's
# exit code (--exit). Bash waits for a GUI program to end, unlike a Windows command prompt. The step's
# own timeout ends a GUI left waiting on a dialog that nobody can close, rather than leaving it to the
# job's.
if: matrix.gui_exe_path != ''
id: gui_tests
timeout-minutes: 3
shell: bash
run: |
if [ ! -f "${{ matrix.gui_exe_path }}" ]; then
echo "ERROR: Executable not found at ${{ matrix.gui_exe_path }}"
exit 1
fi
./${{ matrix.gui_exe_path }} --project-name "ASWUnitTests-CI-Win32GUI" --run --exit \
--report-junit gui-results.xml --test-timeout-seconds 60 --catch-crashes

- name: Check the Win32 GUI's report
# The GUI ran the same tests as the console runner, so both reports list the same number.
if: matrix.gui_exe_path != ''
shell: bash
run: |
console=$(grep -o '<testcase ' junit-results.xml | wc -l)
gui=$(grep -o '<testcase ' gui-results.xml | wc -l)
echo "Console runner: $console tests, Win32 GUI runner: $gui tests"
if [ "$gui" -eq 0 ] || [ "$gui" -ne "$console" ]; then
echo "ERROR: The Win32 GUI's report doesn't list the same tests as the console runner's"
exit 1
fi

- name: Win32 GUI test results summary
# As for the console runner's report above.
if: ${{ matrix.gui_exe_path != '' && !cancelled() && steps.gui_tests.outcome != 'skipped' }}
uses: dorny/test-reporter@v3
with:
name: Win32 GUI Test Results - ${{ matrix.name }}
path: gui-results.xml
reporter: java-junit
use-actions-summary: true

- name: Upload Win32 GUI test results
if: ${{ matrix.gui_exe_path != '' && !cancelled() && steps.gui_tests.outcome != 'skipped' }}
uses: actions/upload-artifact@v7
with:
name: gui-test-results-${{ matrix.name }}
path: gui-results.xml
if-no-files-found: error
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
[Ll]ogs/
[Rr]elease/
[Dd]ebug/
[Pp]lans/

# Misc
*.bak
Expand Down
25 changes: 22 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,14 @@ These instructions apply to the entire repository unless a more specific `AGENTS
ASWUnitTests is a lightweight C++ console unit-testing framework.

- `src/` contains the framework implementation.
- `gui/src/` contains the GUI runners' shared units, which contain no UI or VCL code, and `gui/tests/` their unit tests, which every project (CMake and RAD Studio) compiles, so they also run on Linux.
- `tests/` contains unit tests for the example code.
- `toTest/` contains example code under test.
- `rad370/` contains the RAD Studio 13.1 project and Windows build scripts.
- `vcl/` contains RAD Studio projects that link the VCL and define `ASWUNITTESTS_RTL_EXCEPTIONS`, exercising the framework's opt-in RTL support (RTL exceptions and the `System::String` overloads): `vcl/console/rad370/` is a VCL console project (with its own build scripts) that runs the full self-test suite plus the RTL-specific and GUI unit tests in `vcl/tests/`. `vcl/gui/rad370/` is the VCL GUI runner project (with its own build scripts, and a project group that also opens the console project), built from the sources in `vcl/gui/src/`. The console project also compiles the GUI's non-form units, so their tests run without the GUI.
- `win32/` contains the Win32 GUI runner, which uses only the Windows API (no VCL) and has the VCL GUI runner's features: `win32/gui/src/` holds its units, its `WinMain()`, its manifest and `ASWUnitTests_Win32GUI_Sources.cmake`, from which `cmake/CMakeLists.txt` builds the `ASWUnitTests_Win32_GUI` target on Windows. `win32/gui/rad370/` is its RAD Studio project (Win32 and Win64x, with its own build scripts). `win32/tests/` has the tests of its units that need no window, which the CMake console target and the `rad370` console project also compile on Windows.
- `cmake/` contains the CMake project, which builds the console runner and, on Windows, the Win32 GUI runner.
- `resource/` contains the ASWUnitTests icon, `ASWUnitTests.ico`, and `ASWUnitTests_Icon.rc`, which embeds it in the CMake builds; `make_icon.ps1` draws the icon and writes the `.ico` and its `icon_<size>.png` files.
- `README.md` contains usage and integration examples.
- `.uncrustify.cfg` and `.githooks/` define the repository formatting workflow.

Expand Down Expand Up @@ -51,13 +55,25 @@ Keep all source files (`.cpp`/`.h`) plain ASCII, including comments. MSVC reads

- Insert new class methods in alphabetical order within their existing section. If the class has named or visibly separated sections, preserve those sections and alphabetize only within the relevant section.
- Insert new free functions in alphabetical order within their existing section. Apply the same section rule when functions are grouped.
- Lay out a new class's members by kind, each kind in a section of its own with its own access label, even when the label repeats: nested types first, then static data, then data members, then the methods, grouped by access (private, then protected, then public), with each group's static methods in a section before its other methods. See `TWin32GUIMainWindow` (`win32/gui/src/ASWUnitTests_Win32GUI_MainWindow.h`) and `TStringCheckProbe` (`tests/UT_Helper_StringChecks.h`).
- Follow the surrounding naming, indentation, brace, include, and comment style. Avoid unrelated formatting changes.
- Keep declarations and definitions consistent, and update all relevant project or build files when adding, removing or renaming source files, including `Deploy.bat`, which copies an explicit list of files.
- Keep declarations and definitions consistent, and update all relevant project or build files when adding, removing or renaming source files, including `Deploy.bat`, which copies an explicit list of files, and the `*_Sources.cmake` files (`src/`, `gui/src/`, `win32/gui/src/`), which list each folder's sources for projects that use this repository as a submodule.
- Add or update focused tests for behavior changes, including error and platform-specific cases where applicable.
- Each unit under test has exactly one test module: `ASWUnitTests_X` is tested by `Test_ASWUnitTests_X.cpp`/`.h` (class `TTest_ASWUnitTests_X`, group name `"ASWUnitTests_X_Tests"`), in the matching tests folder, and its tests go there, however large it grows. Supporting code that isn't a test itself, such as a fixture group or a probe whose templates are instantiated for the tests, may go in a helper module named `UT_Helper_<what>.cpp`/`.h` in the same folder (e.g. `tests/UT_Helper_StringChecks`), listed in the projects and build files like any other source file.
- RAD Studio's Win32 linker (ilink32) limits the line-number debug information of each module (its "Line number cache"), and `tests/Test_ASWUnitTests_TestBase.cpp` is close to that limit. A Win32 Debug build then fails with "Fatal: Exceeded memory limit for block Line number cache in module ...". Every distinct lambda registered as a test costs a `std::function` instantiation, so prefer a few tests that each check many cases (or parameterized tests, which share one callback) to hundreds of registered lambdas, and move heavy template instantiations into a `UT_Helper_` module, defined and explicitly instantiated in its `.cpp`. Check with the VCL console's Win32 Debug build, which links the most modules.

## Naming and Style

- New enums take an `E` prefix (`EWin32GUICommand`); classes and structs take `T`. Existing enums that use `T` (e.g. `TLogKind`, `TTestOutcome`) keep it.
- Write acronyms in identifiers and file names in uppercase: `GUI`, `CLI`, `RTL`, `UTF8`, `XML` (e.g. `TCLIParser`, `ToUTF8`, `ASWUnitTests_GUI_TestList`). `JUnit` is a name, not an acronym. Check an existing name against this rule before copying its casing.
- Compare a pointer, `std::function` or other nullable value with `nullptr` explicitly (`if (filter != nullptr)`), rather than relying on its conversion to `bool` (`if (filter)`).
- In a `.cpp` file, describe a function in a block comment between its `//----` separator line and its definition (`/*`, the function's name, a blank line, the description, `*/`), not in `//` lines above it; a function that needs no explanation gets no comment. Declarations in a header keep `//` comments. See `win32/gui/src/ASWUnitTests_Win32GUI_System.cpp`.
- Suppress an intentional MSVC warning with `#pragma warning(push)`, `#pragma warning(disable: N)` and `#pragma warning(pop)` around the whole function or block, guarded by `#if defined(_MSC_VER)`, never with `#pragma warning(suppress: N)`: MSVC checks some warnings (e.g. C4702) against the state at the end of the function, after a `suppress` has lapsed.
- Don't name an identifier `assert`, even a parameter: `assert()` is a macro wherever `<cassert>` is included, and the VCL headers include it.

## Building and Testing

The RAD Studio debug build can be run from `rad370/Build_Win64x_Debug.bat` when the `Rad370` environment variable points to the RAD Studio installation. The release script is `rad370/Build_Win64x_Release.bat`. Neither pauses before exiting by default; pass `--pause` to have the console prompt "press enter to continue" first, e.g. when running from an IDE that would otherwise close the console immediately.
The RAD Studio debug build can be built with `rad370/Build_Win64x_Debug.bat`, run from `rad370/`, when the `Rad370` environment variable points to the RAD Studio installation. The release script is `rad370/Build_Win64x_Release.bat`. The scripts only build; the executable, `build/bin/<Config>/ASWUnitTests.exe`, doesn't pause before exiting by default. Pass it `--pause` to have the console prompt "press enter to continue" first, e.g. when running from an IDE that would otherwise close the console immediately (the RAD Studio projects' debugger parameters do).

For other environments, use the repository's CMake configuration when present or the IDE's native project configuration. Tests should be run outside the debugger unless debugging an expected exception is intentional. Before considering a change complete:

Expand All @@ -66,7 +82,8 @@ For other environments, use the repository's CMake configuration when present or
- Check compiler warnings and errors.
- Validate both Windows-specific and portable paths when the change touches platform code.
- When the change touches code guarded by `ASWUNITTESTS_RTL_EXCEPTIONS_ENABLED`, or the exception handling around it, also build and run the VCL console project (`vcl/console/rad370/Build_Win64x_Debug.bat` and the Win32 script), since no other build compiles that code.
- When the change touches `vcl/gui/src/`, or framework code the GUI runner uses (such as `ITestRunObserver` or `ASWUnitTests_CLI`), also build the VCL console project (which runs the GUI's unit tests) and the GUI project (`vcl/gui/rad370/Build_Win64x_Debug.bat` and the Win32 script), then run the GUI and check the affected behavior by hand.
- When the change touches `vcl/gui/src/` or `gui/src/`, or framework code the GUI runners use (such as `ITestRunObserver` or `ASWUnitTests_CLI`), also build the VCL console project (which runs the GUI's unit tests) and the VCL GUI project (`vcl/gui/rad370/Build_Win64x_Debug.bat` and the Win32 script), then run the GUI and check the affected behavior by hand.
- When the change touches `win32/gui/src/` or `gui/src/`, or framework code the GUI runners use, also build the CMake `ASWUnitTests_Win32_GUI` target with MinGW, with Clang (llvm-mingw) and, when available, with MSVC, and the RAD Studio Win32 GUI project (`win32/gui/rad370/Build_Win64x_Debug.bat` and the Win32 script), then run the GUI and check the affected behavior by hand. A full `--run --exit` of each build (as CI does) checks that it still runs every test.

## Changelog

Expand All @@ -87,4 +104,6 @@ git config --local core.hooksPath .githooks/

Wrap Markdown prose at 100 columns in `README.md`, `CONTRIBUTING.md` and `CHANGELOG.md`, re-wrapping the edited paragraph when a change makes a line too long. Don't split inline code or a link's text across lines. Code blocks and tables are exempt, and so is a line that only overflows because a single link or URL can't be split.

Don't use em dashes in anything written for this repository (documentation, comments, messages): use a hyphen with a space on each side (" - "), or restructure the sentence.

Review the final diff for accidental file changes, ordering regressions, missing includes, platform assumptions, and tests that do not actually exercise the changed behavior. Do not commit changes unless the user explicitly requests a commit.
Loading
Loading