vyperling 0.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- vyperling-0.0.1/LICENSE +21 -0
- vyperling-0.0.1/PKG-INFO +491 -0
- vyperling-0.0.1/README.md +467 -0
- vyperling-0.0.1/pyproject.toml +55 -0
- vyperling-0.0.1/vyperling/__init__.py +3 -0
- vyperling-0.0.1/vyperling/c/UNITY_LICENSE +24 -0
- vyperling-0.0.1/vyperling/c/forge_mock.c +111 -0
- vyperling-0.0.1/vyperling/c/forge_mock.h +54 -0
- vyperling-0.0.1/vyperling/c/unity.c +2501 -0
- vyperling-0.0.1/vyperling/c/unity.h +698 -0
- vyperling-0.0.1/vyperling/c/unity_fixture.h +94 -0
- vyperling-0.0.1/vyperling/c/unity_internals.h +1183 -0
- vyperling-0.0.1/vyperling/cli.py +297 -0
- vyperling-0.0.1/vyperling/compiler.py +162 -0
- vyperling-0.0.1/vyperling/config.py +101 -0
- vyperling-0.0.1/vyperling/coverage.py +86 -0
- vyperling-0.0.1/vyperling/discoverer.py +77 -0
- vyperling-0.0.1/vyperling/errors.py +36 -0
- vyperling-0.0.1/vyperling/mockgen.py +403 -0
- vyperling-0.0.1/vyperling/reporter.py +138 -0
- vyperling-0.0.1/vyperling/runner.py +132 -0
- vyperling-0.0.1/vyperling/scaffold.py +67 -0
- vyperling-0.0.1/vyperling/templates/__init__.py +0 -0
- vyperling-0.0.1/vyperling/templates/mock_header.h.j2 +38 -0
- vyperling-0.0.1/vyperling/templates/mock_source.c.j2 +159 -0
- vyperling-0.0.1/vyperling/templates/scaffold_example_c.j2 +7 -0
- vyperling-0.0.1/vyperling/templates/scaffold_example_h.j2 +7 -0
- vyperling-0.0.1/vyperling/templates/scaffold_forge_yml.j2 +25 -0
- vyperling-0.0.1/vyperling/templates/scaffold_readme_md.j2 +29 -0
- vyperling-0.0.1/vyperling/templates/scaffold_test_example_c.j2 +18 -0
- vyperling-0.0.1/vyperling/toolchains.py +143 -0
- vyperling-0.0.1/vyperling/unity.py +60 -0
vyperling-0.0.1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Ericson Joseph
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
vyperling-0.0.1/PKG-INFO
ADDED
|
@@ -0,0 +1,491 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: vyperling
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: Embedded C test runner with cross-compilation support
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Author: Ericson Joseph
|
|
8
|
+
Author-email: ericsonjoseph@gmail.com
|
|
9
|
+
Requires-Python: >=3.11,<4.0
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
15
|
+
Requires-Dist: click (>=8.0,<9.0)
|
|
16
|
+
Requires-Dist: gcovr (>=7.0,<9.0)
|
|
17
|
+
Requires-Dist: jinja2 (>=3.0,<4.0)
|
|
18
|
+
Requires-Dist: pycparser (>=2.21)
|
|
19
|
+
Requires-Dist: pycparser-fake-libc (>=2.21)
|
|
20
|
+
Requires-Dist: pyyaml (>=6.0,<7.0)
|
|
21
|
+
Requires-Dist: rich (>=13.0,<15.0)
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
24
|
+
# vyperling
|
|
25
|
+
|
|
26
|
+
[](https://www.python.org/downloads/)
|
|
27
|
+
[](https://opensource.org/licenses/MIT)
|
|
28
|
+
[](https://pypi.org/)
|
|
29
|
+
[](https://github.com/ericsonjoseph/vyperling)
|
|
30
|
+
|
|
31
|
+
**Embedded C unit test runner with cross-compilation support.**
|
|
32
|
+
A pip-installable replacement for [Ceedling](https://github.com/ThrowTheSwitch/Ceedling) — no Ruby dependencies, modern Python-first design.
|
|
33
|
+
|
|
34
|
+
## Overview
|
|
35
|
+
|
|
36
|
+
`vyperling` (`vpl` for short) is a complete embedded C testing framework that:
|
|
37
|
+
|
|
38
|
+
- 🔍 **Auto-discovers** `test_*.c` files in your test directory
|
|
39
|
+
- 🎯 **Generates CMock-style mocks** from C headers using pycparser + Jinja2
|
|
40
|
+
- 🔨 **Cross-compiles** for native (GCC) and embedded targets (ARM, MIPS, RISC-V, AVR) with parallel jobs
|
|
41
|
+
- 🖥️ **Executes** natively or under emulation (QEMU, simavr)
|
|
42
|
+
- 📊 **Parses** Unity test output with rich terminal reporting
|
|
43
|
+
- 📈 **Generates coverage** reports (gcov) for native targets
|
|
44
|
+
- 📋 **Exports** JUnit XML for CI/CD integration
|
|
45
|
+
|
|
46
|
+
Perfect for firmware development, embedded systems testing, and hardware validation workflows.
|
|
47
|
+
|
|
48
|
+
## Quick Start
|
|
49
|
+
|
|
50
|
+
### 1. Install
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
pip install vyperling
|
|
54
|
+
# Alias 'vpl' is registered automatically
|
|
55
|
+
vpl --version
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Development (editable install from source):
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
git clone https://github.com/ericsonjoseph/vyperling.git
|
|
62
|
+
cd vyperling
|
|
63
|
+
pip install -e .
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### 2. Create a Project
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
vpl new myproject
|
|
70
|
+
cd myproject
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
This scaffolds:
|
|
74
|
+
- `forge.yml` — project configuration
|
|
75
|
+
- `src/` — source files under test
|
|
76
|
+
- `test/` — test files (test_*.c pattern)
|
|
77
|
+
- `mocks/` — auto-generated mocks
|
|
78
|
+
|
|
79
|
+
### 3. Run Tests
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
# Test native target (default)
|
|
83
|
+
vpl test
|
|
84
|
+
|
|
85
|
+
# Cross-compile for MIPS32
|
|
86
|
+
vpl test --target mips32
|
|
87
|
+
|
|
88
|
+
# Run specific tests (pattern match)
|
|
89
|
+
vpl test -k uart
|
|
90
|
+
|
|
91
|
+
# Parallel compilation (4 jobs)
|
|
92
|
+
vpl test -j4
|
|
93
|
+
|
|
94
|
+
# Generate coverage report (native only)
|
|
95
|
+
vpl test --coverage
|
|
96
|
+
|
|
97
|
+
# Export JUnit XML for CI
|
|
98
|
+
vpl test --output junit
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Commands Reference
|
|
102
|
+
|
|
103
|
+
All commands use **`vyperling`** or **`vpl`** interchangeably.
|
|
104
|
+
|
|
105
|
+
### `vpl test` — Discover, Compile, Run, Report
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
vpl test [OPTIONS]
|
|
109
|
+
|
|
110
|
+
OPTIONS:
|
|
111
|
+
--target TEXT Toolchain target (default: targets.default from forge.yml)
|
|
112
|
+
-k, --filter PATTERN Run only tests matching PATTERN
|
|
113
|
+
-j, --jobs N Parallel compile jobs (default: 1)
|
|
114
|
+
--coverage Enable gcov coverage (native target only)
|
|
115
|
+
--output FORMAT Export results: junit
|
|
116
|
+
-v, --verbose Print every compiler command
|
|
117
|
+
--no-mock Skip automatic mock generation
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
**Example:** Test UART module with coverage on 4 parallel jobs:
|
|
121
|
+
```bash
|
|
122
|
+
vpl test -k uart -j4 --coverage
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### `vpl mock` — Generate Mocks from Headers
|
|
126
|
+
|
|
127
|
+
Generate CMock-style mocks from C header files:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
vpl mock src/uart.h src/spi.h
|
|
131
|
+
|
|
132
|
+
# Or mock all headers in configured source dirs
|
|
133
|
+
vpl mock --all
|
|
134
|
+
|
|
135
|
+
# Use a specific toolchain's preprocessor
|
|
136
|
+
vpl mock --target arm-cortex-m4 src/uart.h
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Output: `mocks/mock_uart.{c,h}` and `mocks/mock_spi.{c,h}`
|
|
140
|
+
|
|
141
|
+
### `vpl build` — Compile Only (No Execution)
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
vpl build [OPTIONS]
|
|
145
|
+
|
|
146
|
+
OPTIONS:
|
|
147
|
+
--target TEXT Toolchain target
|
|
148
|
+
-j, --jobs N Parallel compile jobs
|
|
149
|
+
-v, --verbose Print compiler commands
|
|
150
|
+
--no-mock Skip mock generation
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Useful for checking compilation without running tests:
|
|
154
|
+
```bash
|
|
155
|
+
vpl build --target arm-cortex-m4 --verbose
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### `vpl targets` — List Available Toolchains
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
vpl targets
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Shows:
|
|
165
|
+
- **Built-in targets** (native, mips32, mips32el, arm-cortex-m4, riscv32, avr)
|
|
166
|
+
- **Project-defined targets** (from `forge.yml`)
|
|
167
|
+
|
|
168
|
+
### `vpl clean` — Remove Build Artifacts
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
vpl clean # Remove all build directories
|
|
172
|
+
vpl clean --target mips32 # Remove only target's build dir
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### `vpl --version` / `vpl --help`
|
|
176
|
+
|
|
177
|
+
Show version or full command help.
|
|
178
|
+
|
|
179
|
+
## Cross-Compilation Targets
|
|
180
|
+
|
|
181
|
+
| Target | Triplet | Emulator | Install (Debian/Ubuntu) |
|
|
182
|
+
|--------|---------|----------|------------------------|
|
|
183
|
+
| `native` | (native) | direct exec | (included with GCC) |
|
|
184
|
+
| `mips32` | `mips-linux-gnu` | QEMU | `gcc-mips-linux-gnu qemu-user` |
|
|
185
|
+
| `mips32el` | `mipsel-linux-gnu` | QEMU | `gcc-mipsel-linux-gnu qemu-user` |
|
|
186
|
+
| `arm-cortex-m4` | `arm-none-eabi` | QEMU | `gcc-arm-none-eabi qemu-user` |
|
|
187
|
+
| `riscv32` | `riscv64-unknown-elf` | QEMU | `gcc-riscv64-unknown-elf qemu-user` |
|
|
188
|
+
| `avr` | `avr` | simavr | `gcc-avr avr-libc simavr` |
|
|
189
|
+
|
|
190
|
+
**Installation on Ubuntu/Debian:**
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
# Native (GCC)
|
|
194
|
+
sudo apt install gcc build-essential
|
|
195
|
+
|
|
196
|
+
# MIPS cross-compile
|
|
197
|
+
sudo apt install gcc-mips-linux-gnu qemu-user
|
|
198
|
+
|
|
199
|
+
# ARM Cortex-M4 (bare-metal)
|
|
200
|
+
sudo apt install gcc-arm-none-eabi qemu-user
|
|
201
|
+
|
|
202
|
+
# RISC-V
|
|
203
|
+
sudo apt install gcc-riscv64-unknown-elf qemu-user
|
|
204
|
+
|
|
205
|
+
# AVR (Arduino)
|
|
206
|
+
sudo apt install gcc-avr avr-libc simavr
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Custom Toolchains
|
|
210
|
+
|
|
211
|
+
Define custom targets in `forge.yml`:
|
|
212
|
+
|
|
213
|
+
```yaml
|
|
214
|
+
project:
|
|
215
|
+
name: myproject
|
|
216
|
+
|
|
217
|
+
toolchains:
|
|
218
|
+
custom-arm:
|
|
219
|
+
description: "Custom ARM GCC 12.2"
|
|
220
|
+
cc: "arm-linux-gcc-12.2"
|
|
221
|
+
ar: "arm-linux-ar-12.2"
|
|
222
|
+
cflags: ["-mcpu=cortex-a7", "-mfloat-abi=hard"]
|
|
223
|
+
emulator: qemu-arm-static
|
|
224
|
+
sysroot: /path/to/sysroot
|
|
225
|
+
|
|
226
|
+
targets:
|
|
227
|
+
default: native
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
## Configuration (`forge.yml`)
|
|
231
|
+
|
|
232
|
+
Minimal required:
|
|
233
|
+
|
|
234
|
+
```yaml
|
|
235
|
+
project:
|
|
236
|
+
name: MyProject
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Full example with all options:
|
|
240
|
+
|
|
241
|
+
```yaml
|
|
242
|
+
project:
|
|
243
|
+
name: my-firmware
|
|
244
|
+
src_dirs:
|
|
245
|
+
- src
|
|
246
|
+
- lib/hal
|
|
247
|
+
test_dir: test
|
|
248
|
+
include_dirs:
|
|
249
|
+
- src
|
|
250
|
+
- lib/hal/include
|
|
251
|
+
build_dir: build
|
|
252
|
+
mock_dir: mocks
|
|
253
|
+
|
|
254
|
+
targets:
|
|
255
|
+
default: native
|
|
256
|
+
|
|
257
|
+
compiler:
|
|
258
|
+
extra_cflags:
|
|
259
|
+
- -Wall
|
|
260
|
+
- -Wextra
|
|
261
|
+
- -pedantic
|
|
262
|
+
defines:
|
|
263
|
+
- DEBUG=1
|
|
264
|
+
- VERSION=1.0.0
|
|
265
|
+
|
|
266
|
+
toolchains:
|
|
267
|
+
custom-mcu:
|
|
268
|
+
description: "STM32 Cross-Compile"
|
|
269
|
+
cc: arm-none-eabi-gcc
|
|
270
|
+
ar: arm-none-eabi-ar
|
|
271
|
+
cflags:
|
|
272
|
+
- -mcpu=cortex-m4
|
|
273
|
+
- -mthumb
|
|
274
|
+
emulator: qemu-arm-static
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
## Project Layout
|
|
278
|
+
|
|
279
|
+
After `vpl new myproject`:
|
|
280
|
+
|
|
281
|
+
```
|
|
282
|
+
myproject/
|
|
283
|
+
├── forge.yml # Project configuration
|
|
284
|
+
├── src/ # Source files under test
|
|
285
|
+
│ ├── uart.h
|
|
286
|
+
│ ├── uart.c
|
|
287
|
+
│ └── spi.c
|
|
288
|
+
├── test/ # Unit tests
|
|
289
|
+
│ ├── test_uart.c
|
|
290
|
+
│ └── test_spi.c
|
|
291
|
+
└── mocks/ # Auto-generated mocks (created by 'vpl mock')
|
|
292
|
+
├── mock_uart.h
|
|
293
|
+
├── mock_uart.c
|
|
294
|
+
├── mock_spi.h
|
|
295
|
+
└── mock_spi.c
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
### Test File Pattern
|
|
299
|
+
|
|
300
|
+
Tests use the **`test_*.c`** pattern. Each test file:
|
|
301
|
+
- Includes `unity.h` (provided by vyperling)
|
|
302
|
+
- Includes mocks via `#include "mock_<dependency>.h"`
|
|
303
|
+
- Defines test cases with `void test_<name>(void)`
|
|
304
|
+
|
|
305
|
+
**Example: `test/test_uart.c`**
|
|
306
|
+
|
|
307
|
+
```c
|
|
308
|
+
#include "unity.h"
|
|
309
|
+
#include "uart.h"
|
|
310
|
+
#include "mock_gpio.h"
|
|
311
|
+
|
|
312
|
+
void setUp(void) {
|
|
313
|
+
// Called before each test
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
void tearDown(void) {
|
|
317
|
+
// Called after each test
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
void test_uart_init_should_configure_pins(void) {
|
|
321
|
+
gpio_init_Expect();
|
|
322
|
+
uart_init();
|
|
323
|
+
TEST_ASSERT_TRUE(1);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
void test_uart_send_should_transmit_byte(void) {
|
|
327
|
+
uart_send(0x42);
|
|
328
|
+
TEST_ASSERT_EQUAL_INT(0x42, last_byte_sent);
|
|
329
|
+
}
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
## Test Framework
|
|
333
|
+
|
|
334
|
+
vyperling uses:
|
|
335
|
+
|
|
336
|
+
- **Unity** — lightweight C assertion framework ([ThrowTheSwitch](https://github.com/ThrowTheSwitch/Unity))
|
|
337
|
+
- **CMock** — automated mocking for C functions (auto-generated via `vpl mock`)
|
|
338
|
+
- **pycparser** — C header parser for mock generation
|
|
339
|
+
|
|
340
|
+
### Assertion Macros
|
|
341
|
+
|
|
342
|
+
Unity provides rich assertions:
|
|
343
|
+
|
|
344
|
+
```c
|
|
345
|
+
// Basic checks
|
|
346
|
+
TEST_ASSERT_TRUE(condition)
|
|
347
|
+
TEST_ASSERT_FALSE(condition)
|
|
348
|
+
TEST_ASSERT_NULL(ptr)
|
|
349
|
+
TEST_ASSERT_NOT_NULL(ptr)
|
|
350
|
+
|
|
351
|
+
// Equality
|
|
352
|
+
TEST_ASSERT_EQUAL_INT(expected, actual)
|
|
353
|
+
TEST_ASSERT_EQUAL_UINT(expected, actual)
|
|
354
|
+
TEST_ASSERT_EQUAL_HEX(expected, actual)
|
|
355
|
+
TEST_ASSERT_EQUAL_STRING(expected, actual)
|
|
356
|
+
|
|
357
|
+
// Arrays
|
|
358
|
+
TEST_ASSERT_EQUAL_INT_ARRAY(expected, actual, len)
|
|
359
|
+
TEST_ASSERT_EQUAL_MEMORY(expected, actual, len)
|
|
360
|
+
|
|
361
|
+
// Floating point
|
|
362
|
+
TEST_ASSERT_EQUAL_FLOAT(expected, actual, delta)
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
See [Unity documentation](https://github.com/ThrowTheSwitch/Unity/blob/master/docs/UnityAssertionsReference.md) for complete reference.
|
|
366
|
+
|
|
367
|
+
## Architecture
|
|
368
|
+
|
|
369
|
+
vyperling's pipeline flows through 8 independent modules, connected by dataclasses:
|
|
370
|
+
|
|
371
|
+
```
|
|
372
|
+
TestUnit ──→ CompileResult ──→ RunResult
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
| Module | Responsibility |
|
|
376
|
+
|--------|---|
|
|
377
|
+
| **config.py** | Load `forge.yml`, resolve paths, manage project settings |
|
|
378
|
+
| **toolchains.py** | Maintain toolchain registry (builtin + user-defined) |
|
|
379
|
+
| **discoverer.py** | Glob `test_*.c`, match source files, emit `TestUnit` list |
|
|
380
|
+
| **mockgen.py** | Parse headers with pycparser, generate mocks via Jinja2 |
|
|
381
|
+
| **compiler.py** | Invoke GCC with ThreadPoolExecutor, cache via `.forge_deps.json` |
|
|
382
|
+
| **runner.py** | Execute binaries natively or under QEMU/simavr, parse Unity output |
|
|
383
|
+
| **reporter.py** | Rich terminal tables + JUnit XML export |
|
|
384
|
+
| **coverage.py** | Generate gcov reports (native-only, best-effort) |
|
|
385
|
+
|
|
386
|
+
**Key invariant:** Each module emits structured output (dataclass) that the next consumes — no hidden state.
|
|
387
|
+
|
|
388
|
+
## Development
|
|
389
|
+
|
|
390
|
+
### Install for Development
|
|
391
|
+
|
|
392
|
+
```bash
|
|
393
|
+
git clone https://github.com/ericsonjoseph/vyperling.git
|
|
394
|
+
cd vyperling
|
|
395
|
+
pip install -e .
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
### Run Tests
|
|
399
|
+
|
|
400
|
+
```bash
|
|
401
|
+
# Full test suite (coverage on by default)
|
|
402
|
+
pytest
|
|
403
|
+
|
|
404
|
+
# Single test file
|
|
405
|
+
pytest tests/test_mockgen.py
|
|
406
|
+
|
|
407
|
+
# Single test by name
|
|
408
|
+
pytest -k test_cross_compile
|
|
409
|
+
|
|
410
|
+
# Disable coverage
|
|
411
|
+
pytest --no-cov
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
### Project Structure
|
|
415
|
+
|
|
416
|
+
- `vyperling/` — main library
|
|
417
|
+
- `cli.py` — Click entry point (commands: test, build, mock, clean, targets, new)
|
|
418
|
+
- `config.py` — forge.yml loader and config validation
|
|
419
|
+
- `toolchains.py` — Toolchain dataclass + registry
|
|
420
|
+
- `discoverer.py` — test file discovery
|
|
421
|
+
- `mockgen.py` — C header parsing + mock generation
|
|
422
|
+
- `compiler.py` — GCC invocation with caching and parallel jobs
|
|
423
|
+
- `runner.py` — test execution and Unity output parsing
|
|
424
|
+
- `reporter.py` — rich terminal output + JUnit export
|
|
425
|
+
- `coverage.py` — gcov/gcovr pipeline
|
|
426
|
+
- `scaffold.py` — project template generation
|
|
427
|
+
- `errors.py` — exception hierarchy
|
|
428
|
+
- `unity.py` — Unity C framework accessor
|
|
429
|
+
- `c/` — vendored C assets (Unity v2.6.1 + forge_mock)
|
|
430
|
+
- `templates/` — Jinja2 templates for mocks and scaffolding
|
|
431
|
+
- `tests/` — comprehensive Python test suite
|
|
432
|
+
- `DEVELOPMENT_PLAN.md` — implementation checklist (all 17 steps ✅)
|
|
433
|
+
|
|
434
|
+
## Dependencies
|
|
435
|
+
|
|
436
|
+
**Runtime:**
|
|
437
|
+
- `click>=8.0` — CLI framework
|
|
438
|
+
- `rich>=13.0` — terminal formatting
|
|
439
|
+
- `pyyaml>=6.0` — YAML config parsing
|
|
440
|
+
- `pycparser>=2.21` — C header parsing
|
|
441
|
+
- `jinja2>=3.0` — template engine
|
|
442
|
+
- `gcovr>=7.0` — coverage reporting
|
|
443
|
+
|
|
444
|
+
**Development:**
|
|
445
|
+
- `pytest>=7.0` — testing
|
|
446
|
+
- `pytest-cov>=4.0` — coverage measurement
|
|
447
|
+
|
|
448
|
+
## Known Limitations (v0.0.1)
|
|
449
|
+
|
|
450
|
+
- **Mock generation**: Skips variadic functions, function-pointer params, and incomplete struct-by-value params (warns during generation)
|
|
451
|
+
- **Coverage**: Native target only; requires GCC with `-fprofile-arcs -ftest-coverage` support
|
|
452
|
+
- **Emulation**: Timeout-based (default 30s per test binary)
|
|
453
|
+
|
|
454
|
+
## Roadmap
|
|
455
|
+
|
|
456
|
+
| Phase | Items |
|
|
457
|
+
|-------|-------|
|
|
458
|
+
| v0.1 | ✅ Core pipeline (discover → mock → compile → run → report) |
|
|
459
|
+
| v0.2 | 📋 Enhanced mock generation (variadic support, callbacks) |
|
|
460
|
+
| v0.3 | 📋 CI/CD integration templates (GitHub Actions, GitLab CI) |
|
|
461
|
+
| v0.4 | 📋 IDE integration (VS Code extension) |
|
|
462
|
+
|
|
463
|
+
## Contributing
|
|
464
|
+
|
|
465
|
+
Contributions welcome! Please:
|
|
466
|
+
|
|
467
|
+
1. Fork the repository
|
|
468
|
+
2. Create a feature branch (`git checkout -b feature/my-feature`)
|
|
469
|
+
3. Write tests for your changes
|
|
470
|
+
4. Run the full test suite (`pytest`)
|
|
471
|
+
5. Commit with conventional messages
|
|
472
|
+
6. Push and open a pull request
|
|
473
|
+
|
|
474
|
+
For major changes, please open an issue first to discuss.
|
|
475
|
+
|
|
476
|
+
## License
|
|
477
|
+
|
|
478
|
+
MIT — see [LICENSE](LICENSE) file for details.
|
|
479
|
+
|
|
480
|
+
## Credits
|
|
481
|
+
|
|
482
|
+
- **vyperling** by [Ericson Joseph](https://github.com/ericsonjoseph)
|
|
483
|
+
- **Unity** testing framework by [ThrowTheSwitch](https://github.com/ThrowTheSwitch/Unity)
|
|
484
|
+
- **CMock** concepts adapted from [CMock](https://github.com/ThrowTheSwitch/CMock)
|
|
485
|
+
|
|
486
|
+
## Support
|
|
487
|
+
|
|
488
|
+
- 📖 [Architecture Documentation](vyperling-architecture.md)
|
|
489
|
+
- 🐛 [Issue Tracker](https://github.com/ericsonjoseph/vyperling/issues)
|
|
490
|
+
- 💬 [Discussions](https://github.com/ericsonjoseph/vyperling/discussions)
|
|
491
|
+
|