Test quality analyzer — validates unit tests have sufficient complexity and boundary coverage (companion to knots)
Project description
knots-test-complexity
A Rust-based test quality analyzer for C projects that validates unit tests have sufficient complexity to thoroughly exercise source code.
Motivation
Traditional code coverage metrics (line, branch, function) can be misleading. A test can achieve 100% branch coverage with simple assertions while missing critical edge cases like:
- Overflow scenarios:
uint16_ttimer wrapping at 65535 - Boundary conditions: Off-by-one errors at array bounds
- State transitions: Complex state machines with temporal dependencies
- Error paths: Multiple error conditions not all tested
This tool enforces that tests have sufficient cyclomatic complexity to exercise all logical paths and boundary value testing to catch edge cases.
Philosophy
"A test with lower complexity than its source code is likely not testing all scenarios."
Example: The Overflow Bug
// Source: Cyclomatic Complexity = 2
uint16_t timer_ms = 0;
void periodic_1ms() {
timer_ms++; // Overflows at 65535!
}
bool is_timeout(uint16_t start_ms, uint16_t duration_ms) {
return (timer_ms - start_ms) >= duration_ms;
}
Traditional Coverage (100% line, 100% branch):
void test_timeout() {
timer_ms = 0;
TEST_ASSERT_TRUE(is_timeout(0, 100)); // Happy path
TEST_ASSERT_FALSE(is_timeout(0, 1)); // Boundary
}
// PASSES coverage but MISSES overflow bug!
Tool Enforcement - Would detect:
- Test complexity (2) barely meets source complexity (2)
- Missing boundary tests: 0, 65535, wrap-around scenarios
- Missing state variation: timer_ms at different values
Better Tests (Higher Complexity):
void test_timeout_boundaries() {
// Boundary: timer at 0
timer_ms = 0;
TEST_ASSERT_TRUE(is_timeout(0, 100));
// Boundary: timer near max
timer_ms = 65530;
TEST_ASSERT_TRUE(is_timeout(65520, 100));
// CRITICAL: Overflow scenario
timer_ms = 5; // Wrapped from 65535
TEST_ASSERT_TRUE(is_timeout(65530, 100)); // Catches overflow!
// Multiple start/duration combinations
for (int i = 0; i < 5; i++) {
test_scenario(scenarios[i]);
}
}
// Higher complexity test catches the bug!
Features
Core Metrics
-
Test-to-Source Complexity Ratio
- Aggregate cyclomatic complexity of all test functions
- Compare to aggregate complexity of source functions
- Default threshold: 70% (configurable)
-
Boundary Value Detection
- Detects integer types:
uint8_t,uint16_t,uint32_t,int8_t, etc. - Identifies range checks:
if (x > MAX),if (x < MIN) - Counts required boundary tests
- Validates tests cover: MIN, MIN-1, MAX, MAX+1
- Detects integer types:
-
State Variable Tracking (Future Enhancement)
- Identifies
static,volatile, and global variables - Requires multiple test scenarios per state variable
- Validates state transitions are tested
- Identifies
Output Modes
- Warning Mode (default): Reports violations but doesn't fail pre-commit
- Error Mode: Fails pre-commit on violations
- Verbose Mode: Shows detailed per-function complexity breakdown
Building
cargo build --release --workspace
The binary will be at target/release/knots-test-complexity
Installation
From Source
cd knots
cargo build --release --workspace
# Binary is at target/release/knots-test-complexity
Add to your PATH or copy to a location in your PATH.
Pre-Commit Integration
Add to your project's .pre-commit-config.yaml:
repos:
- repo: https://github.com/brandon-arrendondo/knots
rev: v0.3.0 # Use specific version tag
hooks:
- id: test-complexity
args:
- --threshold=0.70
- --boundary-threshold=0.80
- --level=warn
- --framework=ceedling
- --test-dir=Test
Configuration Options:
--threshold=0.70: Minimum test-to-source complexity ratio (default: 0.70 = 70%)--level=warn: Enforcement level (warnorerror, default:warn)--no-check-boundaries: Disable boundary value detection (enabled by default)--verbose: Show detailed per-file analysis
Example: Strict Enforcement
args:
- --threshold=0.80
- --level=error
- --verbose
Example: Warning Only (No Boundaries)
args:
- --threshold=0.70
- --level=warn
- --no-check-boundaries
Usage
Command Line
Analyze a test file and its corresponding source:
knots-test-complexity Test/test_battery_service.c Core/Src/modules/battery_service/battery_service.c
With verbose output:
knots-test-complexity -v Test/test_battery_service.c Core/Src/modules/battery_service/battery_service.c
With custom thresholds:
knots-test-complexity \
--threshold=0.70 \
--boundary-threshold=0.80 \
--level=error \
Test/test_timer.c Core/Src/timer.c
Output Example
Analyzing Test Quality: test_battery_service.c
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Source File: battery_service.c
Functions: 15
Total Cyclomatic Complexity: 87
Boundary Values Detected: 12
- uint8_t variables: 4 (boundaries: 0, 255)
- Range checks: 8 (if (x > MAX), etc.)
Test File: test_battery_service.c
Functions: 58
Total Cyclomatic Complexity: 74
Boundary Tests Found: 15
Complexity Analysis:
Test/Source Ratio: 85% ✓ (threshold: 70%)
Test Complexity: 74
Source Complexity: 87
Ratio: 74/87 = 0.85
Boundary Analysis:
Required Boundary Tests: 12
Found Boundary Tests: 15 ✓
Coverage: 125%
Result: ✓ PASS
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Failure Example
Analyzing Test Quality: test_lin_comm_service.c
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Source File: lin_comm_service.c
Functions: 8
Total Cyclomatic Complexity: 54
Boundary Values Detected: 8
Test File: test_lin_comm_service.c
Functions: 12
Total Cyclomatic Complexity: 28
Boundary Tests Found: 3
Complexity Analysis:
Test/Source Ratio: 52% ✗ (threshold: 70%)
Test Complexity: 28
Source Complexity: 54
Ratio: 28/54 = 0.52
Boundary Analysis:
Required Boundary Tests: 8
Found Boundary Tests: 3 ✗
Missing Boundaries:
- rxByteCounter: 0, 3, 11, 12 (RX_HEADER_SIZE boundaries)
- rxFrameId: 0, 0x3F (FRAME_MASK boundary)
Recommendations:
1. Add tests for edge cases and error paths
2. Test boundary conditions: 0, max values, overflow
3. Add state transition tests (4 static variables detected)
4. Consider parametrized tests or loops in test code
Result: ✗ FAIL (--level=error)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Algorithm Details
1. Complexity Ratio Calculation
For each test file:
1. Parse test file with tree-sitter-c
2. Calculate cyclomatic complexity for all test functions
- Count: if, while, for, switch, &&, ||, ?:
- Include test helper functions
3. Sum total test complexity
4. Find corresponding source file
5. Calculate cyclomatic complexity for all source functions
6. Sum total source complexity
7. Calculate ratio = test_complexity / source_complexity
8. Compare ratio >= threshold (default 70%)
9. Report: PASS or FAIL with recommendations
2. Boundary Value Detection
For source file:
1. Find all integer type declarations
- uint8_t → boundaries: 0, 255
- uint16_t → boundaries: 0, 65535
- int8_t → boundaries: -128, 127
2. Find all range checks
- if (x > MAX) → test MAX, MAX+1
- if (x < MIN) → test MIN-1, MIN
- if (x >= threshold) → test threshold-1, threshold
3. Count required boundary tests
For test file:
1. Find all numeric literals in assertions
2. Match literals to source boundaries
3. Count covered boundaries
4. Report: boundary_coverage = found / required
5. Warn if coverage < 100%
3. Test Helper Function Handling
Test helpers ARE included in complexity calculation:
// Helper complexity counts!
void simulate_frame(uint8_t id) {
setup_mocks();
if (id == SPECIAL) { // +1 complexity
special_handling();
}
verify_results();
}
// Test also counts
void test_multiple_frames() {
for (int i = 0; i < 10; i++) { // +1 complexity
simulate_frame(i); // Helper complexity included
}
}
// Total test complexity = 2 (loop + helper's if)
This encourages well-structured tests with reusable helpers.
Integration with knots
knots-test-complexity complements knots:
| Tool | Purpose | Applied To | Metric |
|---|---|---|---|
| knots | Source code quality | Production code (.c, .h) |
McCabe & Cognitive complexity per function |
| knots-test-complexity | Test quality | Test code (test_*.c) |
Aggregate complexity ratio & boundary coverage |
Example Combined Workflow:
- repo: local
hooks:
# Check source code complexity (per-function limits)
- id: knots
name: Code Complexity Check
entry: hooks/pre-commit-wrapper.sh
language: script
files: \.(c|h)$
exclude: ^Test/
args: [--mccabe-threshold=15, --cognitive-threshold=15]
# Check test quality (aggregate complexity ratio)
- id: test-complexity
name: Test Quality Check
entry: hooks/test-complexity-wrapper.sh
language: script
files: ^Test/test_.*\.c$
args: [--threshold=70, --level=warn]
Future: Unified Tool
A future enhancement could merge both tools:
# Unified complexity tool
complexity-check --source <file.c> --test <test_file.c>
--source-mccabe-max=15
--source-cognitive-max=15
--test-ratio-min=0.70
--check-boundaries
Dependencies
[dependencies]
tree-sitter = "0.22"
tree-sitter-c = "0.21"
anyhow = "1.0"
clap = { version = "4.5", features = ["derive"] }
regex = "1.10"
Project Structure
knots-test-complexity/
├── Cargo.toml # Rust project manifest
├── README.md # This file
├── src/
│ ├── main.rs # CLI entry point
│ ├── analyzer.rs # Test quality analyzer
│ ├── boundary.rs # Boundary value detector
│ └── reporter.rs # Output formatting
└── examples/
├── test_timer_good.c # Example: sufficient complexity
├── test_timer_bad.c # Example: insufficient complexity
└── README.md # Example documentation
Testing
Run the test suite:
cargo test
Run with verbose output:
cargo test -- --nocapture
License
MIT License. See LICENSE file.
See Also
- knots: Source code complexity analyzer
- pmccabe: Industry-standard McCabe complexity tool (validation reference)
- Cognitive Complexity: SonarSource specification
- Mutation Testing: Alternative approach for test quality (future consideration)
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file knots_test_complexity-1.12.0.tar.gz.
File metadata
- Download URL: knots_test_complexity-1.12.0.tar.gz
- Upload date:
- Size: 169.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3c4e7fad99b44e12aa33a37bb64bb303013fabedb9edca545c2162cf9e31eef4
|
|
| MD5 |
44bd2154088540b580a36210c2be5aad
|
|
| BLAKE2b-256 |
a27ec02a502119d620d028c8f8e9d0cc5d825514ce8d40d7e8157d020cbc219c
|
Provenance
The following attestation bundles were made for knots_test_complexity-1.12.0.tar.gz:
Publisher:
wheels.yml on brandon-arrendondo/knots
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
knots_test_complexity-1.12.0.tar.gz -
Subject digest:
3c4e7fad99b44e12aa33a37bb64bb303013fabedb9edca545c2162cf9e31eef4 - Sigstore transparency entry: 1983514287
- Sigstore integration time:
-
Permalink:
brandon-arrendondo/knots@d6871d437a4e5b1d1c703f5bf4ed9c5db8fbcc1a -
Branch / Tag:
refs/tags/v1.12.0 - Owner: https://github.com/brandon-arrendondo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
wheels.yml@d6871d437a4e5b1d1c703f5bf4ed9c5db8fbcc1a -
Trigger Event:
push
-
Statement type:
File details
Details for the file knots_test_complexity-1.12.0-py3-none-win_amd64.whl.
File metadata
- Download URL: knots_test_complexity-1.12.0-py3-none-win_amd64.whl
- Upload date:
- Size: 1.9 MB
- Tags: Python 3, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a154711f2e403fe05b158fe439e02c04991b43f42ff05efed25442cd72ca613c
|
|
| MD5 |
6da258c0d2b23db381ec4efaeadb55a0
|
|
| BLAKE2b-256 |
a407d21582d9ea80debfe2159087b5a6ab2c650257b1e3c08228b242277b2f11
|
Provenance
The following attestation bundles were made for knots_test_complexity-1.12.0-py3-none-win_amd64.whl:
Publisher:
wheels.yml on brandon-arrendondo/knots
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
knots_test_complexity-1.12.0-py3-none-win_amd64.whl -
Subject digest:
a154711f2e403fe05b158fe439e02c04991b43f42ff05efed25442cd72ca613c - Sigstore transparency entry: 1983516124
- Sigstore integration time:
-
Permalink:
brandon-arrendondo/knots@d6871d437a4e5b1d1c703f5bf4ed9c5db8fbcc1a -
Branch / Tag:
refs/tags/v1.12.0 - Owner: https://github.com/brandon-arrendondo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
wheels.yml@d6871d437a4e5b1d1c703f5bf4ed9c5db8fbcc1a -
Trigger Event:
push
-
Statement type:
File details
Details for the file knots_test_complexity-1.12.0-py3-none-musllinux_1_2_x86_64.whl.
File metadata
- Download URL: knots_test_complexity-1.12.0-py3-none-musllinux_1_2_x86_64.whl
- Upload date:
- Size: 2.3 MB
- Tags: Python 3, musllinux: musl 1.2+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e41ce31ffcfb580529956741f00ebd759f5d0dec425dc4dbc288addefed995be
|
|
| MD5 |
092bd3b1f43c09e51a9cebcd304b866a
|
|
| BLAKE2b-256 |
9ee1326040f3237ac866c25334494e5359e2d45850a72254b9f78ca077b82e1c
|
Provenance
The following attestation bundles were made for knots_test_complexity-1.12.0-py3-none-musllinux_1_2_x86_64.whl:
Publisher:
wheels.yml on brandon-arrendondo/knots
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
knots_test_complexity-1.12.0-py3-none-musllinux_1_2_x86_64.whl -
Subject digest:
e41ce31ffcfb580529956741f00ebd759f5d0dec425dc4dbc288addefed995be - Sigstore transparency entry: 1983515953
- Sigstore integration time:
-
Permalink:
brandon-arrendondo/knots@d6871d437a4e5b1d1c703f5bf4ed9c5db8fbcc1a -
Branch / Tag:
refs/tags/v1.12.0 - Owner: https://github.com/brandon-arrendondo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
wheels.yml@d6871d437a4e5b1d1c703f5bf4ed9c5db8fbcc1a -
Trigger Event:
push
-
Statement type:
File details
Details for the file knots_test_complexity-1.12.0-py3-none-musllinux_1_2_aarch64.whl.
File metadata
- Download URL: knots_test_complexity-1.12.0-py3-none-musllinux_1_2_aarch64.whl
- Upload date:
- Size: 2.2 MB
- Tags: Python 3, musllinux: musl 1.2+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
05f4b2e74b130263c3d8f3d12f98747ec571f3041c6eed9ce7da4441eeffbb24
|
|
| MD5 |
59e3a965b4c45e59ae2969cce6a54674
|
|
| BLAKE2b-256 |
6e6b4909d63152413066f6d3ea168cfdbfa49241a93e1d3fef7df2a2a310189f
|
Provenance
The following attestation bundles were made for knots_test_complexity-1.12.0-py3-none-musllinux_1_2_aarch64.whl:
Publisher:
wheels.yml on brandon-arrendondo/knots
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
knots_test_complexity-1.12.0-py3-none-musllinux_1_2_aarch64.whl -
Subject digest:
05f4b2e74b130263c3d8f3d12f98747ec571f3041c6eed9ce7da4441eeffbb24 - Sigstore transparency entry: 1983515674
- Sigstore integration time:
-
Permalink:
brandon-arrendondo/knots@d6871d437a4e5b1d1c703f5bf4ed9c5db8fbcc1a -
Branch / Tag:
refs/tags/v1.12.0 - Owner: https://github.com/brandon-arrendondo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
wheels.yml@d6871d437a4e5b1d1c703f5bf4ed9c5db8fbcc1a -
Trigger Event:
push
-
Statement type:
File details
Details for the file knots_test_complexity-1.12.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: knots_test_complexity-1.12.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 2.2 MB
- Tags: Python 3, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d8b3372615be9aa9143d5626be9a02c3f60677752f40407f886fa2839e9c2088
|
|
| MD5 |
37dcf26b6dd98935daf02db53e674dd4
|
|
| BLAKE2b-256 |
c8d9375b87e3adcfdd893972dc676ba16bb858dc4c78bc049bd5735980400f66
|
Provenance
The following attestation bundles were made for knots_test_complexity-1.12.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
wheels.yml on brandon-arrendondo/knots
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
knots_test_complexity-1.12.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
d8b3372615be9aa9143d5626be9a02c3f60677752f40407f886fa2839e9c2088 - Sigstore transparency entry: 1983516476
- Sigstore integration time:
-
Permalink:
brandon-arrendondo/knots@d6871d437a4e5b1d1c703f5bf4ed9c5db8fbcc1a -
Branch / Tag:
refs/tags/v1.12.0 - Owner: https://github.com/brandon-arrendondo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
wheels.yml@d6871d437a4e5b1d1c703f5bf4ed9c5db8fbcc1a -
Trigger Event:
push
-
Statement type:
File details
Details for the file knots_test_complexity-1.12.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: knots_test_complexity-1.12.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 2.2 MB
- Tags: Python 3, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b596e4b7c3cce903eaf1bd3208034c93630679260f2f3aa488b1b77a5e98f992
|
|
| MD5 |
2db93d8d070a45bb16190757aaf6dda5
|
|
| BLAKE2b-256 |
3ab59bfd3a51c961ec6397293ad081ec2440081e57758f2092b6e7bea915c1af
|
Provenance
The following attestation bundles were made for knots_test_complexity-1.12.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:
Publisher:
wheels.yml on brandon-arrendondo/knots
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
knots_test_complexity-1.12.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl -
Subject digest:
b596e4b7c3cce903eaf1bd3208034c93630679260f2f3aa488b1b77a5e98f992 - Sigstore transparency entry: 1983514794
- Sigstore integration time:
-
Permalink:
brandon-arrendondo/knots@d6871d437a4e5b1d1c703f5bf4ed9c5db8fbcc1a -
Branch / Tag:
refs/tags/v1.12.0 - Owner: https://github.com/brandon-arrendondo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
wheels.yml@d6871d437a4e5b1d1c703f5bf4ed9c5db8fbcc1a -
Trigger Event:
push
-
Statement type:
File details
Details for the file knots_test_complexity-1.12.0-py3-none-macosx_11_0_arm64.whl.
File metadata
- Download URL: knots_test_complexity-1.12.0-py3-none-macosx_11_0_arm64.whl
- Upload date:
- Size: 2.1 MB
- Tags: Python 3, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b50b114a5739d83f37deee3757504144e93e21e8f0b7f9aaa0b7879491e2be28
|
|
| MD5 |
ff7dcaa4be8a3637faadb325050faf91
|
|
| BLAKE2b-256 |
12c391bb62f3e3271118d3ff145fd569c1723e60cc88ecb8ee8a26bafc6ae190
|
Provenance
The following attestation bundles were made for knots_test_complexity-1.12.0-py3-none-macosx_11_0_arm64.whl:
Publisher:
wheels.yml on brandon-arrendondo/knots
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
knots_test_complexity-1.12.0-py3-none-macosx_11_0_arm64.whl -
Subject digest:
b50b114a5739d83f37deee3757504144e93e21e8f0b7f9aaa0b7879491e2be28 - Sigstore transparency entry: 1983516306
- Sigstore integration time:
-
Permalink:
brandon-arrendondo/knots@d6871d437a4e5b1d1c703f5bf4ed9c5db8fbcc1a -
Branch / Tag:
refs/tags/v1.12.0 - Owner: https://github.com/brandon-arrendondo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
wheels.yml@d6871d437a4e5b1d1c703f5bf4ed9c5db8fbcc1a -
Trigger Event:
push
-
Statement type:
File details
Details for the file knots_test_complexity-1.12.0-py3-none-macosx_10_12_x86_64.whl.
File metadata
- Download URL: knots_test_complexity-1.12.0-py3-none-macosx_10_12_x86_64.whl
- Upload date:
- Size: 2.1 MB
- Tags: Python 3, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
678418ebf5fcc9be89578df187f288cd0d86fc8365d52b1aa94c173beb63e94b
|
|
| MD5 |
41c08f2e2dbec7c37c654e0bc00bb79f
|
|
| BLAKE2b-256 |
3d97fbfb5e795be2c8e750d50c63c11b379123abd5c7e6e1e29a8de9482a8d9c
|
Provenance
The following attestation bundles were made for knots_test_complexity-1.12.0-py3-none-macosx_10_12_x86_64.whl:
Publisher:
wheels.yml on brandon-arrendondo/knots
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
knots_test_complexity-1.12.0-py3-none-macosx_10_12_x86_64.whl -
Subject digest:
678418ebf5fcc9be89578df187f288cd0d86fc8365d52b1aa94c173beb63e94b - Sigstore transparency entry: 1983514386
- Sigstore integration time:
-
Permalink:
brandon-arrendondo/knots@d6871d437a4e5b1d1c703f5bf4ed9c5db8fbcc1a -
Branch / Tag:
refs/tags/v1.12.0 - Owner: https://github.com/brandon-arrendondo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
wheels.yml@d6871d437a4e5b1d1c703f5bf4ed9c5db8fbcc1a -
Trigger Event:
push
-
Statement type: