Skip to content

Commit 4fb24aa

Browse files
committed
test: add integration tests for version --schema
1 parent 8c9dd5e commit 4fb24aa

File tree

7 files changed

+1141
-8
lines changed

7 files changed

+1141
-8
lines changed

.dev/27-integration-tests-revamp-plan.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -141,13 +141,14 @@ tests/integration_tests/version/
141141
- ✅ Refactored tests to use `rstest` for cleaner parameterized testing
142142
- ✅ Enhanced `ZervFixture.with_vcs_data()` to accept `Option` types for better flexibility
143143
- ✅ Implemented `formats.rs`: Comprehensive format conversion tests (30 tests)
144-
- **Result**: 37 tests passing (100% success rate) - 7 source tests + 30 format tests
145-
- **Performance**: Tests run in <0.7 seconds without Docker
144+
- ✅ Implemented `schemas.rs`: Comprehensive schema tests (31 tests)
145+
- **Result**: 82 tests passing (100% success rate) - 7 source tests + 30 format tests + 31 schema tests + 14 other tests
146+
- **Performance**: Tests run in <1.3 seconds without Docker
146147
147148
**Remaining MainConfig Tests:**
148149
149150
- ✅ `formats.rs`: Test `--input-format` (semver/pep440/auto) and `--output-format` (semver/pep440/zerv) combinations, format validation errors, error message consistency (✅ PASSED - 30 tests)
150-
- `schemas.rs`: Test `--schema` (tier1/tier2/tier3) and `--schema-ron` (custom RON schema) options
151+
- `schemas.rs`: Test `--schema` (zerv-standard/zerv-calver) and `--schema-ron` (custom RON schema) options (✅ PASSED - 31 tests)
151152
- ❌ `templates.rs`: Test `--output-template` with Handlebars template rendering
152153
- ❌ `directory.rs`: Test `-C` flag for changing working directory before execution
153154
- ❌ `combinations.rs`: Test MainConfig option combinations (format + schema, template + format, etc.)

CLAUDE.md

