Skip to content

Commit a085634

Browse files
committed
feat: integrations & on-target example for v0.5.0
- examples/cortex_m/ — Cortex-M3 PIL example running under QEMU (mps2-an385 + semihosting). Adds src/trace/trace_semihost.c. - cmake/ceedless.cmake + top-level CMakeLists.txt — add_ceedless_test() with CTest integration and per-test JUnit XML. - library.json — PlatformIO library manifest. - .vscode/tasks.json + extensions.json — build/test/lint/cov/watch/report. - .pre-commit-config.yaml — gofmt/vet, large-file, line-ending hooks. - CI: new cortex_m job installs gcc-arm-none-eabi + qemu-system-arm and asserts the PIL example exits with 3/3 passed. - README & docs/CLI.md updated for the new flags, CMake, parametric, property, and Cortex-M sections. - CHANGELOG: [0.5.0] entry. cli/main.go: version 0.4.0 → 0.5.0. - .gitignore: build-cmake/ + CMake artefacts; whitelist .vscode templates.
1 parent 12fdff0 commit a085634

20 files changed

Lines changed: 743 additions & 11 deletions

File tree

.github/workflows/ci.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,21 @@ jobs:
8484
name: coverage-html
8585
path: demo/app/build/coverage.html
8686

87+
cortex_m:
88+
name: cortex-m PIL (QEMU)
89+
runs-on: ubuntu-latest
90+
needs: test
91+
steps:
92+
- uses: actions/checkout@v4
93+
- name: Install ARM toolchain + QEMU
94+
run: sudo apt-get update && sudo apt-get install -y gcc-arm-none-eabi qemu-system-arm
95+
- name: Build & run Cortex-M3 PIL example
96+
working-directory: examples/cortex_m
97+
run: make qemu | tee qemu.log
98+
- name: Assert all tests passed on target
99+
working-directory: examples/cortex_m
100+
run: grep -q '3/3 passed, 0 failed' qemu.log
101+
87102
docker:
88103
name: docker image build
89104
runs-on: ubuntu-latest

.gitignore

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Build artifacts
22
build/
3+
build-cmake/
34
bin/ceedless
45
*.o
56
*.obj
@@ -8,6 +9,13 @@ bin/ceedless
89
*.dylib
910
*.exe
1011

12+
# CMake
13+
CMakeCache.txt
14+
CMakeFiles/
15+
cmake_install.cmake
16+
CTestTestfile.cmake
17+
Testing/
18+
1119
# Coverage
1220
*.gcda
1321
*.gcno
@@ -21,7 +29,10 @@ report.tap
2129
reports/
2230

