Testing and CI
The project verifies equivalent behavior at two levels:
- one shared set of domain cases executed by every language-specific runner
- one process-level parity suite that compares observable command-line behavior across Java, C++ and Python
Shared contract cases
The file tests/cases.tsv is the language-neutral source of truth.
It contains seven valid and twenty-three invalid IPv4/CIDR examples. Valid cases define the complete expected result. Invalid cases define the exact validation category and message.
The contract covers:
- standard subnets
/0,/31and/32- surrounding ASCII whitespace
- malformed separators and octet counts
- empty and non-decimal values
- signs and internal whitespace
- leading zeros in octets and prefixes
- ordinary and oversized numeric ranges
- combined defects that verify validation priority
The oversized numeric cases prevent a parser difference: Java and C++ use fixed-width integers, while Python supports arbitrary-precision integers. Every implementation performs the same bounded decimal text comparison before conversion.
The combined-error cases verify that, after exactly one / separator is found, empty IPv4 and prefix components are checked before either component is parsed in detail.
Language-specific tests
| Language | Test runner | Contract scope | CLI smoke scope |
|---|---|---|---|
| Java 21 | java/test/SubnetCalculatorTest.java |
Executes the command-line program and checks all shared result fields, errors and exit codes | valid direct call, invalid direct call, help and incorrect usage |
| C++20 | cpp/tests/subnet_test.cpp with CTest |
Calls the calculation module and checks every structured result field and exception message | CMake script executes the built CLI for the same four modes |
| Python 3.12 | python/test_subnet_calculator.py |
Uses unittest for every shared calculation and validation case |
subprocess checks for the same four modes |
No external test framework is required.
Cross-language parity
tests/cross_language_parity.py executes the three real command-line implementations and records:
(return code, stdout bytes, stderr bytes)
The current parity suite contains nine direct cases and two interactive cases. It covers:
- empty-prefix priority when the IPv4 part is also invalid
- leading-zero prefixes
- a non-whitespace ASCII control character
- non-breaking space (
U+00A0) - ideographic space (
U+3000) - allowed ASCII tab and carriage-return trimming
- ASCII-trimmed interactive quit handling
- rejection of Unicode-space-wrapped quit text
On Linux, all nine direct cases and both interactive cases require complete byte-for-byte equality across Java, C++ and Python.
On Windows, all ASCII-safe direct cases and both interactive cases also require complete byte-for-byte equality. The two non-ASCII command-line argument cases are checked semantically per implementation: identical exit code, identical error category, empty standard output and the expected direct-mode format hint. This boundary is explicit because the Windows Java launcher may replace a command-line character that is not representable in its native launcher encoding before main(String[]) receives the argument.
The C++ executable uses a wide-character Windows entry point and converts command-line arguments to UTF-8. The parity-only Java launcher configures UTF-8 standard streams. Child-process streams are captured as bytes so the test harness does not impose an incorrect decoder on platform-native output.
A failed parity run writes parity-diagnostics.txt. GitHub Actions uploads that file as a temporary diagnostic artifact on Windows failures; successful runs remove it.
Local commands
Java
javac -d java/out java/src/SubnetCalculator.java java/test/SubnetCalculatorTest.java java/test/Utf8JavaLauncher.java
java -cp java/out SubnetCalculatorTest tests/cases.tsv
C++
cmake -S cpp -B cpp/build -DBUILD_TESTING=ON
cmake --build cpp/build --config Release
ctest --test-dir cpp/build --build-config Release --output-on-failure
Python
python -m unittest discover -s python -p "test_*.py" -v
Cross-language parity
After Java and C++ have been built:
python tests/cross_language_parity.py
On Windows, py -3.12 can replace python.
GitHub Actions
The workflow under .github/workflows/ci.yml runs on pull requests, pushes to main and manual dispatches.
It exposes five independent checks:
Java 21C++20Python 3.12Cross-language parityCross-language parity (Windows)
The workflow uses read-only repository permissions, cancels superseded runs and applies a ten-minute timeout to every job. Keeping the checks separate makes failures easy to locate and verifies both the Linux toolchain and the Windows execution boundary.