Lines changed: 284 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,281 @@ let prerelease = match &version_obj.pre {
9999

100100
**Bottom Line**: If you're about to write a comment, first try to make the code clearer. If the code can't be clearer, then add the comment.
101101

102+
### 🚨 ZERO TOLERANCE: Comment Violations
103+
104+
**ABSOLUTELY FORBIDDEN** - These patterns will be immediately rejected:
105+
106+
1. **Function name restatements**:
107+
108+
```rust
109+
// ❌ FORBIDDEN
110+
/// Converts VCS data to Zerv variables
111+
pub fn vcs_data_to_zerv_vars() { }
112+
113+
// ✅ INSTEAD: Make function name clear or remove comment entirely
114+
pub fn vcs_data_to_zerv_vars() { } // Name is self-explanatory
115+
```
116+
117+
2. **Obvious parameter documentation**:
118+
119+
```rust
120+
// ❌ FORBIDDEN
121+
/// Processes the version
122+
/// @param version: The version to process
123+
fn process_version(version: Version) { }
124+
```
125+
126+
3. **Section divider comments** - Use `mod` blocks instead:
127+
128+
```rust
129+
// ❌ FORBIDDEN
130+
// ============================================================================
131+
// Builder Pattern Methods
132+
// ============================================================================
133+
134+
// ✅ INSTEAD: Use module organization or no comments at all
135+
```
136+
137+
4. **Process step comments**:
138+
```rust
139+
// ❌ FORBIDDEN
140+
let result = calculate(); // Calculate the result
141+
return result; // Return the result
142+
```
143+
144+
**If you see these patterns during code review, REMOVE THEM IMMEDIATELY.**
145+
146+
---
147+
148+
## 🔒 Import Statement Policy
149+
150+
**MANDATORY: Always place `use` statements at the top of the file or module, never inside functions.**
151+
152+
### The Rule
153+
154+
All `use` statements must be declared at:
155+
156+
1. **Top of file** (preferred for most cases)
157+
2. **Top of test module** (for test-specific imports in `#[cfg(test)] mod tests { ... }`)
158+
159+
**NEVER** place `use` statements inside individual functions, even in tests.
160+
161+
### Why This Matters
162+
163+
1. **Readability** - All dependencies visible at a glance
164+
2. **Maintainability** - Easy to see what the file/module depends on
165+
3. **Rust Conventions** - Standard Rust style guidelines
166+
4. **IDE Support** - Better auto-imports and refactoring
167+
5. **Code Review** - Easier to spot unused or unnecessary imports
168+
169+
### Examples
170+
171+
```rust
172+
// ✅ GOOD - Imports at top of file
173+
use rstest::rstest;
174+
use zerv::test_utils::{ZervFixture, ZervSchemaFixture};
175+
use zerv::version::zerv::{Component, Var, ZervSchema};
176+
177+
#[test]
178+
fn test_something() {
179+
let schema = ZervSchema::new_with_precedence(
180+
vec![Component::Var(Var::Major)],
181+
vec![],
182+
vec![],
183+
PrecedenceOrder::default(),
184+
).unwrap();
185+
}
186+
187+
// ✅ GOOD - Test-specific imports at top of test module
188+
#[cfg(test)]
189+
mod tests {
190+
use super::*;
191+
use crate::test_utils::TestHelper;
192+
193+
#[test]
194+
fn test_helper_usage() {
195+
TestHelper::new();
196+
}
197+
}
198+
199+
// ❌ BAD - Imports inside function
200+
#[test]
201+
fn test_something() {
202+
use zerv::version::zerv::{Component, Var, ZervSchema}; // ❌ WRONG!
203+
use zerv::version::zerv::bump::precedence::PrecedenceOrder; // ❌ WRONG!
204+
205+
let schema = ZervSchema::new_with_precedence(
206+
vec![Component::Var(Var::Major)],
207+
vec![],
208+
vec![],
209+
PrecedenceOrder::default(),
210+
).unwrap();
211+
}
212+
213+
// ❌ BAD - Imports scattered throughout file
214+
fn function_a() {
215+
use some_crate::TypeA; // ❌ WRONG!
216+
// ...
217+
}
218+
219+
fn function_b() {
220+
use some_crate::TypeB; // ❌ WRONG!
221+
// ...
222+
}
223+
```
224+
225+
### Exception (Very Rare)
226+
227+
The only acceptable use of inline imports is when deliberately limiting scope to prevent naming conflicts:
228+
229+
```rust
230+
// ✅ ACCEPTABLE - Intentional scope limitation
231+
fn convert_format() {
232+
use external_crate::Format as ExternalFormat; // Avoids naming conflict with local Format
233+
// Use ExternalFormat here only
234+
}
235+
```
236+
237+
**If you see inline `use` statements during code review or refactoring, move them to the top of the file immediately.**
238+
239+
---
240+
241+
## 📦 Test Organization Policy
242+
243+
**MANDATORY: Use Rust modules for test organization, not comment-based grouping.**
244+
245+
### The Rule
246+
247+
When organizing tests into logical groups:
248+
249+
1. **Use `mod` blocks** for structural grouping
250+
2. **NEVER use comment dividers** like `// ============ Section Name ============`
251+
3. Each module should use `use super::*;` to import parent scope
252+
253+
**Benefits over comment-based grouping:**
254+
255+
- Rust enforces module boundaries
256+
- IDEs can collapse/expand modules
257+
- Test names include module path for clarity
258+
- Can add module-level helpers
259+
- Consistent with codebase patterns
260+
261+
### Test Organization Pattern
262+
263+
```rust
264+
// ✅ GOOD - Module-based organization
265+
use rstest::rstest;
266+
use crate::util::TestCommand;
267+
268+
mod feature_basic {
269+
use super::*;
270+
271+
#[test]
272+
fn test_something() { /* ... */ }
273+
274+
#[rstest]
275+
#[case::scenario_a("input", "expected")]
276+
fn test_parameterized(#[case] input: &str, #[case] expected: &str) { /* ... */ }
277+
}
278+
279+
mod feature_advanced {
280+
use super::*;
281+
282+
#[test]
283+
fn test_complex_behavior() { /* ... */ }
284+
285+
// Module-level helper function
286+
fn setup_complex_fixture() -> Fixture {
287+
// ...
288+
}
289+
}
290+
291+
mod feature_error_handling {
292+
use super::*;
293+
294+
#[test]
295+
fn test_error_case() { /* ... */ }
296+
}
297+
298+
// ❌ BAD - Comment-based grouping
299+
// ============================================================================
300+
// Feature Basic Tests
301+
// ============================================================================
302+
303+
#[test]
304+
fn test_something() { /* ... */ }
305+
306+
// ============================================================================
307+
// Feature Advanced Tests
308+
// ============================================================================
309+
310+
#[test]
311+
fn test_complex_behavior() { /* ... */ }
312+
```
313+
314+
### Real Example from Codebase
315+
316+
**Before (comment-based):**
317+
318+
```rust
319+
// ============================================================================
320+
// Schema Preset Tests - zerv-standard
321+
// ============================================================================
322+
323+
#[test]
324+
fn test_schema_standard_tier_1() { /* ... */ }
325+
326+
// ============================================================================
327+
// Schema Validation and Error Handling
328+
// ============================================================================
329+
330+
#[test]
331+
fn test_schema_unknown_preset_error() { /* ... */ }
332+
```
333+
334+
**After (module-based):**
335+
336+
```rust
337+
mod schema_preset_standard {
338+
use super::*;
339+
340+
#[test]
341+
fn test_schema_standard_tier_1() { /* ... */ }
342+
}
343+
344+
mod schema_validation {
345+
use super::*;
346+
347+
#[test]
348+
fn test_schema_unknown_preset_error() { /* ... */ }
349+
}
350+
```
351+
352+
**Test output includes module path:**
353+
354+
```
355+
test integration_tests::version::main::schemas::schema_preset_standard::test_schema_standard_tier_1 ... ok
356+
test integration_tests::version::main::schemas::schema_validation::test_schema_unknown_preset_error ... ok
357+
```
358+
359+
### When to Use Modules
360+
361+
Use module-based organization when:
362+
363+
- File has 3+ logical test groups
364+
- Tests naturally cluster by feature/behavior
365+
- Need to share setup code within a group
366+
- File exceeds ~200 lines
367+
368+
### Module Naming Conventions
369+
370+
- Use snake_case: `mod schema_preset_standard`
371+
- Be descriptive: `mod schema_validation` not `mod validation`
372+
- Match test function prefixes when possible
373+
- Keep names short but clear
374+
375+
**If you see comment-based test grouping during refactoring, convert it to module-based organization.**
376+
102377
---
103378

104379
## Essential Commands
@@ -670,13 +945,18 @@ Action: Run `make test_flaky` (5 iterations) to detect instability
670945
6.**Include detailed error context** in all error messages
671946
7.**NO useless comments** - only comment when code cannot explain itself
672947
8.**Check existing utilities** in `src/test_utils/` before creating new ones
948+
9.**Place `use` statements at top of file/module** - never inside functions
949+
10.**Use `mod` blocks for test organization** - not comment dividers
673950

674951
**NEVER do these:**
675952

676953
1. ❌ Use bare string literals for field/format/source names
677954
2. ❌ Use `unwrap()` or `expect()` in production code
678955
3. ❌ Add comments that just repeat function names or restate code
679-
4. ❌ Create Git fixtures without proper isolation
680-
5. ❌ Skip Docker test gating for Docker-dependent tests
681-
6. ❌ Write generic error messages without context
682-
7. ❌ Duplicate code instead of using existing utilities
956+
4. ❌ Write useless comments that restate what's already obvious from function/variable names
957+
5. ❌ Create Git fixtures without proper isolation
958+
6. ❌ Skip Docker test gating for Docker-dependent tests
959+
7. ❌ Write generic error messages without context
960+
8. ❌ Duplicate code instead of using existing utilities
961+
9. ❌ Place `use` statements inside functions (except rare naming conflict cases)
962+
10. ❌ Use comment dividers for test grouping (use `mod` blocks instead)

0 commit comments

Comments
 (0)