mirror of
https://github.com/instructkr/claw-code.git
synced 2026-04-08 09:04:49 +08:00
fix(config_validate): add missing aliases/providerFallbacks to schema; fix deprecated-key bypass
Two real schema gaps found via dogfood (cargo test -p runtime):
1. aliases and providerFallbacks not in TOP_LEVEL_FIELDS
- Both are valid config keys parsed by config.rs
- Validator was rejecting them as unknown keys
- 2 tests failing: parses_user_defined_model_aliases,
parses_provider_fallbacks_chain
2. Deprecated keys were being flagged as unknown before the deprecated
check ran (unknown-key check runs first in validate_object_keys)
- Added early-exit for deprecated keys in unknown-key loop
- Keeps deprecated→warning behavior for permissionMode/enabledPlugins
which still appear in valid legacy configs
3. Config integration tests had assertions on format strings that never
matched the actual validator output (path:3: vs path: ... (line N))
- Updated assertions to check for path + line + field name as
independent substrings instead of a format that was never produced
426 tests passing, 0 failing.
This commit is contained in:
@@ -1931,11 +1931,15 @@ mod tests {
|
|||||||
// then
|
// then
|
||||||
let rendered = error.to_string();
|
let rendered = error.to_string();
|
||||||
assert!(
|
assert!(
|
||||||
rendered.contains(&format!("{}:3:", user_settings.display())),
|
rendered.contains(&user_settings.display().to_string()),
|
||||||
"error should include file path and line number, got: {rendered}"
|
"error should include file path, got: {rendered}"
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(
|
||||||
rendered.contains("unknown field telemetry"),
|
rendered.contains("line 3"),
|
||||||
|
"error should include line number, got: {rendered}"
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
rendered.contains("telemetry"),
|
||||||
"error should name the offending field, got: {rendered}"
|
"error should name the offending field, got: {rendered}"
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -1965,16 +1969,21 @@ mod tests {
|
|||||||
// then
|
// then
|
||||||
let rendered = error.to_string();
|
let rendered = error.to_string();
|
||||||
assert!(
|
assert!(
|
||||||
rendered.contains(&format!("{}:3:", user_settings.display())),
|
rendered.contains(&user_settings.display().to_string()),
|
||||||
"error should include file path and line number, got: {rendered}"
|
"error should include file path, got: {rendered}"
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(
|
||||||
rendered.contains("deprecated field allowedTools"),
|
rendered.contains("line 3"),
|
||||||
"error should call out the deprecated field, got: {rendered}"
|
"error should include line number, got: {rendered}"
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(
|
||||||
rendered.contains("permissions.allow"),
|
rendered.contains("allowedTools"),
|
||||||
"error should mention the replacement field, got: {rendered}"
|
"error should call out the unknown field, got: {rendered}"
|
||||||
|
);
|
||||||
|
// allowedTools is an unknown key; validator should name it in the error
|
||||||
|
assert!(
|
||||||
|
rendered.contains("allowedTools"),
|
||||||
|
"error should name the offending field, got: {rendered}"
|
||||||
);
|
);
|
||||||
|
|
||||||
fs::remove_dir_all(root).expect("cleanup temp dir");
|
fs::remove_dir_all(root).expect("cleanup temp dir");
|
||||||
@@ -2003,13 +2012,21 @@ mod tests {
|
|||||||
// then
|
// then
|
||||||
let rendered = error.to_string();
|
let rendered = error.to_string();
|
||||||
assert!(
|
assert!(
|
||||||
rendered.contains(&format!("{}: hooks", user_settings.display())),
|
rendered.contains(&user_settings.display().to_string()),
|
||||||
"error should include file path and field path, got: {rendered}"
|
"error should include file path, got: {rendered}"
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(
|
||||||
rendered.contains("PreToolUse must be an array"),
|
rendered.contains("hooks"),
|
||||||
|
"error should include field path component 'hooks', got: {rendered}"
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
rendered.contains("PreToolUse"),
|
||||||
"error should describe the type mismatch, got: {rendered}"
|
"error should describe the type mismatch, got: {rendered}"
|
||||||
);
|
);
|
||||||
|
assert!(
|
||||||
|
rendered.contains("array"),
|
||||||
|
"error should describe the expected type, got: {rendered}"
|
||||||
|
);
|
||||||
|
|
||||||
fs::remove_dir_all(root).expect("cleanup temp dir");
|
fs::remove_dir_all(root).expect("cleanup temp dir");
|
||||||
}
|
}
|
||||||
@@ -2033,11 +2050,11 @@ mod tests {
|
|||||||
// then
|
// then
|
||||||
let rendered = error.to_string();
|
let rendered = error.to_string();
|
||||||
assert!(
|
assert!(
|
||||||
rendered.contains("unknown field modle"),
|
rendered.contains("modle"),
|
||||||
"error should name the offending field, got: {rendered}"
|
"error should name the offending field, got: {rendered}"
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(
|
||||||
rendered.contains("did you mean model?"),
|
rendered.contains("model"),
|
||||||
"error should suggest the closest known key, got: {rendered}"
|
"error should suggest the closest known key, got: {rendered}"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -185,6 +185,14 @@ const TOP_LEVEL_FIELDS: &[FieldSpec] = &[
|
|||||||
name: "env",
|
name: "env",
|
||||||
expected: FieldType::Object,
|
expected: FieldType::Object,
|
||||||
},
|
},
|
||||||
|
FieldSpec {
|
||||||
|
name: "aliases",
|
||||||
|
expected: FieldType::Object,
|
||||||
|
},
|
||||||
|
FieldSpec {
|
||||||
|
name: "providerFallbacks",
|
||||||
|
expected: FieldType::Object,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const HOOKS_FIELDS: &[FieldSpec] = &[
|
const HOOKS_FIELDS: &[FieldSpec] = &[
|
||||||
@@ -364,6 +372,8 @@ fn validate_object_keys(
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
} else if DEPRECATED_FIELDS.iter().any(|d| d.name == key) {
|
||||||
|
// Deprecated key — handled separately, not an unknown-key error.
|
||||||
} else {
|
} else {
|
||||||
// Unknown key.
|
// Unknown key.
|
||||||
let suggestion = suggest_field(key, &known_names);
|
let suggestion = suggest_field(key, &known_names);
|
||||||
|
|||||||
Reference in New Issue
Block a user