2331
# Editor / IDE
24-
.vscode/
32+
.vscode/*
33+
!.vscode/tasks.json
34+
!.vscode/launch.json
35+
!.vscode/extensions.json
2536
.idea/
2637
*.swp
2738
*.swo

.pre-commit-config.yaml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# See https://pre-commit.com for usage.
2+
#
3+
# pip install pre-commit
4+
# pre-commit install
5+
#
6+
# Runs gofmt + go vet on the CLI, basic hygiene checks on every commit,
7+
# and lets `make lint` (which also runs Go unit tests) gate any push.
8+
9+
repos:
10+
- repo: https://github.com/pre-commit/pre-commit-hooks
11+
rev: v4.6.0
12+
hooks:
13+
- id: trailing-whitespace
14+
- id: end-of-file-fixer
15+
- id: check-merge-conflict
16+
- id: check-added-large-files
17+
args: [--maxkb=512]
18+
- id: check-yaml
19+
- id: mixed-line-ending
20+
args: [--fix=lf]
21+
22+
- repo: https://github.com/dnephin/pre-commit-golang
23+
rev: v0.5.1
24+
hooks:
25+
- id: go-fmt
26+
files: ^cli/.*\.go$
27+
- id: go-vet
28+
files: ^cli/.*\.go$
29+
args: [./cli/...]
30+
31+
- repo: local
32+
hooks:
33+
- id: ceedless-lint
34+
name: ceedless lint (gofmt + go vet + go test)
35+
entry: make lint
36+
language: system
37+
pass_filenames: false
38+
stages: [pre-push]

.vscode/extensions.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"recommendations": [
3+
"ms-vscode.cpptools",
4+
"ms-vscode.makefile-tools",
5+
"golang.go",
6+
"hbenl.vscode-test-explorer",
7+
"matepek.vscode-catch2-test-adapter"
8+
]
9+
}

.vscode/tasks.json

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
{
2+
"version": "2.0.0",
3+
"tasks": [
4+
{
5+
"label": "ceedless: build all",
6+
"type": "shell",
7+
"command": "make all",
8+
"group": { "kind": "build", "isDefault": true },
9+
"problemMatcher": ["$gcc"]
10+
},
11+
{
12+
"label": "ceedless: run self-tests",
13+
"type": "shell",
14+
"command": "make test",
15+
"group": "test",
16+
"problemMatcher": ["$gcc"]
17+
},
18+
{
19+
"label": "ceedless: lint (gofmt+vet+go test)",
20+
"type": "shell",
21+
"command": "make lint",
22+
"problemMatcher": []
23+
},
24+
{
25+
"label": "ceedless: coverage report",
26+
"type": "shell",
27+
"command": "./bin/ceedless cov",
28+
"problemMatcher": ["$gcc"]
29+
},
30+
{
31+
"label": "ceedless: watch (re-run on file change)",
32+
"type": "shell",
33+
"command": "./bin/ceedless watch",
34+
"isBackground": true,
35+
"problemMatcher": []
36+
},
37+
{
38+
"label": "ceedless: HTML report from reports/",
39+
"type": "shell",
40+
"command": "./bin/ceedless test --report-dir reports && ./bin/ceedless report reports/",
41+
"problemMatcher": []
42+
},
43+
{
44+
"label": "ceedless: clean",
45+
"type": "shell",
46+
"command": "make clean",
47+
"problemMatcher": []
48+
}
49+
]
50+
}

CHANGELOG.md

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,48 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
66

77
## [Unreleased]
88

9+
## [0.5.0] — 2026-05-31
10+
11+
### Added — framework
12+
- `TEST_CASE(args...)` annotation + `RUN_TEST_CASE(name, label, args)` for
13+
parametric tests. The runner generator auto-emits one call per `TEST_CASE`.
14+
- `TEST_PROPERTY(var, iters, body)` — property-based test loop.
15+
- `TEST_ASSERT_GOLDEN_BYTES(label, buf, n)` — snapshot / golden-file
16+
comparison; `CEEDLESS_GOLDEN_UPDATE=1` to refresh.
17+
- `mock_expect_with_matcher` / `MOCK_EXPECT_WITH_MATCHER` — user-supplied
18+
argument matchers (for ranges, partial matches, etc.).
19+
- Deterministic shuffle via `ceedless_set_shuffle_seed` / `CEEDLESS_SEED`.
20+
- TAP 13 output backend: `ceedless_set_tap_path` / `CEEDLESS_TAP`.
21+
- ARM Cortex-M semihosting trace backend (`CEEDLESS_TRACE_SEMIHOST`).
22+
- Memory assertion failures now show a ±8-byte hex window around the diff.
23+
24+
### Added — CLI
25+
- `ceedless test --asan / --ubsan / --msan` — sanitizer flag passthrough.
26+
- `ceedless test --shuffle [--seed N]` — reproducible random test order.
27+
- `ceedless test --tap-dir DIR` — per-program TAP files.
28+
- `ceedless fuzz <fn> -h <header>` — libFuzzer harness generator.
29+
- `ceedless report DIR` — HTML aggregate over JUnit XMLs.
30+
- Auto-runner now `#include`s the test source so `static` parametric
31+
functions resolve cleanly.
32+
33+
### Added — integrations & examples
34+
- `examples/cortex_m/` — Cortex-M3 PIL example running under QEMU
35+
(`make qemu`). Same source compiles for host SIL and target PIL.
36+
- `cmake/ceedless.cmake` + top-level `CMakeLists.txt`
37+
`add_ceedless_test(<name> SOURCES … INCLUDE … DEFINES …)` integrates
38+
with CTest and emits JUnit XML via `CEEDLESS_JUNIT`.
39+
- `library.json` — PlatformIO library manifest.
40+
- `.vscode/tasks.json` + `extensions.json` — VS Code tasks for build,
41+
test, lint, coverage, watch, report.
42+
- `.pre-commit-config.yaml` — pre-commit hooks template (gofmt, vet,
43+
large-file, line-ending checks; `make lint` on push).
44+
- CI matrix gains a `cortex_m` job that installs `gcc-arm-none-eabi`
45+
and `qemu-system-arm` and runs the PIL example.
46+
47+
### Changed
48+
- Self-test count: 33 → 42 (new `tests/test_extensions.c` exercises
49+
parametric, property, golden, PRNG, and memory-diff paths).
50+
951
## [0.4.0] — 2026-05-29
1052

1153
### Added
@@ -53,7 +95,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
5395
- Virtual I2C / generic register-bank peripheral.
5496
- Sensor-driver example.
5597

56-
[Unreleased]: https://github.com/tevfik/ceedless/compare/v0.4.0...HEAD
98+
[Unreleased]: https://github.com/tevfik/ceedless/compare/v0.5.0...HEAD
99+
[0.5.0]: https://github.com/tevfik/ceedless/releases/tag/v0.5.0
57100
[0.4.0]: https://github.com/tevfik/ceedless/releases/tag/v0.4.0
58101
[0.3.0]: https://github.com/tevfik/ceedless/releases/tag/v0.3.0
59102
[0.2.0]: https://github.com/tevfik/ceedless/releases/tag/v0.2.0

CMakeLists.txt

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# SPDX-License-Identifier: MIT
2+
# Copyright (c) 2026 Tevfik — https://github.com/tevfik/ceedless
3+
#
4+
# Top-level CMakeLists for building ceedless's own self-tests via CMake.
5+
# Most users should clone the repo and either (a) `make all` or
6+
# (b) include `cmake/ceedless.cmake` from their own CMake project.
7+
8+
cmake_minimum_required(VERSION 3.16)
9+
project(ceedless C)
10+
11+
set(CEEDLESS_HOME "${CMAKE_CURRENT_SOURCE_DIR}")
12+
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
13+
include(ceedless)
14+
15+
enable_testing()
16+
17+
set(SELFTEST_SRC
18+
tests/test_main.c
19+
tests/test_trace_port.c
20+
tests/test_virtual_peripheral.c
21+
tests/test_runner.c
22+
tests/test_assertions.c
23+
tests/test_exception.c
24+
tests/test_mock.c
25+
tests/test_peripherals.c
26+
tests/test_extensions.c
27+
)
28+
29+
add_ceedless_test(ceedless_selftest
30+
SOURCES ${SELFTEST_SRC}
31+
INCLUDE include tests
32+
DEFINES CEEDLESS_TRACE_BUFFER
33+
)
34+
35+
add_ceedless_test(ceedless_example_sensor
36+
SOURCES
37+
examples/sensor_driver/sensor_driver.c
38+
examples/sensor_driver/test_sensor_driver.c
39+
INCLUDE examples/sensor_driver
40+
)

Makefile

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ EXAMPLE_SRC := \
4040

4141
BUILD := build
4242

43-
.PHONY: all cli test example cli-test docker docker-test lint clean
43+
.PHONY: all cli test example cli-test docker docker-test lint clean cortex_m
4444
all: cli test example cli-test
4545

4646
# Build the Go CLI into bin/ceedless. Pure stdlib, no deps.
@@ -112,5 +112,10 @@ lint:
112112
@echo "==> go test"
113113
@cd cli && go test ./...
114114

115+
# Build & run the Cortex-M3 PIL example under QEMU. Skipped from `make all`
116+
# because it requires arm-none-eabi-gcc + qemu-system-arm.
117+
cortex_m:
118+
$(MAKE) -C examples/cortex_m qemu
119+
115120
clean:
116121
rm -rf $(BUILD)

README.md

Lines changed: 63 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,22 @@ binary CLI.
1212
**Key features:**
1313

1414
- Unity-style assertion macros (full set: INT, HEX, FLOAT, STRING, MEMORY, ARRAY)
15-
- Header-only function mocks (MOCK_DEFINE / MOCK_EXPECT_* / MOCK_VERIFY)
15+
- Header-only function mocks with argument matchers, callbacks, throw, return-thru-ptr
1616
- Try / Catch / Throw exception handling
1717
- Virtual peripherals: SPI, UART, GPIO, ADC (stateful, register-bank backed)
18-
- On-target execution support (same source builds for host SIL and MCU PIL)
19-
- Pluggable trace transport (ITM, RTT, UART, host-printf, ring-buffer)
18+
- On-target execution support — same source compiles for host SIL and Cortex-M PIL
19+
(see [`examples/cortex_m/`](examples/cortex_m/README.md) for a QEMU runner)
20+
- Pluggable trace transport: host-printf, UART, RTT, ITM, semihosting, ring-buffer
21+
- Parametric `TEST_CASE(...)` annotations + property-based `TEST_PROPERTY`
22+
- Snapshot / golden-byte assertions for protocol & codec tests
23+
- Deterministic test order shuffle (`--shuffle --seed`) for flake hunting
2024
- Auto test discovery + runner generation (`ceedless test`)
21-
- gcov coverage, JUnit XML output, file-watch mode
25+
- gcov coverage, JUnit XML + TAP output, HTML aggregate report
26+
- Sanitizer flag passthrough (`--asan/--ubsan/--msan`) and `ceedless fuzz`
27+
libFuzzer harness generator
28+
- Build integrations: GNU Make, **CMake** (`add_ceedless_test`), **PlatformIO**
2229

23-
Zero dynamic allocation. ~1500 LOC of portable C11.
30+
Zero dynamic allocation in the core. ~2000 LOC of portable C11.
2431

2532
---
2633

@@ -52,6 +59,57 @@ OK: negative test failed as expected
5259
ceedless: 1/1 test programs passed
5360
```
5461

62+
### CMake
63+
64+
```cmake
65+
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
66+
set(CEEDLESS_HOME "${CMAKE_SOURCE_DIR}/external/ceedless")
67+
include(ceedless)
68+
69+
enable_testing()
70+
add_ceedless_test(test_packet
71+
SOURCES test/test_packet.c src/packet.c
72+
INCLUDE include
73+
)
74+
```
75+
76+
Run with `cmake -B build && ctest --test-dir build --output-on-failure`.
77+
78+
### Parametric tests
79+
80+
```c
81+
TEST_CASE(0, 0, 0)
82+
TEST_CASE(1, 2, 3)
83+
TEST_CASE(-5, 5, 0)
84+
static void test_add(int a, int b, int expected)
85+
{
86+
TEST_ASSERT_EQUAL_INT(expected, a + b);
87+
}
88+
```
89+
90+
The runner generator emits one `RUN_TEST_CASE` call per `TEST_CASE` line —
91+
no manual dispatch needed.
92+
93+
### Property-based tests
94+
95+
```c
96+
TEST_PROPERTY(x, 256, {
97+
uint32_t y = ceedless_rand_u32();
98+
TEST_ASSERT_EQUAL_UINT32(x + y, y + x);
99+
});
100+
```
101+
102+
Use `--seed N` (or `CEEDLESS_SEED=N`) for reproducible failures.
103+
104+
### Cortex-M PIL
105+
106+
```bash
107+
cd examples/cortex_m && make qemu
108+
```
109+
110+
Runs the same assertion suite on an ARM Cortex-M3 under QEMU with
111+
semihosting output. See [`examples/cortex_m/README.md`](examples/cortex_m/README.md).
112+
55113
---
56114

57115
## Layout

cli/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import (
77
"os"
88
)
99

10-
const version = "0.4.0"
10+
const version = "0.5.0"
1111

1212
type command struct {
1313
name string

0 commit comments

Comments
 (0)