Test configuration source evidence
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
# ConfigKit v1.1.0 adoption implementation plan
|
# ConfigKit v1.1.0 adoption implementation plan
|
||||||
|
|
||||||
Status: Stages 1–2 complete; Stages 3–6 are not started.
|
Status: Stages 1–3 complete; Stages 4–6 are not started.
|
||||||
|
|
||||||
This plan is for a Luna coding agent implementing the selected
|
This plan is for a Luna coding agent implementing the selected
|
||||||
[ConfigKit adoption target](configkit-v1.1.0.md). Follow Stage 1 through Stage 6
|
[ConfigKit adoption target](configkit-v1.1.0.md). Follow Stage 1 through Stage 6
|
||||||
@@ -148,6 +148,10 @@ source inventory, explanation, diagnostic, and outcome semantics are retained.
|
|||||||
|
|
||||||
## Stage 3: Update focused report and adapter coverage
|
## Stage 3: Update focused report and adapter coverage
|
||||||
|
|
||||||
|
**Completed.** Focused source tests cover the new text and YAML keys, native
|
||||||
|
main layer, ordered selections, empty lists, and nil/redacted evidence. The
|
||||||
|
offline `TestSources` suite passed with Go 1.27.0.
|
||||||
|
|
||||||
1. Extend `TestSourcesProjectNativeEvidenceInTextAndYAML` in `sources_test.go`
|
1. Extend `TestSourcesProjectNativeEvidenceInTextAndYAML` in `sources_test.go`
|
||||||
rather than building another report-test framework. Update fixtures and
|
rather than building another report-test framework. Update fixtures and
|
||||||
assertions to the new native fields and report keys. Check that legacy
|
assertions to the new native fields and report keys. Check that legacy
|
||||||
|
|||||||
@@ -34,7 +34,11 @@ func TestSourcesProjectNativeEvidenceInTextAndYAML(t *testing.T) {
|
|||||||
reader := &sourceInventory{values: []configkit.SourceInfo{
|
reader := &sourceInventory{values: []configkit.SourceInfo{
|
||||||
{
|
{
|
||||||
ID: "root", Label: "root source", Path: "root.yml",
|
ID: "root", Label: "root source", Path: "root.yml",
|
||||||
PlacementMode: configkit.PlacementModeMapping,
|
PlacementMode: configkit.PlacementModeMapping, Layer: configkit.LayerMain,
|
||||||
|
EmptyImportSelections: []configkit.EmptyImportSelection{
|
||||||
|
{Path: configkit.Keys("imports", "first"), Location: configkit.Location{SourceID: "root.yml", Line: 3, Column: 4}, Selector: configkit.ImportSelectorGlob},
|
||||||
|
{Path: configkit.Keys("imports", "second"), Location: configkit.Location{}, Selector: configkit.ImportSelectorPath},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "item", Label: "sequence item", Path: "item.yml",
|
ID: "item", Label: "sequence item", Path: "item.yml",
|
||||||
@@ -70,11 +74,13 @@ func TestSourcesProjectNativeEvidenceInTextAndYAML(t *testing.T) {
|
|||||||
var report struct {
|
var report struct {
|
||||||
Scope string `yaml:"scope"`
|
Scope string `yaml:"scope"`
|
||||||
Sources []struct {
|
Sources []struct {
|
||||||
ID string `yaml:"id"`
|
ID string `yaml:"id"`
|
||||||
Destination string `yaml:"destination"`
|
Destination string `yaml:"destination"`
|
||||||
Placement string `yaml:"placement"`
|
Placement string `yaml:"placement"`
|
||||||
DestinationUnresolved bool `yaml:"destination_unresolved"`
|
Layer string `yaml:"layer"`
|
||||||
VersionCheck *struct {
|
EmptyImportSelections []emptyImportSelectionDTO `yaml:"empty_import_selections"`
|
||||||
|
DestinationIsFallback bool `yaml:"destination_is_fallback"`
|
||||||
|
VersionEvidence *struct {
|
||||||
Path string `yaml:"path"`
|
Path string `yaml:"path"`
|
||||||
Version struct {
|
Version struct {
|
||||||
Present bool `yaml:"present"`
|
Present bool `yaml:"present"`
|
||||||
@@ -87,7 +93,7 @@ func TestSourcesProjectNativeEvidenceInTextAndYAML(t *testing.T) {
|
|||||||
Column int `yaml:"column"`
|
Column int `yaml:"column"`
|
||||||
} `yaml:"location"`
|
} `yaml:"location"`
|
||||||
Redacted bool `yaml:"redacted"`
|
Redacted bool `yaml:"redacted"`
|
||||||
} `yaml:"version_check"`
|
} `yaml:"version_evidence"`
|
||||||
} `yaml:"sources"`
|
} `yaml:"sources"`
|
||||||
}
|
}
|
||||||
if err := yaml.Unmarshal(yamlOutput.Bytes(), &report); err != nil {
|
if err := yaml.Unmarshal(yamlOutput.Bytes(), &report); err != nil {
|
||||||
@@ -99,21 +105,31 @@ func TestSourcesProjectNativeEvidenceInTextAndYAML(t *testing.T) {
|
|||||||
if got := []string{report.Sources[0].ID, report.Sources[1].ID, report.Sources[2].ID}; !reflect.DeepEqual(got, []string{"root", "item", "null"}) {
|
if got := []string{report.Sources[0].ID, report.Sources[1].ID, report.Sources[2].ID}; !reflect.DeepEqual(got, []string{"root", "item", "null"}) {
|
||||||
t.Fatalf("source order = %v", got)
|
t.Fatalf("source order = %v", got)
|
||||||
}
|
}
|
||||||
if root := report.Sources[0]; root.Destination != "" || root.Placement != "mapping" || root.DestinationUnresolved || root.VersionCheck != nil {
|
if root := report.Sources[0]; root.Destination != "" || root.Placement != "mapping" || root.DestinationIsFallback || root.VersionEvidence != nil || root.Layer != "main" {
|
||||||
t.Errorf("root source projection = %#v", root)
|
t.Errorf("root source projection = %#v", root)
|
||||||
}
|
}
|
||||||
|
wantSelections := []emptyImportSelectionDTO{
|
||||||
|
{Path: "/imports/first", Location: locationDTO{SourceID: "root.yml", Line: 3, Column: 4}, Selector: "glob"},
|
||||||
|
{Path: "/imports/second", Location: locationDTO{}, Selector: "path"},
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(report.Sources[0].EmptyImportSelections, wantSelections) || report.Sources[1].EmptyImportSelections == nil || len(report.Sources[1].EmptyImportSelections) != 0 {
|
||||||
|
t.Fatalf("import selections: %#v", report.Sources)
|
||||||
|
}
|
||||||
|
if strings.Contains(yamlOutput.String(), "destination_unresolved:") || strings.Contains(yamlOutput.String(), "version_check:") {
|
||||||
|
t.Fatal("legacy YAML keys present")
|
||||||
|
}
|
||||||
item := report.Sources[1]
|
item := report.Sources[1]
|
||||||
if item.Destination != "/services" || item.Placement != "sequence_item" || !item.DestinationUnresolved {
|
if item.Destination != "/services" || item.Placement != "sequence_item" || !item.DestinationIsFallback {
|
||||||
t.Errorf("sequence item projection = %#v", item)
|
t.Errorf("sequence item projection = %#v", item)
|
||||||
}
|
}
|
||||||
if check := item.VersionCheck; check == nil || check.Path != "/version" || !check.Version.Present || check.Version.Null || check.Version.Text != "v2" || check.Location == nil || check.Location.SourceID != "item.yml" || check.Location.Line != 4 || check.Location.Column != 2 || check.Redacted {
|
if check := item.VersionEvidence; check == nil || check.Path != "/version" || !check.Version.Present || check.Version.Null || check.Version.Text != "v2" || check.Location == nil || check.Location.SourceID != "item.yml" || check.Location.Line != 4 || check.Location.Column != 2 || check.Redacted {
|
||||||
t.Errorf("text version evidence projection = %#v", check)
|
t.Errorf("text version evidence projection = %#v", check)
|
||||||
}
|
}
|
||||||
nullSource := report.Sources[2]
|
nullSource := report.Sources[2]
|
||||||
if nullSource.Destination != "/other" || nullSource.Placement != "mapping" || nullSource.DestinationUnresolved {
|
if nullSource.Destination != "/other" || nullSource.Placement != "mapping" || nullSource.DestinationIsFallback {
|
||||||
t.Errorf("mapping projection = %#v", nullSource)
|
t.Errorf("mapping projection = %#v", nullSource)
|
||||||
}
|
}
|
||||||
if check := nullSource.VersionCheck; check == nil || check.Path != "/metadata/version" || !check.Version.Present || !check.Version.Null || check.Version.Text != "" || check.Location != nil || !check.Redacted {
|
if check := nullSource.VersionEvidence; check == nil || check.Path != "/metadata/version" || !check.Version.Present || !check.Version.Null || check.Version.Text != "" || check.Location != nil || !check.Redacted {
|
||||||
t.Errorf("null/redacted version evidence projection = %#v", check)
|
t.Errorf("null/redacted version evidence projection = %#v", check)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,9 +138,15 @@ func TestSourcesProjectNativeEvidenceInTextAndYAML(t *testing.T) {
|
|||||||
if outcome.Kind != commandkit.OutcomeSuccess || reader.calls != 2 {
|
if outcome.Kind != commandkit.OutcomeSuccess || reader.calls != 2 {
|
||||||
t.Fatalf("text source report outcome=%#v calls=%d", outcome, reader.calls)
|
t.Fatalf("text source report outcome=%#v calls=%d", outcome, reader.calls)
|
||||||
}
|
}
|
||||||
|
if strings.Contains(textOutput.String(), "destination_unresolved:") || strings.Contains(textOutput.String(), "version_check:") {
|
||||||
|
t.Fatal("legacy text keys present")
|
||||||
|
}
|
||||||
|
if strings.Index(textOutput.String(), `path: "/imports/first"`) > strings.Index(textOutput.String(), `path: "/imports/second"`) {
|
||||||
|
t.Fatal("import selection order changed")
|
||||||
|
}
|
||||||
for _, fragment := range []string{
|
for _, fragment := range []string{
|
||||||
`id: "root"`, `destination: ""`, `placement: "mapping"`, "destination_unresolved: false", "version_check: null",
|
`id: "root"`, `destination: ""`, `placement: "mapping"`, `layer: "main"`, "destination_is_fallback: false", "version_evidence: null", `path: "/imports/first"`, `location: {source_id: "root.yml", line: 3, column: 4}`, `selector: "glob"`, `path: "/imports/second"`, `location: {source_id: "", line: 0, column: 0}`, `selector: "path"`, "empty_import_selections: []",
|
||||||
`destination: "/services"`, `placement: "sequence_item"`, "destination_unresolved: true", `path: "/version"`, `text: "v2"`,
|
`destination: "/services"`, `placement: "sequence_item"`, "destination_is_fallback: true", `path: "/version"`, `text: "v2"`,
|
||||||
`destination: "/other"`, `path: "/metadata/version"`, "null: true", `text: ""`, "location: null", "redacted: true",
|
`destination: "/other"`, `path: "/metadata/version"`, "null: true", `text: ""`, "location: null", "redacted: true",
|
||||||
} {
|
} {
|
||||||
if !strings.Contains(textOutput.String(), fragment) {
|
if !strings.Contains(textOutput.String(), fragment) {
|
||||||
|
|||||||
Reference in New Issue
Block a user