package configkit import ( "bytes" "reflect" "testing" ) func TestMetadataHistoricalPaths(t *testing.T) { t.Parallel() result, err := Load[map[string]any](Bytes("base", []byte("retired: {child: 1}\nshape: {'0': base}\n'a/b~': {'': 2}\n")), Options[map[string]any]{ Overrides: []Override{ {Path: Keys("retired"), Value: nil, Flag: "--retired"}, {Path: Keys("shape"), Value: []any{"replacement"}, Flag: "--shape"}, }, }) if err != nil { t.Fatal(err) } metadata := result.Metadata() paths := metadata.HistoricalPaths() var got []string for _, path := range paths { got = append(got, path.String()) if len(metadata.History(path)) == 0 { t.Fatalf("enumerated path %s has no history", path) } } want := []string{"", "/a~1b~0", "/a~1b~0/", "/retired", "/retired/child", "/shape", "/shape/0"} if !reflect.DeepEqual(got, want) { t.Fatalf("historical paths = %v, want %v", got, want) } if _, ok := metadata.Lookup(paths[4]); ok { t.Fatal("removed descendant remains effective") } if _, ok := metadata.Lookup(paths[6]); !ok { t.Fatal("enumerated numeric path cannot query the new sequence shape") } // Returned slices and nested paths must not alias retained metadata. paths[1].segments[0].key = "mutated" paths[2] = Keys("replacement") if again := metadata.HistoricalPaths(); again[1].String() != want[1] || again[2].String() != want[2] { t.Fatal("enumeration returned aliased paths") } if len((Metadata{}).HistoricalPaths()) != 0 { t.Fatal("zero metadata contains paths") } } func TestHistoricalPathsExposeHiddenBaseOwnershipWithoutResolvingBaseSecrets(t *testing.T) { t.Setenv("CONFIGKIT_HISTORY_UNUSED_PROD_KEY", "") t.Setenv("CONFIGKIT_HISTORY_TEST_KEY", "synthetic-test-key") type config struct { Credential *Secret `yaml:"credential"` Definitions map[string]map[string]string `yaml:"definitions"` } for _, credential := range []string{"CONFIGKIT_HISTORY_TEST_KEY", "null"} { t.Run(credential, func(t *testing.T) { dir := t.TempDir() root := writeImportFile(t, dir, "main.yml", "configkit:\n imports: [{path: first.yml}, {path: second.yml}]\ncredential: CONFIGKIT_HISTORY_UNUSED_PROD_KEY\n") writeImportFile(t, dir, "first.yml", "definitions: {recap: {prompt: recap}}\n") writeImportFile(t, dir, "second.yml", "definitions: {recap: {output: recap.md}}\n") writeImportFile(t, dir, "profiles/testing.yml", "definitions: null\ncredential: "+credential+"\n") result, err := Load[config](File(root), Options[config]{Imports: true, Profile: "testing"}) if err != nil { t.Fatal(err) } metadata := result.Metadata() found := false for _, path := range metadata.HistoricalPaths() { if path.String() != "/definitions/recap" { continue } found = true owners := map[string]bool{} for _, change := range metadata.History(path) { if change.Origin.Layer == LayerBase { for _, location := range change.Origin.Locations { owners[location.SourceID] = true } } } if len(owners) != 2 { t.Fatalf("hidden declaration owners = %v", owners) } } if !found { t.Fatal("hidden base declaration was not discoverable") } }) } } func TestMetadataQueriesReturnDetachedRecords(t *testing.T) { t.Parallel() path := Keys("service", "workers") metadata := Metadata{ effectivePaths: map[string]Path{path.String(): path}, historicalPaths: map[string][]Path{path.String(): {path}}, fields: map[string]FieldInfo{ path.String(): { Explicit: true, Origin: Origin{ Layer: LayerBase, Locations: []Location{{SourceID: "source-1", Line: 2, Column: 3}}, }, }, }, history: map[string][]Change{ path.String(): {{ Path: path, Origin: Origin{Layer: LayerResolution, Locations: []Location{{SourceID: "source-1"}}}, Previous: []Origin{{Layer: LayerDefault, Locations: []Location{{SourceID: "default"}}}}, Reasons: []string{"bounded worker count"}, Dependencies: []Path{Keys("limits")}, }}, }, } info, ok := metadata.Lookup(path) if !ok || !info.Explicit || !metadata.IsExplicit(path) { t.Fatalf("Lookup() = %#v, %v", info, ok) } info.Origin.Locations[0].SourceID = "mutated" again, _ := metadata.Lookup(path) if again.Origin.Locations[0].SourceID != "source-1" { t.Fatal("Lookup returned aliased locations") } history := metadata.History(path) history[0].Reasons[0] = "mutated" history[0].Previous[0].Locations[0].SourceID = "mutated" history[0].Dependencies[0].segments[0].key = "mutated" againHistory := metadata.History(path) if againHistory[0].Reasons[0] != "bounded worker count" || againHistory[0].Previous[0].Locations[0].SourceID != "default" || againHistory[0].Dependencies[0].String() != "/limits" { t.Fatal("History returned aliased nested records") } missing := Keys("missing") if _, ok := metadata.Lookup(missing); ok || metadata.IsExplicit(missing) || metadata.History(missing) != nil { t.Fatal("unknown path produced metadata") } if _, ok := metadata.Lookup(Path{}.Index(-1)); ok { t.Fatal("invalid path produced metadata") } } func TestQueriesRespectActualHistoricalAndEffectiveContainers(t *testing.T) { result, err := Load[map[string]any](Bytes("base", []byte("items: [1]\nm: {'0': 2}\nx: 3\nretired: {child: 4}\n")), Options[map[string]any]{Overrides: []Override{{Path: Keys("retired"), Value: "removed", Flag: "--retired"}}}) if err != nil { t.Fatal(err) } for _, path := range []Path{Keys("items", "0"), Keys("m").Index(0), Keys("x", "missing"), Keys("items").Index(8)} { if _, ok := result.Metadata().Lookup(path); ok { t.Fatalf("invalid lookup %s", path) } if result.Metadata().History(path) != nil { t.Fatalf("invalid history %s", path) } if _, ok := result.Explain(path); ok { t.Fatalf("invalid explanation %s", path) } var out bytes.Buffer if err := result.WriteExplanation(&out, path); err == nil || out.Len() != 0 { t.Fatalf("invalid path wrote output: %s", path) } } for _, pointer := range []string{"/items/0", "/m/0"} { path, _ := ParsePath(pointer) if _, ok := result.Metadata().Lookup(path); !ok { t.Fatal("parsed path lost lookup") } if _, ok := result.Explain(path); !ok { t.Fatal("parsed path lost explanation") } } retired := Keys("retired", "child") if _, ok := result.Metadata().Lookup(retired); ok { t.Fatal("removed path remains effective") } if len(result.Metadata().History(retired)) == 0 { t.Fatal("removed history missing") } x, ok := result.Explain(retired) if !ok || x.Effective.Present || len(x.History) == 0 { t.Fatal("removed explanation missing") } }