Testing Strategy
Relevant source files
The following files were used as context for generating this wiki page:
The testing strategy for the node-semver project is a multi-layered approach designed to ensure the integrity of semantic versioning logic, prevent Regular Expression Denial of Service (ReDoS) vulnerabilities, and maintain 100% code coverage. The strategy encompasses unit tests for core classes and functions, integration tests for complex string parsing, and automated CI/CD enforcement.
Sources: CONTRIBUTING.md:43-46, package.json:7-13, test/map.js:33-46
Test Infrastructure and Tooling
The project utilizes the tap (Test Anything Protocol) framework as its primary test runner and assertion library. Tests are structured to run automatically during the pull request process to validate bug fixes and new features.
Test Execution Commands
Testing is integrated into the npm lifecycle scripts:
| Command | Description |
|---|---|
npm test | Runs all tests using tap with a requirement for 100% coverage and a 30-second timeout. |
npm run snap | Executes tests and updates snapshots (if applicable). |
npm run lint | Runs linting checks (currently disabled or handled by template-oss). |
Sources: package.json:7-13, CONTRIBUTING.md:43-46
Coverage Enforcement
The project maintains a strict coverage policy. Every new feature or bug fix must include corresponding tests, and the test suite is configured to fail if code coverage drops below 100%. A coverage map is used to ensure that test files correctly correspond to the system files they are intended to cover.
Sources: CONTRIBUTING.md:46-48, test/map.js:33-46, package.json:8
Unit Testing Logic
Unit tests are categorized by the internal structure of the library, focusing on classes, standalone functions, and internal regular expressions.
Class Testing
Tests for core classes like SemVer, Range, and Comparator validate instantiation, property assignment (major, minor, patch, prerelease, build), and instance methods like .inc().
The diagram shows the logic flow for testing the SemVer class, including validation of internal state and error handling.
Sources: test/classes/semver.js:12-25, test/classes/semver.js:77-96
Function Testing
Standalone utility functions (e.g., parse, valid, inc, satisfies, compare) are tested against extensive fixture sets. These fixtures include:
- increments.js: Mapping versions and release types to expected results.
- comparisons.js: Defining expected order between version pairs.
- equality.js: Defining equivalent versions across loose and strict modes.
Sources: test/functions/inc.js:9-52, test/functions/compare.js:10-18, test/index.js:28-66
Security and Performance Testing
ReDoS Prevention
A critical component of the testing strategy is defending against ReDoS. The project uses "safe" regular expressions that avoid greedy whitespace (\s+ or \s*). Integration tests simulate malicious inputs with extremely large strings of whitespace or zeros to ensure parsing remains performant within the tap timeout limits.
This sequence illustrates how integration tests verify that the parser handles large inputs without triggering catastrophic backtracking.
Sources: test/integration/whitespace.js:13-23, test/internal/re.js:21-24, test/whitespace.js:13-36
Input Validation Limits
The test suite ensures that versions exceeding MAX_LENGTH (256 characters) or numeric segments exceeding MAX_SAFE_INTEGER are handled gracefully, typically by returning null or throwing a TypeError.
Sources: test/classes/semver.js:98-102, test/integration/whitespace.js:39-44
Integration and Regression Testing
Integration tests in test/index.js and test/integration/ verify the end-to-end flow of the library. They cover:
- Range Satisfaction: Validating if specific versions satisfy complex ranges (e.g.,
1.0.0 - 2.0.0,^1.2.3,~1.2.3). - Loose vs. Strict Modes: Testing how the library handles non-standard version strings (e.g.,
v1.2.3,01.02.03) depending on thelooseflag. - Prerelease Handling: Testing the
includePrereleaseoption and its effect on range matching.
Sources: test/index.js:120-192, test/index.js:304-320, test/classes/semver.js:175-248
Conclusion
The testing strategy of node-semver is centered on absolute correctness and security. By combining exhaustive unit tests based on semantic versioning fixtures with specific performance-focused integration tests, the project ensures that it remains a reliable foundation for the npm ecosystem. The requirement for 100% coverage and automated linting ensures that all contributions maintain the established quality standards.
Sources: CONTRIBUTING.md:43-51, package.json:7-10