Skip to content
Documentation GitHub
Test Failures

Settings Struct Literal Tests Break When Domain Fields Are Added

Settings Struct Literal Tests Break When Domain Fields Are Added

Problem

Adding a new field to the domain Settings struct (e.g., mcp_enabled: bool) causes compilation failures in infrastructure tests that construct Settings using struct literal syntax instead of Default::default().

Symptoms:

  • cargo test fails with missing field 'mcp_enabled' in initializer of 'Settings'
  • Only tests in specific crates fail (e.g., infrastructure-json), not domain or application tests
  • Tests that use Settings::default() or ..Default::default() continue to pass

Investigation

Steps Tried

  1. Added mcp_enabled and mcp_port to domain Settings — domain tests passed (they use Settings::default())
  2. Ran cargo test — 4 tests failed in crates/infrastructure/json/src/settings_repository.rs
  3. Inspected failing tests — all constructed Settings via struct literal with every field specified
  4. Added missing fields — fixed immediately

Root Cause

The infrastructure tests were written using exhaustive struct literal construction:

let settings = Settings {
first_launch_completed: true,
user_persona: Some("novelist".to_string()),
analytics_enabled: true,
log_retention_days: 30,
schema_version: 4,
// ... every field listed explicitly
};

This pattern is fragile — any new field added to the struct requires updating every test that constructs it this way. In contrast, the struct update syntax (..Default::default()) absorbs new fields automatically.

Solution

Immediate Fix

Add the missing fields to all struct literals:

let settings = Settings {
first_launch_completed: true,
user_persona: Some("novelist".to_string()),
analytics_enabled: true,
log_retention_days: 30,
schema_version: 5,
mcp_enabled: false, // NEW
mcp_port: 7862, // NEW
};

Better Pattern (For New Tests)

Use struct update syntax to absorb future field additions:

// Resilient — new fields get defaults automatically
let settings = Settings {
first_launch_completed: true,
user_persona: Some("novelist".to_string()),
..Default::default()
};

When Full Struct Literals Are Appropriate

Full struct literals ARE the right choice when the test intentionally verifies serialization of ALL fields (e.g., round-trip tests). In these cases, the compile error is actually a helpful signal that the test needs updating for the new field.

Implementation Notes

  • The 4 affected tests in settings_repository.rs test serialization round-trips — they intentionally specify all fields to verify nothing is lost
  • For round-trip tests, the compile error is a FEATURE, not a bug — it forces you to decide what the new field’s serialized form should be
  • For setup/fixture tests that just need “some settings,” prefer ..Default::default()

Prevention

Best Practices

  • New tests: Use ..Default::default() unless you’re testing serialization of ALL fields
  • When adding Settings fields: Search for Settings { in the codebase to find all struct literal constructions — cargo test will catch them, but searching first saves a round-trip
  • Always add #[serde(default = "...")] on new Settings fields for backward-compatible deserialization of existing settings files
  • Bump SETTINGS_SCHEMA_VERSION when adding fields (helps track which version introduced which fields)

Warning Signs

  • Test constructs a domain entity with every field spelled out but isn’t testing serialization
  • Multiple tests in different files repeat the same full struct literal — suggests a test helper is needed
  • New domain field addition causes failures in distant infrastructure crates

Quick Search Command

Terminal window
# Find all Settings struct literal constructions
grep -rn "Settings {" crates/ --include="*.rs" | grep -v "Default\|default()\|//"

References

  • Commit: 7832ede — Fixed settings struct literals after adding mcp_enabled/mcp_port (INK-251)
  • Related: crates/domain/src/settings.rs — Settings entity with SETTINGS_SCHEMA_VERSION
  • Related: crates/infrastructure/json/src/settings_repository.rs — affected tests

Was this page helpful?