Migrate acquisition fixtures to document-root controls

This commit is contained in:
2026-11-02 00:40:16 +00:00
parent ad5b859337
commit 54bdc24865
20 changed files with 258 additions and 223 deletions

View File

@@ -171,6 +171,8 @@ affected fixtures have been migrated.
## Stage 5 — Migrate engine source and acquisition fixtures
**Status:** Complete. Focused acquisition, import, destination, and source tests pass; structural fixtures remain for the next stage.
**Scope:** remaining engine source/discovery/import/placement/resource-context
tests and acquisition-related benchmarks, excluding structural/history fixtures
assigned to Stage 6.

View File

@@ -72,7 +72,7 @@ func TestNestedItemGlobsShareUnderlayNodeBudget(t *testing.T) {
t.Parallel()
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", `configkit:
mainPath := writeImportFile(t, directory, "main.yml", `config:
imports:
- glob: children/*.yml
destination: [children]
@@ -132,7 +132,7 @@ func TestImportedEmptyBodiesChargeEachDestinationWrapper(t *testing.T) {
t.Parallel()
filesystem := NewFilesystem("bundle", fstest.MapFS{
"main.yml": &fstest.MapFile{Data: []byte("configkit: {imports: [{path: fragment.yml}]}\n")},
"main.yml": &fstest.MapFile{Data: []byte("config: {imports: [{path: fragment.yml}]}\n")},
"fragment.yml": &fstest.MapFile{Data: []byte("{}\n")},
})
mainSource := filesystem.File("main.yml")
@@ -186,7 +186,7 @@ func TestImportedEmptyBodiesChargeFullRelativeDestinations(t *testing.T) {
t.Parallel()
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", `configkit:
mainPath := writeImportFile(t, directory, "main.yml", `config:
imports:
- path: empty.yml
destination: [groups, empty]
@@ -248,7 +248,7 @@ func TestGlobMatchesChargeTheirSharedRelativeDestination(t *testing.T) {
t.Parallel()
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", `configkit:
mainPath := writeImportFile(t, directory, "main.yml", `config:
imports:
- glob: fragments/*.yml
destination: [groups, empty]
@@ -316,7 +316,7 @@ func TestRelativeImportDestinationUsesAccumulatedDocumentDepth(t *testing.T) {
t.Parallel()
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", "configkit: {imports: [{path: fragment.yml, destination: [extra]}]}\n")
mainPath := writeImportFile(t, directory, "main.yml", "config: {imports: [{path: fragment.yml, destination: [extra]}]}\n")
writeImportFile(t, directory, "fragment.yml", "value: nested\n")
destination := Path{segments: make([]pathSegment, maxDocumentDepth)}
for index := range destination.segments {
@@ -351,11 +351,11 @@ func TestAbsentOptionalImportsDoNotChargeUnusedDeepDestinations(t *testing.T) {
}{
{
name: "optional missing path",
body: "configkit: {imports: [{path: missing.yml, destination: [unused]}]}\n",
body: "config: {imports: [{path: missing.yml, destination: [unused]}]}\n",
},
{
name: "optional unmatched glob",
body: "configkit: {imports: [{glob: empty/*.yml, destination: [unused]}]}\n",
body: "config: {imports: [{glob: empty/*.yml, destination: [unused]}]}\n",
setup: func(t *testing.T, directory string) {
if err := os.Mkdir(filepath.Join(directory, "empty"), 0o755); err != nil {
t.Fatal(err)

View File

@@ -64,7 +64,7 @@ func TestLayeredDestinationDiagnosticsUseEffectivePathsAndAuthoredLocations(t *t
t.Run("imported version failure uses effective path and import source", func(t *testing.T) {
t.Parallel()
directory := t.TempDir()
writeImportFile(t, directory, "main.yml", "configkit: {imports: [{path: fragment.yml}]}\n")
writeImportFile(t, directory, "main.yml", "config: {imports: [{path: fragment.yml}]}\n")
writeImportFile(t, directory, "fragment.yml", "version: forbidden\n")
rule := &VersionRule{Path: Keys("application", "version"), Check: func(Version, *Validation) error { return nil }}
loaded, err := LoadLayered(
@@ -108,7 +108,7 @@ func TestLayeredDestinationDiagnosticsUseEffectivePathsAndAuthoredLocations(t *t
t.Run("malformed source directive keeps its local path and location", func(t *testing.T) {
t.Parallel()
filesystem := NewFilesystem("bundle", fstest.MapFS{
"main.yml": &fstest.MapFile{Data: []byte("configkit: {imports: [true]}\nvalue: present\n")},
"main.yml": &fstest.MapFile{Data: []byte("config: {imports: [true]}\nvalue: present\n")},
})
loaded, err := LoadLayered(
Input{Source: filesystem.File("main.yml"), Imports: true, Destination: Keys("application")},
@@ -119,7 +119,7 @@ func TestLayeredDestinationDiagnosticsUseEffectivePathsAndAuthoredLocations(t *t
t.Fatalf("malformed directive returned a result: %#v", loaded)
}
diagnostic := firstDestinationDiagnostic(t, err)
if diagnostic.Code != CodeImportInvalid || diagnostic.Path.String() != "/configkit/imports/0" {
if diagnostic.Code != CodeImportInvalid || diagnostic.Path.String() != "/config/imports/0" {
t.Fatalf("malformed directive diagnostic = %#v", diagnostic)
}
if diagnostic.Primary == nil || diagnostic.Primary.SourceID != "source-1" || diagnostic.Primary.Line != 1 {

View File

@@ -28,7 +28,7 @@ func TestRelativeImportsFeedFinalInheritanceAndInspectionLifecycle(t *testing.T)
load := func(dynamic string) *testResult[configuration] {
t.Helper()
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "entry.yml", `configkit:
mainPath := writeImportFile(t, directory, "entry.yml", `config:
imports:
- path: parent.yml
destination: [entries]
@@ -166,7 +166,7 @@ func TestRelativeImportMatchesWrappedPlacementAndSafeDiff(t *testing.T) {
options := LayeredOptions[map[string]any]{}
if relativeImport {
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", `configkit:
mainPath := writeImportFile(t, directory, "main.yml", `config:
imports:
- path: fragment.yml
destination: [application]

View File

@@ -13,17 +13,52 @@ type importDestinationConfig struct {
Collections map[string]map[string]string `yaml:"collections"`
}
func TestImportsKeepDocumentControlsBeforePlacement(t *testing.T) {
directory := t.TempDir()
main := writeImportFile(t, directory, "main.yml", "config: {imports: [{path: parent.yml, destination: [config]}]}\n")
parent := writeImportFile(t, directory, "parent.yml", "config: {imports: [{path: leaf.yml, destination: [config]}]}\nimports: ordinary\n")
leaf := writeImportFile(t, directory, "leaf.yml", "sequences: ordinary\n")
loaded, err := LoadLayered(Input{Source: File(main), Imports: true}, testSecretBinding(), LayeredOptions[map[string]any]{})
if err != nil {
t.Fatal(err)
}
root := loaded.Config["config"].(map[string]any)
if root["imports"] != "ordinary" || root["config"].(map[string]any)["sequences"] != "ordinary" {
t.Fatalf("assembled configuration = %#v", loaded.Config)
}
sources := testLoaded(loaded).Sources()
if len(sources) != 3 || sources[1].Path != canonicalTestPath(t, parent) || sources[1].Destination.String() != "/config" || sources[2].Path != canonicalTestPath(t, leaf) || sources[2].Destination.String() != "/config/config" || sources[2].ImportedFrom == nil {
t.Fatalf("sources = %#v", sources)
}
if info, ok := testLoaded(loaded).Metadata().Lookup(Keys("config", "config", "sequences")); !ok || len(info.Origin.Locations) == 0 || info.Origin.Locations[0].SourceID != sources[2].ID {
t.Fatalf("leaf attribution = %#v, %t", info, ok)
}
}
func TestImportsLeaveNestedConfigDataUntouched(t *testing.T) {
directory := t.TempDir()
main := writeImportFile(t, directory, "main.yml", "nested: {config: {imports: ordinary}}\n")
loaded, err := LoadLayered(Input{Source: File(main), Imports: true}, testSecretBinding(), LayeredOptions[map[string]any]{})
if err != nil {
t.Fatal(err)
}
nested := loaded.Config["nested"].(map[string]any)["config"].(map[string]any)
if nested["imports"] != "ordinary" {
t.Fatalf("nested data = %#v", nested)
}
}
func TestLayeredHostImportsInheritInputDestinationTransitively(t *testing.T) {
t.Parallel()
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", `configkit:
mainPath := writeImportFile(t, directory, "main.yml", `config:
imports:
- path: first.yml
- path: second.yml
root: main
`)
firstPath := writeImportFile(t, directory, "first.yml", `configkit:
firstPath := writeImportFile(t, directory, "first.yml", `config:
imports:
- path: nested/third.yml
first: one
@@ -52,7 +87,7 @@ first: one
t.Errorf("mounted[%q] = %q, want %q", key, result.Config.Mounted[key], value)
}
}
if _, ok := result.Metadata().Lookup(Keys("mounted", "configkit")); ok {
if _, ok := result.Metadata().Lookup(Keys("mounted", "config")); ok {
t.Fatal("source-root import directive leaked into application content")
}
sources := result.Sources()
@@ -77,13 +112,13 @@ func TestImportTraversalUsesPerDeclarationDestinations(t *testing.T) {
t.Parallel()
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", `configkit:
mainPath := writeImportFile(t, directory, "main.yml", `config:
imports:
- path: parent.yml
- path: sibling.yml
- glob: fragments/*.yml
`)
parentPath := writeImportFile(t, directory, "parent.yml", `configkit:
parentPath := writeImportFile(t, directory, "parent.yml", `config:
imports:
- path: nested/child.yml
parent: true
@@ -163,7 +198,7 @@ func TestEntryDestinationSurvivesImportSetupAndParseFailures(t *testing.T) {
t.Run("import context failure", func(t *testing.T) {
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", "configkit: {imports: [{path: child.yml}]}\n")
mainPath := writeImportFile(t, directory, "main.yml", "config: {imports: [{path: child.yml}]}\n")
input, diagnostics := testAcquireInput(inputAcquisitionRequest{
input: loadInput{source: File(mainPath), imports: true, filesystem: &FilesystemContext{Root: t.TempDir()}, destination: Keys("mounted")},
role: sourceVersionMain, directiveContext: rootDirectiveContextImportsOnly,
@@ -178,7 +213,7 @@ func TestEntryDestinationSurvivesImportSetupAndParseFailures(t *testing.T) {
t.Run("imported parse failure", func(t *testing.T) {
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", "configkit: {imports: [{path: broken.yml}]}\n")
mainPath := writeImportFile(t, directory, "main.yml", "config: {imports: [{path: broken.yml}]}\n")
writeImportFile(t, directory, "broken.yml", "broken: [\n")
input, diagnostics := testAcquireInput(inputAcquisitionRequest{
input: loadInput{source: File(mainPath), imports: true, destination: Keys("mounted")},
@@ -211,39 +246,39 @@ func TestRelativeImportDestinationsKeepStrictCompositionBoundaries(t *testing.T)
}{
{
name: "disjoint peers at one destination",
main: "configkit:\n imports:\n - path: left.yml\n destination: [application]\n - path: right.yml\n destination: [application]\n",
main: "config:\n imports:\n - path: left.yml\n destination: [application]\n - path: right.yml\n destination: [application]\n",
files: map[string]string{"left.yml": "left: one\n", "right.yml": "right: two\n"},
want: map[string]any{"/application/left": "one", "/application/right": "two"},
},
{
name: "different destinations",
main: "configkit:\n imports:\n - path: left.yml\n destination: [left]\n - path: right.yml\n destination: [right]\n",
main: "config:\n imports:\n - path: left.yml\n destination: [left]\n - path: right.yml\n destination: [right]\n",
files: map[string]string{"left.yml": "value: shared\n", "right.yml": "value: shared\n"},
want: map[string]any{"/left/value": "shared", "/right/value": "shared"},
},
{
name: "ancestor and descendant overlap",
main: "configkit:\n imports:\n - path: parent.yml\n destination: [application]\n - path: child.yml\n destination: [application, branch]\n",
main: "config:\n imports:\n - path: parent.yml\n destination: [application]\n - path: child.yml\n destination: [application, branch]\n",
files: map[string]string{"parent.yml": "branch: {base: one}\n", "child.yml": "leaf: two\n"},
want: map[string]any{"/application/branch/base": "one", "/application/branch/leaf": "two"},
},
{
name: "collision with explicitly wrapped content",
main: "configkit: {imports: [{path: fragment.yml, destination: [application]}]}\napplication: {value: root}\n",
main: "config: {imports: [{path: fragment.yml, destination: [application]}]}\napplication: {value: root}\n",
files: map[string]string{"fragment.yml": "value: imported\n"},
conflict: true,
wantPath: "/application/value",
},
{
name: "equal peer values conflict",
main: "configkit:\n imports:\n - path: left.yml\n destination: [application]\n - path: right.yml\n destination: [application]\n",
main: "config:\n imports:\n - path: left.yml\n destination: [application]\n - path: right.yml\n destination: [application]\n",
files: map[string]string{"left.yml": "value: same\n", "right.yml": "value: same\n"},
conflict: true,
wantPath: "/application/value",
},
{
name: "unequal peer values conflict",
main: "configkit:\n imports:\n - path: left.yml\n destination: [application]\n - path: right.yml\n destination: [application]\n",
main: "config:\n imports:\n - path: left.yml\n destination: [application]\n - path: right.yml\n destination: [application]\n",
files: map[string]string{"left.yml": "value: left\n", "right.yml": "value: right\n"},
conflict: true,
wantPath: "/application/value",
@@ -291,7 +326,7 @@ func TestRelativeImportDestinationsKeepStrictCompositionBoundaries(t *testing.T)
t.Run("upper tier cannot repair a lower import conflict", func(t *testing.T) {
directory := t.TempDir()
lowerPath := writeImportFile(t, directory, "lower.yml", `configkit:
lowerPath := writeImportFile(t, directory, "lower.yml", `config:
imports:
- path: left.yml
destination: [application]
@@ -324,12 +359,12 @@ func TestRelativeImportDestinationsUseEffectiveVersionOwnership(t *testing.T) {
} {
t.Run(test.name, func(t *testing.T) {
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", `configkit:
mainPath := writeImportFile(t, directory, "main.yml", `config:
imports:
- path: parent.yml
destination: [group]
`)
writeImportFile(t, directory, "parent.yml", `configkit:
writeImportFile(t, directory, "parent.yml", `config:
imports:
- path: fragment.yml
destination: [nested]
@@ -374,13 +409,13 @@ func TestRelativeImportDestinationsKeepMainVersionCheckScoped(t *testing.T) {
} `yaml:"collection"`
}
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", `configkit:
mainPath := writeImportFile(t, directory, "main.yml", `config:
imports:
- path: parent.yml
destination: [group]
schema_version: 6
`)
writeImportFile(t, directory, "parent.yml", `configkit:
writeImportFile(t, directory, "parent.yml", `config:
imports:
- path: fragment.yml
destination: [nested]
@@ -421,8 +456,8 @@ func TestLayeredNativeFilesystemImportsInheritInputDestination(t *testing.T) {
t.Parallel()
native := fstest.MapFS{
"main.yml": &fstest.MapFile{Data: []byte("configkit:\n imports:\n - path: first.yml\nroot: main\n")},
"first.yml": &fstest.MapFile{Data: []byte("configkit: {imports: [{path: nested.yml}]}\nfirst: imported\n")},
"main.yml": &fstest.MapFile{Data: []byte("config:\n imports:\n - path: first.yml\nroot: main\n")},
"first.yml": &fstest.MapFile{Data: []byte("config: {imports: [{path: nested.yml}]}\nfirst: imported\n")},
"nested.yml": &fstest.MapFile{Data: []byte("nested: imported\n")},
}
namespace := newNativeNamespace("bundle", native)
@@ -451,7 +486,7 @@ func TestLayeredImportOnlyInputMaterializesDestination(t *testing.T) {
t.Parallel()
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", `configkit:
mainPath := writeImportFile(t, directory, "main.yml", `config:
imports:
- path: optional.yml
`)
@@ -489,7 +524,7 @@ func TestLayeredImportedVersionClaimsUseEffectiveDestination(t *testing.T) {
t.Run(test.name, func(t *testing.T) {
t.Parallel()
directory := t.TempDir()
writeImportFile(t, directory, "main.yml", "configkit: {imports: [{path: fragment.yml}]}\n")
writeImportFile(t, directory, "main.yml", "config: {imports: [{path: fragment.yml}]}\n")
writeImportFile(t, directory, "fragment.yml", "version: v2\n")
rule := &VersionRule{Path: test.rulePath, Check: func(Version, *Validation) error { return nil }}
loaded, err := LoadLayered(
@@ -534,7 +569,7 @@ func TestLayeredDestinationsDoNotChangeRepeatedSourceIdentity(t *testing.T) {
directory := t.TempDir()
writeImportFile(t, directory, "shared.yml", "value: shared\n")
importerPath := writeImportFile(t, directory, "importer.yml", "configkit: {imports: [{path: shared.yml, destination: [nested]}]}\n")
importerPath := writeImportFile(t, directory, "importer.yml", "config: {imports: [{path: shared.yml, destination: [nested]}]}\n")
_, err := LoadLayered(
Input{Source: NoSource()},
testSecretBinding(),
@@ -558,8 +593,8 @@ func TestLayeredDestinationsDoNotChangeRepeatedSourceIdentity(t *testing.T) {
t.Run("placement does not break a physical cycle", func(t *testing.T) {
t.Parallel()
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", "configkit: {imports: [{path: parent.yml, destination: [one]}]}\n")
writeImportFile(t, directory, "parent.yml", "configkit: {imports: [{path: main.yml, destination: [two]}]}\n")
mainPath := writeImportFile(t, directory, "main.yml", "config: {imports: [{path: parent.yml, destination: [one]}]}\n")
writeImportFile(t, directory, "parent.yml", "config: {imports: [{path: main.yml, destination: [two]}]}\n")
_, err := LoadLayered(Input{Source: File(mainPath), Imports: true}, testSecretBinding(), LayeredOptions[map[string]any]{})
loadError, ok := err.(*LoadError)
if !ok || len(loadError.Diagnostics()) == 0 || loadError.Diagnostics()[0].Code != CodeImportCycle {

View File

@@ -121,7 +121,7 @@ func TestLayeredImportedInheritedValuesRetainResourceContexts(t *testing.T) {
}
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "config/main.yml", "child:\n extends: parent\n")
inputPath := writeImportFile(t, directory, "shared/input.yml", "configkit: {imports: [{path: parent.yml}]}\n")
inputPath := writeImportFile(t, directory, "shared/input.yml", "config: {imports: [{path: parent.yml}]}\n")
writeImportFile(t, directory, "shared/parent.yml", "parent:\n resource: icon.txt\n count: 1\n")
writeImportFile(t, directory, "shared/icon.txt", "parent-resource")
var resolutionContext ResourceContext

View File

@@ -214,7 +214,7 @@ func TestLayeredDestinationChecksVersionOnceOnComposedMain(t *testing.T) {
App appConfig `yaml:"app"`
}
filesystem := NewFilesystem("bundle", fstest.MapFS{
"main.yml": &fstest.MapFile{Data: []byte("configkit: {imports: [{path: fragment.yml}]}\nversion: 6\ncount: 4\nmain: main\n")},
"main.yml": &fstest.MapFile{Data: []byte("config: {imports: [{path: fragment.yml}]}\nversion: 6\ncount: 4\nmain: main\n")},
"fragment.yml": &fstest.MapFile{Data: []byte("imported: included\n")},
})
checks := 0
@@ -300,7 +300,7 @@ func TestLayeredDestinationVersionClaimsUsePlacedApplicationPaths(t *testing.T)
t.Run(test.name, func(t *testing.T) {
t.Parallel()
directory := t.TempDir()
writeImportFile(t, directory, "main.yml", "configkit: {imports: [{path: fragment.yml}]}\n")
writeImportFile(t, directory, "main.yml", "config: {imports: [{path: fragment.yml}]}\n")
writeImportFile(t, directory, "fragment.yml", test.body)
loaded, err := LoadLayered(
Input{Source: NoSource()},

View File

@@ -21,7 +21,7 @@ func TestSearchLoadMatchesExplicitFileThroughImportsAndContext(t *testing.T) {
t.Parallel()
root := t.TempDir()
mainPath := writeImportFile(t, root, "app.yml", `configkit:
mainPath := writeImportFile(t, root, "app.yml", `config:
imports: [{path: fragments/extra.yml}]
settings: {main: selected}
`)
@@ -52,7 +52,7 @@ func TestSearchLayeredMainAndUnderlayMatchExplicitFiles(t *testing.T) {
root := t.TempDir()
mainPath := writeImportFile(t, root, "main.yml", "settings: {main: value}\n")
underlayPath := writeImportFile(t, root, "underlay/base.yml", `configkit:
underlayPath := writeImportFile(t, root, "underlay/base.yml", `config:
imports: [{path: extra.yml}]
settings: {underlay: value}
`)

View File

@@ -11,13 +11,13 @@ import (
func TestLoadGlobImportsUseLexicalDeclarationOrderAndNestedDFS(t *testing.T) {
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", `configkit:
mainPath := writeImportFile(t, directory, "main.yml", `config:
imports:
- glob: fragments/*.yml
- path: after.yml
items: {root: root}
`)
aPath := writeImportFile(t, directory, "fragments/a.yml", `configkit:
aPath := writeImportFile(t, directory, "fragments/a.yml", `config:
imports: [{path: nested/child.yml}]
items: {alpha: alpha}
`)
@@ -57,7 +57,7 @@ items: {alpha: alpha}
func TestLoadGlobImportsSupportEscapesClassesAndExplicitConfD(t *testing.T) {
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", `configkit:
mainPath := writeImportFile(t, directory, "main.yml", `config:
imports:
- glob: 'conf.d/literal\*.yml'
- glob: 'conf.d/item-[ab].yml'
@@ -127,7 +127,7 @@ func TestLoadGlobImportsPreserveIdentityAndFileRules(t *testing.T) {
t.Run("overlapping declarations", func(t *testing.T) {
directory := t.TempDir()
writeImportFile(t, directory, "conf/value.yml", "items: {value: value}\n")
mainPath := writeImportFile(t, directory, "main.yml", `configkit:
mainPath := writeImportFile(t, directory, "main.yml", `config:
imports:
- glob: conf/*.yml
- glob: conf/value.*
@@ -318,5 +318,5 @@ func writeGlobRoot(t *testing.T, directory, pattern string, required bool) strin
if required {
requiredLine = "\n required: true"
}
return writeImportFile(t, directory, "main.yml", "configkit:\n imports:\n - glob: '"+pattern+"'"+requiredLine+"\n")
return writeImportFile(t, directory, "main.yml", "config:\n imports:\n - glob: '"+pattern+"'"+requiredLine+"\n")
}

View File

@@ -12,14 +12,14 @@ func TestBroadEmptyImportSelectionsKeepDeclaringSourceOwnership(t *testing.T) {
t.Parallel()
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", `configkit:
mainPath := writeImportFile(t, directory, "main.yml", `config:
imports:
- glob: fragments/*.yml
- path: []
`)
const fragments = 32
for index := 0; index < fragments; index++ {
writeImportFile(t, directory, fmt.Sprintf("fragments/fragment-%02d.yml", index), `configkit:
writeImportFile(t, directory, fmt.Sprintf("fragments/fragment-%02d.yml", index), `config:
imports:
- path: missing.yml
- path: []
@@ -34,7 +34,7 @@ func TestBroadEmptyImportSelectionsKeepDeclaringSourceOwnership(t *testing.T) {
t.Fatalf("source count = %d, want %d", len(sources), fragments+1)
}
for index, source := range sources {
wantPaths := []string{"/configkit/imports/0", "/configkit/imports/1"}
wantPaths := []string{"/config/imports/0", "/config/imports/1"}
if index == 0 {
wantPaths = wantPaths[1:]
}
@@ -57,7 +57,7 @@ func TestOptionalEmptyImportSelectionsRemainSourceLocalAndDetached(t *testing.T)
Value string `yaml:"value"`
}
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", `configkit:
mainPath := writeImportFile(t, directory, "main.yml", `config:
imports:
- dir: absent
- path: missing.yml
@@ -82,7 +82,7 @@ func TestOptionalEmptyImportSelectionsRemainSourceLocalAndDetached(t *testing.T)
if len(sources) != 2 {
t.Fatalf("sources = %#v", sources)
}
wantPaths := []string{"/configkit/imports/0", "/configkit/imports/1", "/configkit/imports/2", "/configkit/imports/3"}
wantPaths := []string{"/config/imports/0", "/config/imports/1", "/config/imports/2", "/config/imports/3"}
wantSelectors := []importSelector{importSelectorDirectory, importSelectorPath, importSelectorPath, importSelectorDirectory}
evidence := sources[0].importSelections
if len(evidence) != len(wantPaths) {
@@ -119,7 +119,7 @@ func TestFailedLoadRetainsOnlyCompletedEmptyImportSelections(t *testing.T) {
Value string `yaml:"value"`
}
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", `configkit:
mainPath := writeImportFile(t, directory, "main.yml", `config:
imports:
- glob: absent/*.yml
- path: required-missing.yml
@@ -137,11 +137,11 @@ value: main
t.Fatalf("failed-load sources = %#v", sources)
}
selection := sources[0].importSelections[0]
if selection.path.String() != "/configkit/imports/0" || selection.location.SourceID != sources[0].ID || selection.selector != importSelectorGlob {
if selection.path.String() != "/config/imports/0" || selection.location.SourceID != sources[0].ID || selection.selector != importSelectorGlob {
t.Fatalf("retained selection = %#v", selection)
}
sources[0].importSelections[0].path.segments[0].key = "changed"
if got := loadError.Sources()[0].importSelections[0].path.String(); got != "/configkit/imports/0" {
if got := loadError.Sources()[0].importSelections[0].path.String(); got != "/config/imports/0" {
t.Fatalf("mutating failed-load snapshot changed retained evidence: %q", got)
}
}
@@ -160,7 +160,7 @@ func TestImportSelectionEvidenceSurvivesCompositionUnderlaysAndResolutionEntry(t
Overlay string `yaml:"overlay"`
}
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", `configkit:
mainPath := writeImportFile(t, directory, "main.yml", `config:
imports:
- path: helper.yml
- path: item.yml
@@ -169,24 +169,24 @@ func TestImportSelectionEvidenceSurvivesCompositionUnderlaysAndResolutionEntry(t
- dir: absent-main
value: main
`)
helperPath := writeImportFile(t, directory, "helper.yml", `configkit:
helperPath := writeImportFile(t, directory, "helper.yml", `config:
imports:
- glob: absent-helper/*.yml
helper: value
`)
itemPath := writeImportFile(t, directory, "item.yml", `configkit:
itemPath := writeImportFile(t, directory, "item.yml", `config:
imports:
- path: []
- path: item-helper.yml
destination: [metadata]
id: selected
`)
itemHelperPath := writeImportFile(t, directory, "item-helper.yml", `configkit:
itemHelperPath := writeImportFile(t, directory, "item-helper.yml", `config:
imports:
- dir: absent-item-helper
key: value
`)
underlayPath := writeImportFile(t, directory, "underlay.yml", `configkit:
underlayPath := writeImportFile(t, directory, "underlay.yml", `config:
imports:
- path: []
value: underlay
@@ -216,11 +216,11 @@ value: underlay
t.Fatalf("configuration = %#v", loaded.Config)
}
want := map[string]string{
"source-1": "/configkit/imports/2",
"source-2": "/configkit/imports/0",
"source-3": "/configkit/imports/0",
"source-4": "/configkit/imports/0",
"source-5": "/configkit/imports/0",
"source-1": "/config/imports/2",
"source-2": "/config/imports/0",
"source-3": "/config/imports/0",
"source-4": "/config/imports/0",
"source-5": "/config/imports/0",
}
sources := loaded.Inspection.Sources()
if len(sources) != 6 {
@@ -266,18 +266,18 @@ func TestFailedNestedItemLoadKeepsEvidenceWithUnresolvedDestination(t *testing.T
Items []item `yaml:"items"`
}
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", `configkit:
mainPath := writeImportFile(t, directory, "main.yml", `config:
imports:
- path: item.yml
destination: [items]
placement: sequence-item
`)
writeImportFile(t, directory, "item.yml", `configkit:
writeImportFile(t, directory, "item.yml", `config:
imports:
- path: helper.yml
destination: [metadata]
`)
writeImportFile(t, directory, "helper.yml", `configkit:
writeImportFile(t, directory, "helper.yml", `config:
imports:
- dir: absent
- path: missing.yml
@@ -294,7 +294,7 @@ key: value
continue
}
if !source.destinationUnresolved || source.Destination.String() != "/items" || len(source.importSelections) != 1 ||
source.importSelections[0].path.String() != "/configkit/imports/0" || source.importSelections[0].location.SourceID != source.ID {
source.importSelections[0].path.String() != "/config/imports/0" || source.importSelections[0].location.SourceID != source.ID {
t.Fatalf("failed nested item source = %#v", source)
}
return

View File

@@ -17,9 +17,9 @@ func TestImportedAcquisitionClosesOwnedHostRootOnEveryExit(t *testing.T) {
wantError bool
wantPanic bool
}{
{name: "success", main: "configkit: {imports: [{path: child.yml}]}\n", child: "value: child\n"},
{name: "error", main: "configkit: {imports: [{path: missing.yml, required: true}]}\n", wantError: true},
{name: "version panic", main: "configkit: {imports: [{path: child.yml}]}\n", child: "version: v1\n", version: true, wantPanic: true},
{name: "success", main: "config: {imports: [{path: child.yml}]}\n", child: "value: child\n"},
{name: "error", main: "config: {imports: [{path: missing.yml, required: true}]}\n", wantError: true},
{name: "version panic", main: "config: {imports: [{path: child.yml}]}\n", child: "version: v1\n", version: true, wantPanic: true},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
@@ -80,7 +80,7 @@ func TestImportedAcquisitionClosesOwnedHostRootOnEveryExit(t *testing.T) {
func TestImportedAcquisitionClosesChildFileBeforeVersionPanic(t *testing.T) {
filesystem := &observedFilesystem{files: fstest.MapFS{
"main.yml": &fstest.MapFile{Data: []byte("configkit: {imports: [{path: child.yml}]}\n")},
"main.yml": &fstest.MapFile{Data: []byte("config: {imports: [{path: child.yml}]}\n")},
"child.yml": &fstest.MapFile{Data: []byte("version: v1\n")},
}}
namespace := newNativeNamespace("bundle", filesystem)

View File

@@ -72,7 +72,7 @@ func TestSelectNamedImportsChecksRequiredTargetsBeforeExclusions(t *testing.T) {
t.Fatal(diagnostics)
}
_, diagnostics = selectNamedImportCandidates(access, root, specs[0], policy)
if len(diagnostics) != 1 || diagnostics[0].Code != CodeImportMissing || diagnostics[0].Path.String() != "/configkit/imports/0/path" {
if len(diagnostics) != 1 || diagnostics[0].Code != CodeImportMissing || diagnostics[0].Path.String() != "/config/imports/0/path" {
t.Fatalf("required excluded missing target diagnostics = %#v", diagnostics)
}
}
@@ -171,8 +171,8 @@ func TestSelectNamedImportsChecksNormalizedPathsLexically(t *testing.T) {
}}
failingAccess := newNativeAccess(failingFilesystem, ".", &namespaceToken{})
_, diagnostics = selectNamedImportCandidates(failingAccess, ".", specs[0], resolvedImportPolicy{})
if len(diagnostics) != 1 || diagnostics[0].Code != CodeImportInvalid || diagnostics[0].Path.String() != "/configkit/imports/0/path/1" {
t.Fatalf("first lexical failure = %#v, want /configkit/imports/0/path/1", diagnostics)
if len(diagnostics) != 1 || diagnostics[0].Code != CodeImportInvalid || diagnostics[0].Path.String() != "/config/imports/0/path/1" {
t.Fatalf("first lexical failure = %#v, want /config/imports/0/path/1", diagnostics)
}
if diagnostics[0].Primary == nil || diagnostics[0].Primary.SourceID != "source-1" {
t.Fatalf("first lexical failure location = %#v", diagnostics[0].Primary)

View File

@@ -34,7 +34,7 @@ func TestParseImportDeclarationSpecNormalizesPresenceAndPlacement(t *testing.T)
if first.required == nil || *first.required || first.destination.String() != "/services" || first.placement != PlacementModeSequenceItem {
t.Fatalf("explicit declaration values = %#v", first)
}
if first.path.String() != "/configkit/imports/0" || first.fieldSites["required"].path.String() != "/configkit/imports/0/required" {
if first.path.String() != "/config/imports/0" || first.fieldSites["required"].path.String() != "/config/imports/0/required" {
t.Fatalf("stored paths = declaration %q, required %q", first.path.String(), first.fieldSites["required"].path.String())
}
second := specs[1]
@@ -53,21 +53,21 @@ func TestParseImportDeclarationSpecValidatesSelectorMatrixAndTypes(t *testing.T)
tests := []struct {
name, yaml, path string
}{
{name: "missing selector", yaml: " - required: true\n", path: "/configkit/imports/0"},
{name: "multiple selectors", yaml: " - path: one.yaml\n dir: fragments\n", path: "/configkit/imports/0"},
{name: "removed optional", yaml: " - path: one.yaml\n optional: true\n", path: "/configkit/imports/0/optional"},
{name: "inapplicable field", yaml: " - path: one.yaml\n pattern: '*.yaml'\n", path: "/configkit/imports/0/pattern"},
{name: "selector null", yaml: " - path: null\n", path: "/configkit/imports/0/path"},
{name: "empty path", yaml: " - path: ''\n", path: "/configkit/imports/0/path"},
{name: "nested selector list", yaml: " - path: [[one.yaml]]\n", path: "/configkit/imports/0/path/0"},
{name: "null selector member", yaml: " - dir: [fragments, null]\n", path: "/configkit/imports/0/dir/1"},
{name: "empty glob", yaml: " - glob: ''\n", path: "/configkit/imports/0/glob"},
{name: "recursive glob wildcard", yaml: " - glob: '**/*.yaml'\n", path: "/configkit/imports/0/glob"},
{name: "null boolean", yaml: " - path: one.yaml\n required: null\n", path: "/configkit/imports/0/required"},
{name: "bad pattern member with empty roots", yaml: " - dir: []\n pattern: ['*', '[']\n", path: "/configkit/imports/0/pattern/1"},
{name: "bad exclusion member", yaml: " - glob: '*.yaml'\n exclude: ['[']\n", path: "/configkit/imports/0/exclude/0"},
{name: "invalid destination", yaml: " - path: one.yaml\n destination: [configkit]\n", path: "/configkit/imports/0/destination/0"},
{name: "invalid placement", yaml: " - path: one.yaml\n placement: sequence\n", path: "/configkit/imports/0/placement"},
{name: "missing selector", yaml: " - required: true\n", path: "/config/imports/0"},
{name: "multiple selectors", yaml: " - path: one.yaml\n dir: fragments\n", path: "/config/imports/0"},
{name: "removed optional", yaml: " - path: one.yaml\n optional: true\n", path: "/config/imports/0/optional"},
{name: "inapplicable field", yaml: " - path: one.yaml\n pattern: '*.yaml'\n", path: "/config/imports/0/pattern"},
{name: "selector null", yaml: " - path: null\n", path: "/config/imports/0/path"},
{name: "empty path", yaml: " - path: ''\n", path: "/config/imports/0/path"},
{name: "nested selector list", yaml: " - path: [[one.yaml]]\n", path: "/config/imports/0/path/0"},
{name: "null selector member", yaml: " - dir: [fragments, null]\n", path: "/config/imports/0/dir/1"},
{name: "empty glob", yaml: " - glob: ''\n", path: "/config/imports/0/glob"},
{name: "recursive glob wildcard", yaml: " - glob: '**/*.yaml'\n", path: "/config/imports/0/glob"},
{name: "null boolean", yaml: " - path: one.yaml\n required: null\n", path: "/config/imports/0/required"},
{name: "bad pattern member with empty roots", yaml: " - dir: []\n pattern: ['*', '[']\n", path: "/config/imports/0/pattern/1"},
{name: "bad exclusion member", yaml: " - glob: '*.yaml'\n exclude: ['[']\n", path: "/config/imports/0/exclude/0"},
{name: "invalid destination", yaml: " - path: one.yaml\n destination: [extends]\n", path: "/config/imports/0/destination/0"},
{name: "invalid placement", yaml: " - path: one.yaml\n placement: sequence\n", path: "/config/imports/0/placement"},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
@@ -108,7 +108,7 @@ func TestParseImportDeclarationSpecValidatesDepthSyntaxAndPolicy(t *testing.T) {
t.Parallel()
specs, diagnostics := parseImportSpecsYAML(t, " - dir: []\n recursive: true\n depth: "+test.value+"\n")
if !test.valid {
if len(diagnostics) == 0 || diagnostics[0].Path.String() != "/configkit/imports/0/depth" {
if len(diagnostics) == 0 || diagnostics[0].Path.String() != "/config/imports/0/depth" {
t.Fatalf("diagnostics = %#v, want invalid depth", diagnostics)
}
return
@@ -124,7 +124,7 @@ func TestParseImportDeclarationSpecValidatesDepthSyntaxAndPolicy(t *testing.T) {
t.Fatalf("syntax-only parse diagnostics = %#v", diagnostics)
}
_, diagnostics = resolveImportPolicy(specs[0], ImportDefaults{})
if len(diagnostics) != 1 || diagnostics[0].Path.String() != "/configkit/imports/0/depth" {
if len(diagnostics) != 1 || diagnostics[0].Path.String() != "/config/imports/0/depth" {
t.Fatalf("policy diagnostics = %#v, want depth applicability error", diagnostics)
}
@@ -228,7 +228,7 @@ func TestInvalidImportDefaultPatternsFailBeforeReadingSource(t *testing.T) {
func parseImportSpecsYAML(t *testing.T, declarations string) ([]importDeclarationSpec, []Diagnostic) {
t.Helper()
parsed, diagnostics := parseSource(Bytes("import specification fixture", []byte("configkit:\n imports:\n"+declarations)), "source-1", defaultParseLimits())
parsed, diagnostics := parseSource(Bytes("import specification fixture", []byte("config:\n imports:\n"+declarations)), "source-1", defaultParseLimits())
if len(diagnostics) != 0 {
return nil, diagnostics
}

View File

@@ -47,14 +47,14 @@ func TestLoadFormerDirectiveKeyIsApplicationData(t *testing.T) {
func TestLoadTraversesPathImportsDepthFirstAndComposesOrigins(t *testing.T) {
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", `configkit:
mainPath := writeImportFile(t, directory, "main.yml", `config:
imports:
- path: first.yml
- path: second.yml
settings:
root: root
`)
firstPath := writeImportFile(t, directory, "first.yml", `configkit:
firstPath := writeImportFile(t, directory, "first.yml", `config:
imports:
- path: nested/third.yml
settings:
@@ -99,13 +99,13 @@ func TestLoadOrdinaryImportsUseDependencyReadyCompositionOrder(t *testing.T) {
Tasks []task `yaml:"tasks"`
}
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", `configkit:
mainPath := writeImportFile(t, directory, "main.yml", `config:
imports:
- path: z-parent.yml
- path: a-independent.yml
tasks: [{id: main}]
`)
zParentPath := writeImportFile(t, directory, "z-parent.yml", `configkit:
zParentPath := writeImportFile(t, directory, "z-parent.yml", `config:
imports:
- path: b-dependency.yml
tasks: [{id: z-parent}]
@@ -180,7 +180,7 @@ func TestAcquiredContextsUseSelectedFileWhenSourceRecordsAreReordered(t *testing
func TestLoadImportsFromProfilesDirectoryAsBaseInput(t *testing.T) {
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", "configkit: {imports: [{path: profiles/shared.yml}]}\n")
mainPath := writeImportFile(t, directory, "main.yml", "config: {imports: [{path: profiles/shared.yml}]}\n")
writeImportFile(t, directory, "profiles/shared.yml", "settings: {root: imported}\n")
result, err := testLoad[importTestConfig](File(mainPath), Options[importTestConfig]{Imports: true})
@@ -193,7 +193,7 @@ func TestLoadImportsFromProfilesDirectoryAsBaseInput(t *testing.T) {
func TestLoadRejectsImportConflictsAndFragmentVersions(t *testing.T) {
t.Run("all duplicate claimants", func(t *testing.T) {
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", `configkit:
mainPath := writeImportFile(t, directory, "main.yml", `config:
imports:
- path: one.yml
- path: two.yml
@@ -219,7 +219,7 @@ func TestLoadRejectsImportConflictsAndFragmentVersions(t *testing.T) {
} {
t.Run(test.name, func(t *testing.T) {
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", "configkit:\n imports:\n - path: fragment.yml\n")
mainPath := writeImportFile(t, directory, "main.yml", "config:\n imports:\n - path: fragment.yml\n")
writeImportFile(t, directory, "fragment.yml", test.fragment)
loadError := requireLoadCode(t, File(mainPath), Options[importTestConfig]{Imports: true, Definition: Definition[importTestConfig]{Version: versionRule}}, CodeImportVersion)
diagnostic := loadError.Diagnostics()[0]
@@ -236,18 +236,17 @@ func TestLoadImportDirectiveValidationAndTemporaryGlobGate(t *testing.T) {
body string
code Code
}{
{name: "directive kind", body: "configkit: []\n", code: CodeImportInvalid},
{name: "unknown directive field", body: "configkit: {unknown: true}\n", code: CodeImportInvalid},
{name: "imports kind", body: "configkit: {imports: {}}\n", code: CodeImportInvalid},
{name: "declaration kind", body: "configkit: {imports: [file.yml]}\n", code: CodeImportInvalid},
{name: "missing target", body: "configkit: {imports: [{required: true}]}\n", code: CodeImportInvalid},
{name: "two targets", body: "configkit: {imports: [{path: a.yml, glob: '*.yml'}]}\n", code: CodeImportInvalid},
{name: "unknown declaration field", body: "configkit: {imports: [{path: a.yml, extra: true}]}\n", code: CodeImportInvalid},
{name: "removed optional field", body: "configkit: {imports: [{path: a.yml, optional: true}]}\n", code: CodeImportInvalid},
{name: "required kind", body: "configkit: {imports: [{path: a.yml, required: 'yes'}]}\n", code: CodeImportInvalid},
{name: "placement kind", body: "configkit: {imports: [{path: a.yml, placement: true}]}\n", code: CodeImportInvalid},
{name: "placement value", body: "configkit: {imports: [{path: a.yml, placement: item}]}\n", code: CodeImportInvalid},
{name: "nested directive", body: "nested: {configkit: {}}\n", code: CodeImportInvalid},
{name: "directive kind", body: "config: []\n", code: CodeImportInvalid},
{name: "unknown directive field", body: "config: {unknown: true}\n", code: CodeImportInvalid},
{name: "imports kind", body: "config: {imports: {}}\n", code: CodeImportInvalid},
{name: "declaration kind", body: "config: {imports: [file.yml]}\n", code: CodeImportInvalid},
{name: "missing target", body: "config: {imports: [{required: true}]}\n", code: CodeImportInvalid},
{name: "two targets", body: "config: {imports: [{path: a.yml, glob: '*.yml'}]}\n", code: CodeImportInvalid},
{name: "unknown declaration field", body: "config: {imports: [{path: a.yml, extra: true}]}\n", code: CodeImportInvalid},
{name: "removed optional field", body: "config: {imports: [{path: a.yml, optional: true}]}\n", code: CodeImportInvalid},
{name: "required kind", body: "config: {imports: [{path: a.yml, required: 'yes'}]}\n", code: CodeImportInvalid},
{name: "placement kind", body: "config: {imports: [{path: a.yml, placement: true}]}\n", code: CodeImportInvalid},
{name: "placement value", body: "config: {imports: [{path: a.yml, placement: item}]}\n", code: CodeImportInvalid},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
@@ -274,13 +273,13 @@ func TestLoadItemImportComposesHelpersAndNestedItemsInDeclaringScope(t *testing.
Items []record `yaml:"items"`
}
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", `configkit:
mainPath := writeImportFile(t, directory, "main.yml", `config:
imports:
- path: records/item.yml
destination: [items]
placement: sequence-item
`)
itemPath := writeImportFile(t, directory, "records/item.yml", `configkit:
itemPath := writeImportFile(t, directory, "records/item.yml", `config:
imports:
- path: nested/helper.yml
- path: child.yml
@@ -288,7 +287,7 @@ func TestLoadItemImportComposesHelpersAndNestedItemsInDeclaringScope(t *testing.
placement: sequence-item
name: authored
`)
helperPath := writeImportFile(t, directory, "records/nested/helper.yml", `configkit:
helperPath := writeImportFile(t, directory, "records/nested/helper.yml", `config:
imports:
- path: more.yml
destination: [metadata]
@@ -349,13 +348,13 @@ label: helper
t.Run("duplicate helper identity remains a mapping conflict", func(t *testing.T) {
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", `configkit:
mainPath := writeImportFile(t, directory, "main.yml", `config:
imports:
- path: item.yml
destination: [items]
placement: sequence-item
`)
writeImportFile(t, directory, "item.yml", `configkit:
writeImportFile(t, directory, "item.yml", `config:
imports:
- path: helper.yml
id: authored
@@ -392,7 +391,7 @@ func TestLayeredUnderlayItemImportRetainsNestedEvidenceAndDestinations(t *testin
}
directory := t.TempDir()
itemPath := writeImportFile(t, directory, "records/item.yml", `configkit:
itemPath := writeImportFile(t, directory, "records/item.yml", `config:
imports:
- path: nested/helper.yml
- path: children/child.yml
@@ -400,7 +399,7 @@ func TestLayeredUnderlayItemImportRetainsNestedEvidenceAndDestinations(t *testin
placement: sequence-item
name: authored
`)
helperPath := writeImportFile(t, directory, "records/nested/helper.yml", `configkit:
helperPath := writeImportFile(t, directory, "records/nested/helper.yml", `config:
imports:
- path: more.yml
destination: [metadata]
@@ -482,7 +481,7 @@ func TestLoadItemGlobKeepsDefaultModeIndependentAndOptionalMissesAbsent(t *testi
Other map[string]string `yaml:"other"`
}
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", `configkit:
mainPath := writeImportFile(t, directory, "main.yml", `config:
imports:
- glob: records/*.yml
destination: [items]
@@ -518,7 +517,7 @@ func TestLoadMainItemPlacementKeepsItsHelpersInTheItem(t *testing.T) {
Items []item `yaml:"items"`
}
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", "configkit:\n imports:\n - path: helper.yml\nid: main\n")
mainPath := writeImportFile(t, directory, "main.yml", "config:\n imports:\n - path: helper.yml\nid: main\n")
helperPath := writeImportFile(t, directory, "helper.yml", "value: helper\n")
result, err := testLoad[config](File(mainPath), Options[config]{
Imports: true, Destination: Keys("items"), PlacementMode: PlacementModeSequenceItem,
@@ -616,14 +615,14 @@ func TestProjectNestedEvidenceUsesMappedSequenceItemIndex(t *testing.T) {
func TestDeferredInputCompositionUsesRetainedAcquisitionScopes(t *testing.T) {
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", `configkit:
mainPath := writeImportFile(t, directory, "main.yml", `config:
imports:
- path: item.yml
destination: [records]
placement: sequence-item
name: main
`)
itemPath := writeImportFile(t, directory, "item.yml", `configkit:
itemPath := writeImportFile(t, directory, "item.yml", `config:
imports:
- path: helper.yml
id: item
@@ -680,13 +679,13 @@ func TestItemImportCanJoinAnAuthoredListUnderRegisteredComposition(t *testing.T)
Items []map[string]string `yaml:"items"`
}
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", `configkit:
mainPath := writeImportFile(t, directory, "main.yml", `config:
imports:
- path: item.yml
destination: [items]
placement: sequence-item
`)
writeImportFile(t, directory, "item.yml", "configkit: {imports: [{path: helper.yml}]}\nname: imported\n")
writeImportFile(t, directory, "item.yml", "config: {imports: [{path: helper.yml}]}\nname: imported\n")
writeImportFile(t, directory, "helper.yml", "id: helper-id\n")
sequencePolicy := mustCompileSequenceIdentityPolicy(t, []sequenceIdentityRegistration{{selector: sequenceIdentitySelector{literalSequenceSelector("items")}, identityFields: []string{"id"}}})
input, diagnostics := testAcquireInput(inputAcquisitionRequest{
@@ -734,7 +733,7 @@ func TestParseImportDestinationUsesLiteralStringSegments(t *testing.T) {
},
} {
t.Run(test.name, func(t *testing.T) {
body := "configkit:\n imports:\n - path: child.yml\n" + test.destination
body := "config:\n imports:\n - path: child.yml\n" + test.destination
declarations := parseImportSpecificationsYAML(t, body)
if len(declarations) != 1 {
t.Fatalf("declarations = %#v", declarations)
@@ -754,7 +753,7 @@ func TestParseImportDestinationUsesLiteralStringSegments(t *testing.T) {
func TestParseImportPlacementDefaultsPerDeclaration(t *testing.T) {
t.Parallel()
declarations := parseImportSpecificationsYAML(t, `configkit:
declarations := parseImportSpecificationsYAML(t, `config:
imports:
- path: mapping.yml
- glob: records/*.yml
@@ -774,18 +773,17 @@ func TestParseImportDestinationRejectsInvalidShapesAndMembers(t *testing.T) {
wantPath string
badMember string
}{
{name: "null", value: "null", wantPath: "/configkit/imports/0/destination", badMember: "null"},
{name: "scalar string", value: "prompts", wantPath: "/configkit/imports/0/destination", badMember: "prompts"},
{name: "number", value: "3", wantPath: "/configkit/imports/0/destination", badMember: "3"},
{name: "non-string number", value: "[valid, 7]", wantPath: "/configkit/imports/0/destination/1", badMember: "7"},
{name: "non-string null", value: "[valid, null]", wantPath: "/configkit/imports/0/destination/1", badMember: "null"},
{name: "non-string boolean", value: "[valid, true]", wantPath: "/configkit/imports/0/destination/1", badMember: "true"},
{name: "non-string mapping", value: "[valid, {key: value}]", wantPath: "/configkit/imports/0/destination/1", badMember: "{key"},
{name: "reserved configkit", value: "[valid, configkit]", wantPath: "/configkit/imports/0/destination/1", badMember: "configkit"},
{name: "reserved extends", value: "[valid, extends]", wantPath: "/configkit/imports/0/destination/1", badMember: "extends"},
{name: "null", value: "null", wantPath: "/config/imports/0/destination", badMember: "null"},
{name: "scalar string", value: "prompts", wantPath: "/config/imports/0/destination", badMember: "prompts"},
{name: "number", value: "3", wantPath: "/config/imports/0/destination", badMember: "3"},
{name: "non-string number", value: "[valid, 7]", wantPath: "/config/imports/0/destination/1", badMember: "7"},
{name: "non-string null", value: "[valid, null]", wantPath: "/config/imports/0/destination/1", badMember: "null"},
{name: "non-string boolean", value: "[valid, true]", wantPath: "/config/imports/0/destination/1", badMember: "true"},
{name: "non-string mapping", value: "[valid, {key: value}]", wantPath: "/config/imports/0/destination/1", badMember: "{key"},
{name: "reserved extends", value: "[valid, extends]", wantPath: "/config/imports/0/destination/1", badMember: "extends"},
} {
t.Run(test.name, func(t *testing.T) {
body := "configkit:\n imports:\n - path: child.yml\n destination: " + test.value + "\n"
body := "config:\n imports:\n - path: child.yml\n destination: " + test.value + "\n"
parsed, diagnostics := parseImportSpecificationYAML(body)
if len(diagnostics) != 1 || diagnostics[0].Code != CodeImportInvalid || diagnostics[0].Path.String() != test.wantPath {
t.Fatalf("parse = %#v, want import.invalid at %q", diagnostics, test.wantPath)
@@ -809,13 +807,13 @@ func TestImportDestinationValidationPrecedesOptionalSuppression(t *testing.T) {
}{
{
name: "optional missing path",
body: "configkit:\n imports:\n - path: absent.yml\n destination: null\n",
path: "/configkit/imports/0/destination",
body: "config:\n imports:\n - path: absent.yml\n destination: null\n",
path: "/config/imports/0/destination",
},
{
name: "optional unmatched glob",
body: "configkit:\n imports:\n - glob: absent/*.yml\n destination: [extends]\n",
path: "/configkit/imports/0/destination/0",
body: "config:\n imports:\n - glob: absent/*.yml\n destination: [extends]\n",
path: "/config/imports/0/destination/0",
},
} {
t.Run(test.name, func(t *testing.T) {
@@ -832,7 +830,7 @@ func TestImportDestinationValidationPrecedesOptionalSuppression(t *testing.T) {
func TestLoadImportMissingContainmentAndRegularFileRules(t *testing.T) {
t.Run("optional missing", func(t *testing.T) {
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", `configkit:
mainPath := writeImportFile(t, directory, "main.yml", `config:
imports:
- path: missing.yml
settings: {root: retained}
@@ -871,7 +869,7 @@ settings: {root: retained}
if test.code == CodeImportMissing {
required = "\n required: true"
}
mainPath := writeImportFile(t, directory, "main.yml", "configkit:\n imports:\n - path: \""+test.path+"\""+required+"\n")
mainPath := writeImportFile(t, directory, "main.yml", "config:\n imports:\n - path: \""+test.path+"\""+required+"\n")
requireLoadCode(t, File(mainPath), Options[importTestConfig]{Imports: true}, test.code)
})
}
@@ -881,8 +879,8 @@ func TestImportDefaultsReachOrdinaryAndGroupedDeclarations(t *testing.T) {
t.Parallel()
required := true
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", "configkit: {imports: [{path: child.yml}]}\n")
writeImportFile(t, directory, "child.yml", "configkit: {imports: [{path: absent.yml}]}\n")
mainPath := writeImportFile(t, directory, "main.yml", "config: {imports: [{path: child.yml}]}\n")
writeImportFile(t, directory, "child.yml", "config: {imports: [{path: absent.yml}]}\n")
_, err := testLoad[importTestConfig](File(mainPath), Options[importTestConfig]{
Imports: true, ImportDefaults: ImportDefaults{Required: &required},
})
@@ -892,7 +890,7 @@ func TestImportDefaultsReachOrdinaryAndGroupedDeclarations(t *testing.T) {
}
basePath := writeImportFile(t, directory, "base.yml", "settings: {root: base}\n")
underlayPath := writeImportFile(t, directory, "underlay.yml", "configkit: {imports: [{path: absent.yml}]}\n")
underlayPath := writeImportFile(t, directory, "underlay.yml", "config: {imports: [{path: absent.yml}]}\n")
_, err = loadGroupedWithSecretLookup(loadRequest[importTestConfig]{
main: loadInput{source: File(basePath)},
underlays: []loadGroup{{inputs: []loadInput{{source: File(underlayPath), imports: true}}}},
@@ -906,9 +904,9 @@ func TestImportDefaultsReachOrdinaryAndGroupedDeclarations(t *testing.T) {
func TestLoadImportIdentityReportsCyclesAndRepeatedRoutes(t *testing.T) {
t.Run("cycle", func(t *testing.T) {
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", "configkit:\n imports: [{path: a.yml}]\n")
writeImportFile(t, directory, "a.yml", "configkit:\n imports: [{path: b.yml}]\n")
writeImportFile(t, directory, "b.yml", "configkit:\n imports: [{path: main.yml}]\n")
mainPath := writeImportFile(t, directory, "main.yml", "config:\n imports: [{path: a.yml}]\n")
writeImportFile(t, directory, "a.yml", "config:\n imports: [{path: b.yml}]\n")
writeImportFile(t, directory, "b.yml", "config:\n imports: [{path: main.yml}]\n")
loadError := requireLoadCode(t, File(mainPath), Options[importTestConfig]{Imports: true}, CodeImportCycle)
diagnostic := loadError.Diagnostics()[0]
if diagnostic.Primary == nil || len(diagnostic.Related) != 2 || !strings.Contains(diagnostic.Message, "main.yml") || !strings.Contains(diagnostic.Message, "a.yml") || !strings.Contains(diagnostic.Message, "b.yml") {
@@ -918,13 +916,13 @@ func TestLoadImportIdentityReportsCyclesAndRepeatedRoutes(t *testing.T) {
t.Run("cycle through an item scope", func(t *testing.T) {
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", `configkit:
mainPath := writeImportFile(t, directory, "main.yml", `config:
imports:
- path: item.yml
destination: [items]
placement: sequence-item
`)
writeImportFile(t, directory, "item.yml", "configkit: {imports: [{path: main.yml}]}\n")
writeImportFile(t, directory, "item.yml", "config: {imports: [{path: main.yml}]}\n")
loadError := requireLoadCode(t, File(mainPath), Options[importTestConfig]{Imports: true}, CodeImportCycle)
diagnostic := loadError.Diagnostics()[0]
if diagnostic.Primary == nil || len(diagnostic.Related) != 1 || !strings.Contains(diagnostic.Message, "main.yml") || !strings.Contains(diagnostic.Message, "item.yml") {
@@ -934,9 +932,9 @@ func TestLoadImportIdentityReportsCyclesAndRepeatedRoutes(t *testing.T) {
t.Run("diamond", func(t *testing.T) {
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", "configkit:\n imports: [{path: left.yml}, {path: right.yml}]\n")
writeImportFile(t, directory, "left.yml", "configkit:\n imports: [{path: shared.yml}]\n")
writeImportFile(t, directory, "right.yml", "configkit:\n imports: [{path: shared.yml}]\n")
mainPath := writeImportFile(t, directory, "main.yml", "config:\n imports: [{path: left.yml}, {path: right.yml}]\n")
writeImportFile(t, directory, "left.yml", "config:\n imports: [{path: shared.yml}]\n")
writeImportFile(t, directory, "right.yml", "config:\n imports: [{path: shared.yml}]\n")
writeImportFile(t, directory, "shared.yml", "settings: {root: shared}\n")
loadError := requireLoadCode(t, File(mainPath), Options[importTestConfig]{Imports: true}, CodeImportRepeated)
diagnostic := loadError.Diagnostics()[0]
@@ -957,20 +955,20 @@ func TestLoadImportIdentityReportsCyclesAndRepeatedRoutes(t *testing.T) {
if err := os.Symlink("target.yml", filepath.Join(directory, "second-link.yml")); err != nil {
t.Skipf("symlinks unavailable: %v", err)
}
mainPath := writeImportFile(t, directory, "main.yml", "configkit: {imports: [{path: first-link.yml}, {path: second-link.yml}]}\n")
mainPath := writeImportFile(t, directory, "main.yml", "config: {imports: [{path: first-link.yml}, {path: second-link.yml}]}\n")
requireLoadCode(t, File(mainPath), Options[importTestConfig]{Imports: true}, CodeImportRepeated)
})
}
func TestItemAcquisitionRetainsInclusionGraphAndScopeOwnership(t *testing.T) {
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", `configkit:
mainPath := writeImportFile(t, directory, "main.yml", `config:
imports:
- path: item.yml
destination: [items]
placement: sequence-item
`)
itemPath := writeImportFile(t, directory, "item.yml", "configkit: {imports: [{path: helper.yml}]}\nname: item\n")
itemPath := writeImportFile(t, directory, "item.yml", "config: {imports: [{path: helper.yml}]}\nname: item\n")
helperPath := writeImportFile(t, directory, "helper.yml", "id: supplied\n")
input, diagnostics := testAcquireInput(inputAcquisitionRequest{
@@ -1036,7 +1034,7 @@ func TestItemContributionsUseDependencyReadySchedules(t *testing.T) {
}
definition := Definition[config]{sequenceIdentityRegistrations: []sequenceIdentityRegistration{{selector: sequenceIdentitySelector{literalSequenceSelector("items")}, identityFields: []string{"id"}}}}
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", `configkit:
mainPath := writeImportFile(t, directory, "main.yml", `config:
imports:
- path: z-item.yml
destination: [items]
@@ -1065,19 +1063,19 @@ items: []
t.Run("unequal helper branches", func(t *testing.T) {
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", `configkit:
mainPath := writeImportFile(t, directory, "main.yml", `config:
imports:
- path: item.yml
destination: [items]
placement: sequence-item
`)
writeImportFile(t, directory, "item.yml", `configkit:
writeImportFile(t, directory, "item.yml", `config:
imports:
- path: b-parent.yml
- path: c-independent.yml
id: item
`)
writeImportFile(t, directory, "b-parent.yml", "configkit: {imports: [{path: a-dependency.yml}]}\nid: b\n")
writeImportFile(t, directory, "b-parent.yml", "config: {imports: [{path: a-dependency.yml}]}\nid: b\n")
writeImportFile(t, directory, "a-dependency.yml", "id: a\n")
writeImportFile(t, directory, "c-independent.yml", "id: c\n")
loadError := requireLoadCode(t, File(mainPath), Options[importTestConfig]{Imports: true}, CodeComposeConflict)
@@ -1104,7 +1102,7 @@ id: item
t.Run("selected main item dependencies", func(t *testing.T) {
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", "configkit: {imports: [{path: helper.yml}]}\nid: main\n")
mainPath := writeImportFile(t, directory, "main.yml", "config: {imports: [{path: helper.yml}]}\nid: main\n")
writeImportFile(t, directory, "helper.yml", "id: helper\n")
options := Options[importTestConfig]{
Imports: true, Destination: Keys("items"), PlacementMode: PlacementModeSequenceItem,
@@ -1130,11 +1128,11 @@ func TestBroadItemScopesKeepHelperOriginsAndDestinations(t *testing.T) {
directory := t.TempDir()
const count = 32
var main strings.Builder
main.WriteString("configkit:\n imports:\n")
main.WriteString("config:\n imports:\n")
for index := count - 1; index >= 0; index-- {
name := strconv.Itoa(100 + index)
main.WriteString(" - path: item-" + name + ".yml\n destination: [items]\n placement: sequence-item\n")
writeImportFile(t, directory, "item-"+name+".yml", "configkit: {imports: [{path: helper-"+name+".yml}]}\nid: item-"+name+"\n")
writeImportFile(t, directory, "item-"+name+".yml", "config: {imports: [{path: helper-"+name+".yml}]}\nid: item-"+name+"\n")
writeImportFile(t, directory, "helper-"+name+".yml", "value: helper-"+name+"\n")
}
mainPath := writeImportFile(t, directory, "main.yml", main.String())
@@ -1183,14 +1181,14 @@ func TestBroadItemScopesKeepHelperOriginsAndDestinations(t *testing.T) {
func TestItemHelperScopeScheduleInterleavesUnequalBranches(t *testing.T) {
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", `configkit:
mainPath := writeImportFile(t, directory, "main.yml", `config:
imports:
- path: item.yml
destination: [items]
placement: sequence-item
`)
writeImportFile(t, directory, "item.yml", "configkit: {imports: [{path: b-parent.yml}, {path: c-independent.yml}]}\nitem: true\n")
writeImportFile(t, directory, "b-parent.yml", "configkit: {imports: [{path: a-dependency.yml}]}\nb: true\n")
writeImportFile(t, directory, "item.yml", "config: {imports: [{path: b-parent.yml}, {path: c-independent.yml}]}\nitem: true\n")
writeImportFile(t, directory, "b-parent.yml", "config: {imports: [{path: a-dependency.yml}]}\nb: true\n")
writeImportFile(t, directory, "a-dependency.yml", "a: true\n")
writeImportFile(t, directory, "c-independent.yml", "c: true\n")
input, diagnostics := testAcquireInput(inputAcquisitionRequest{
@@ -1232,7 +1230,7 @@ func TestLoadImportsCanonicalSymlinksAndKeepsHardLinksDistinct(t *testing.T) {
if err := os.Symlink(target, filepath.Join(directory, "link.yml")); err != nil {
t.Skipf("symlinks unavailable: %v", err)
}
mainPath := writeImportFile(t, directory, "main.yml", "configkit: {imports: [{path: link.yml}]}\n")
mainPath := writeImportFile(t, directory, "main.yml", "config: {imports: [{path: link.yml}]}\n")
result, err := testLoad[importTestConfig](File(mainPath), Options[importTestConfig]{Imports: true})
if err != nil || result.Config.Settings.First != "linked" || result.Sources()[1].Path != canonicalTestPath(t, target) {
t.Fatalf("symlink result = %#v, %v", result, err)
@@ -1246,7 +1244,7 @@ func TestLoadImportsCanonicalSymlinksAndKeepsHardLinksDistinct(t *testing.T) {
if err := os.Symlink(target, filepath.Join(root, "escape.yml")); err != nil {
t.Skipf("symlinks unavailable: %v", err)
}
mainPath := writeImportFile(t, root, "main.yml", "configkit: {imports: [{path: escape.yml}]}\n")
mainPath := writeImportFile(t, root, "main.yml", "config: {imports: [{path: escape.yml}]}\n")
requireLoadCode(t, File(mainPath), Options[importTestConfig]{Imports: true}, CodeImportOutsideRoot)
})
@@ -1256,7 +1254,7 @@ func TestLoadImportsCanonicalSymlinksAndKeepsHardLinksDistinct(t *testing.T) {
if err := os.Link(one, filepath.Join(directory, "two.yml")); err != nil {
t.Skipf("hard links unavailable: %v", err)
}
mainPath := writeImportFile(t, directory, "main.yml", "configkit: {imports: [{path: one.yml}, {path: two.yml}]}\n")
mainPath := writeImportFile(t, directory, "main.yml", "config: {imports: [{path: one.yml}, {path: two.yml}]}\n")
requireLoadCode(t, File(mainPath), Options[importTestConfig]{Imports: true}, CodeComposeConflict)
})
@@ -1265,7 +1263,7 @@ func TestLoadImportsCanonicalSymlinksAndKeepsHardLinksDistinct(t *testing.T) {
if err := os.Symlink("loop.yml", filepath.Join(directory, "loop.yml")); err != nil {
t.Skipf("symlinks unavailable: %v", err)
}
mainPath := writeImportFile(t, directory, "main.yml", "configkit: {imports: [{path: loop.yml}]}\n")
mainPath := writeImportFile(t, directory, "main.yml", "config: {imports: [{path: loop.yml}]}\n")
requireLoadCode(t, File(mainPath), Options[importTestConfig]{Imports: true}, CodeImportInvalid)
})
}
@@ -1273,7 +1271,7 @@ func TestLoadImportsCanonicalSymlinksAndKeepsHardLinksDistinct(t *testing.T) {
func TestLoadByteAndReaderImportsRequireExplicitFilesystemContext(t *testing.T) {
directory := t.TempDir()
writeImportFile(t, directory, "fragment.yml", "settings: {first: imported}\n")
input := []byte("configkit: {imports: [{path: fragment.yml}]}\n")
input := []byte("config: {imports: [{path: fragment.yml}]}\n")
context := &FilesystemContext{BaseDir: directory, Root: directory}
for _, test := range []struct {
name string
@@ -1296,7 +1294,7 @@ func TestLoadByteAndReaderImportsRequireExplicitFilesystemContext(t *testing.T)
func TestFileImportRootCanContainTheSelectedFileDirectory(t *testing.T) {
root := t.TempDir()
mainPath := writeImportFile(t, root, "configs/main.yml", "configkit: {imports: [{path: ../shared.yml}]}\n")
mainPath := writeImportFile(t, root, "configs/main.yml", "config: {imports: [{path: ../shared.yml}]}\n")
writeImportFile(t, root, "shared.yml", "settings: {root: shared}\n")
result, err := testLoad[importTestConfig](File(mainPath), Options[importTestConfig]{
Imports: true, Filesystem: &FilesystemContext{Root: root},
@@ -1310,7 +1308,7 @@ func TestFileImportRootCanContainTheSelectedFileDirectory(t *testing.T) {
func TestImportedParseAndDecodeDiagnosticsKeepTheirSource(t *testing.T) {
t.Run("parse", func(t *testing.T) {
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", "configkit: {imports: [{path: broken.yml}]}\n")
mainPath := writeImportFile(t, directory, "main.yml", "config: {imports: [{path: broken.yml}]}\n")
writeImportFile(t, directory, "broken.yml", "settings: [\n")
loadError := requireAnyLoadError(t, File(mainPath), Options[importTestConfig]{Imports: true})
diagnostics := loadError.Diagnostics()
@@ -1321,7 +1319,7 @@ func TestImportedParseAndDecodeDiagnosticsKeepTheirSource(t *testing.T) {
t.Run("decode", func(t *testing.T) {
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", "configkit: {imports: [{path: unknown.yml}]}\n")
mainPath := writeImportFile(t, directory, "main.yml", "config: {imports: [{path: unknown.yml}]}\n")
writeImportFile(t, directory, "unknown.yml", "unknown: value\n")
loadError := requireLoadCode(t, File(mainPath), Options[importTestConfig]{Imports: true}, CodeDecodeUnknownField)
diagnostic := loadError.Diagnostics()[0]
@@ -1333,7 +1331,7 @@ func TestImportedParseAndDecodeDiagnosticsKeepTheirSource(t *testing.T) {
func TestOptionalImportDoesNotSuppressUnsafeOrUnreadableTargets(t *testing.T) {
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "outside.yml", "configkit: {imports: [{path: ../missing.yml}]}\n")
mainPath := writeImportFile(t, directory, "outside.yml", "config: {imports: [{path: ../missing.yml}]}\n")
requireLoadCode(t, File(mainPath), Options[importTestConfig]{Imports: true}, CodeImportOutsideRoot)
locked := writeImportFile(t, directory, "locked.yml", "settings: {root: locked}\n")
@@ -1345,13 +1343,13 @@ func TestOptionalImportDoesNotSuppressUnsafeOrUnreadableTargets(t *testing.T) {
_ = file.Close()
t.Skip("filesystem does not enforce the unreadable-file fixture")
}
mainPath = writeImportFile(t, directory, "main.yml", "configkit: {imports: [{path: locked.yml}]}\n")
mainPath = writeImportFile(t, directory, "main.yml", "config: {imports: [{path: locked.yml}]}\n")
requireLoadCode(t, File(mainPath), Options[importTestConfig]{Imports: true}, CodeSourcePermission)
}
func TestImportTraversalEnforcesPrivateBudgets(t *testing.T) {
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", "configkit: {imports: [{path: one.yml}, {path: two.yml}]}\n")
mainPath := writeImportFile(t, directory, "main.yml", "config: {imports: [{path: one.yml}, {path: two.yml}]}\n")
writeImportFile(t, directory, "one.yml", "settings: {first: one}\n")
writeImportFile(t, directory, "two.yml", "settings: {second: two}\n")
main := parseImportMain(t, mainPath)
@@ -1372,7 +1370,7 @@ func TestImportTraversalEnforcesPrivateBudgets(t *testing.T) {
})
}
writeImportFile(t, directory, "one.yml", "configkit: {imports: [{path: nested.yml}]}\n")
writeImportFile(t, directory, "one.yml", "config: {imports: [{path: nested.yml}]}\n")
writeImportFile(t, directory, "nested.yml", "settings: {nested: nested}\n")
main = parseImportMain(t, mainPath)
request := testImportRequest(File(mainPath), nil, main, Path{}, nil, nil)
@@ -1401,10 +1399,10 @@ func TestImportDepthBudgetCountsSelectedEdges(t *testing.T) {
} {
t.Run(test.name, func(t *testing.T) {
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", "configkit: {imports: [{path: leaf.yml}]}\n")
mainPath := writeImportFile(t, directory, "main.yml", "config: {imports: [{path: leaf.yml}]}\n")
leaf := "end: true\n"
if test.declaration != "" {
leaf += "configkit:\n imports:\n - " + test.declaration + "\n"
leaf += "config:\n imports:\n - " + test.declaration + "\n"
}
writeImportFile(t, directory, "leaf.yml", leaf)
writeImportFile(t, directory, "parts/next.yml", "next: true\n")
@@ -1428,7 +1426,7 @@ func TestImportDepthBudgetCountsSelectedEdges(t *testing.T) {
func TestImportTraversalAcceptsExactPrivateBudgets(t *testing.T) {
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", "configkit: {imports: [{path: imported.yml}]}\n")
mainPath := writeImportFile(t, directory, "main.yml", "config: {imports: [{path: imported.yml}]}\n")
importedPath := writeImportFile(t, directory, "imported.yml", "settings: {first: imported}\n")
main := parseImportMain(t, mainPath)
imported := parseImportMain(t, importedPath)

View File

@@ -21,18 +21,18 @@ func testGroupedLoad[T any](request loadRequest[T]) (*testResult[T], error) {
func TestUnderlayGroupSchedulesInterleavedImportBranches(t *testing.T) {
directory := t.TempDir()
zRoot := writeImportFile(t, directory, "z-root.yml", `configkit:
zRoot := writeImportFile(t, directory, "z-root.yml", `config:
imports:
- path: d-parent.yml
items: [{id: z}]
`)
dParent := writeImportFile(t, directory, "d-parent.yml", `configkit:
dParent := writeImportFile(t, directory, "d-parent.yml", `config:
imports:
- path: a-dependency.yml
items: [{id: d}]
`)
aDependency := writeImportFile(t, directory, "a-dependency.yml", "items: [{id: a}]\n")
bRoot := writeImportFile(t, directory, "b-root.yml", `configkit:
bRoot := writeImportFile(t, directory, "b-root.yml", `config:
imports:
- path: c-helper.yml
items: [{id: b}]
@@ -75,7 +75,7 @@ items: [{id: b}]
func TestUnderlayGroupAcquisitionRetainsScopesUntilComposition(t *testing.T) {
filesystem := NewFilesystem("handoff", fstest.MapFS{
"main.yml": &fstest.MapFile{Data: []byte("configkit: {imports: [{path: child.yml}]}\nmain: retained\n")},
"main.yml": &fstest.MapFile{Data: []byte("config: {imports: [{path: child.yml}]}\nmain: retained\n")},
"child.yml": &fstest.MapFile{Data: []byte("child: retained\n")},
})
accounting := &importAccounting{}
@@ -91,7 +91,7 @@ func TestUnderlayGroupAcquisitionRetainsScopesUntilComposition(t *testing.T) {
if len(acquired.sources) != 2 || acquired.sources[0].UnderlayIndex != 2 || acquired.sources[1].ID != "source-2" {
t.Fatalf("acquired source evidence = %#v", acquired.sources)
}
if acquired.inputBytes != int64(len("configkit: {imports: [{path: child.yml}]}\nmain: retained\n")+len("child: retained\n")) {
if acquired.inputBytes != int64(len("config: {imports: [{path: child.yml}]}\nmain: retained\n")+len("child: retained\n")) {
t.Fatalf("group input byte accounting = %d", acquired.inputBytes)
}
@@ -199,7 +199,7 @@ func TestUnderlayItemConflictUsesScheduledGroupIndex(t *testing.T) {
func TestUnderlayItemHelperConflictUsesScheduledGroupIndex(t *testing.T) {
directory := t.TempDir()
zBad := writeImportFile(t, directory, "z-bad.yml", "configkit: {imports: [{path: helper.yml}]}\nid: duplicate\n")
zBad := writeImportFile(t, directory, "z-bad.yml", "config: {imports: [{path: helper.yml}]}\nid: duplicate\n")
helper := writeImportFile(t, directory, "helper.yml", "id: duplicate\n")
aGood := writeImportFile(t, directory, "a-good.yml", "id: good\n")
request := loadRequest[map[string]any]{
@@ -246,7 +246,7 @@ func TestUnderlayItemHelperConflictUsesScheduledGroupIndex(t *testing.T) {
func TestGroupedLoadPrecedenceSourceOrderAndSingleLifecycle(t *testing.T) {
filesystem := NewFilesystem("bundle", fstest.MapFS{
"main.yml": &fstest.MapFile{Data: []byte("configkit: {imports: [{path: imported.yml}]}\nversion: v1\nport: 5\nsettings: {shared: main}\n")},
"main.yml": &fstest.MapFile{Data: []byte("config: {imports: [{path: imported.yml}]}\nversion: v1\nport: 5\nsettings: {shared: main}\n")},
"imported.yml": &fstest.MapFile{Data: []byte("settings: {imported: included}\n")},
"overlays/test.yml": &fstest.MapFile{Data: []byte("settings: {shared: overlay}\n")},
})
@@ -340,7 +340,7 @@ func TestGroupedLoadAbsentMainAndVersionProtection(t *testing.T) {
t.Fatalf("underlay version code = %s", got)
}
filesystem := NewFilesystem("bundle", fstest.MapFS{
"main.yml": &fstest.MapFile{Data: []byte("configkit: {imports: [{path: fragment.yml}]}\n")},
"main.yml": &fstest.MapFile{Data: []byte("config: {imports: [{path: fragment.yml}]}\n")},
"fragment.yml": &fstest.MapFile{Data: []byte("version: forbidden\n")},
})
request.underlays[1].inputs[0] = loadInput{source: filesystem.File("main.yml"), imports: true}
@@ -359,7 +359,7 @@ func TestGroupedLoadAbsentMainAndVersionProtection(t *testing.T) {
func TestLayeredCollectionPolicyFlowsBetweenTiers(t *testing.T) {
t.Parallel()
policyOnly := Bytes("lower-policy", []byte("configkit:\n sequences:\n - destination: [items]\n key: id\n mode: append\n"))
policyOnly := Bytes("lower-policy", []byte("config:\n sequences:\n - destination: [items]\n key: id\n mode: append\n"))
duplicate := func(name string) loadInput {
return loadInput{source: Bytes(name, []byte("items: [{id: repeated}]\n"))}
}
@@ -380,7 +380,7 @@ func TestLayeredCollectionPolicyFlowsBetweenTiers(t *testing.T) {
request = loadRequest[map[string]any]{
main: loadInput{source: NoSource()},
underlays: []loadGroup{
{inputs: []loadInput{{source: Bytes("lower", []byte("configkit:\n sequences:\n - destination: [items]\n key: id\n mode: append\nitems: [{id: repeated}]\n"))}}},
{inputs: []loadInput{{source: Bytes("lower", []byte("config:\n sequences:\n - destination: [items]\n key: id\n mode: append\nitems: [{id: repeated}]\n"))}}},
{inputs: []loadInput{duplicate("higher")}},
},
}
@@ -389,8 +389,8 @@ func TestLayeredCollectionPolicyFlowsBetweenTiers(t *testing.T) {
}
request = loadRequest[map[string]any]{
main: loadInput{source: Bytes("main", []byte("configkit:\n sequences:\n - destination: [items]\n key: name\n mode: replace\nitems: [{name: higher}]\n"))},
underlays: []loadGroup{{inputs: []loadInput{{source: Bytes("lower", []byte("configkit:\n sequences:\n - destination: [items]\n key: id\n mode: append\nitems: [{id: lower}]\n"))}}}},
main: loadInput{source: Bytes("main", []byte("config:\n sequences:\n - destination: [items]\n key: name\n mode: replace\nitems: [{name: higher}]\n"))},
underlays: []loadGroup{{inputs: []loadInput{{source: Bytes("lower", []byte("config:\n sequences:\n - destination: [items]\n key: id\n mode: append\nitems: [{id: lower}]\n"))}}}},
}
result, err := testGroupedLoad(request)
if err != nil || !reflect.DeepEqual(result.Config["items"], []any{map[string]any{"name": "higher"}}) {
@@ -402,7 +402,7 @@ func TestLayeredCollectionPolicyFlowsBetweenTiers(t *testing.T) {
}
filesystem := NewFilesystem("overlay", fstest.MapFS{
"overlays/testing.yml": &fstest.MapFile{Data: []byte("configkit:\n sequences:\n - destination: [items]\n key: id\n mode: append\nitems: [{id: overlay}]\n")},
"overlays/testing.yml": &fstest.MapFile{Data: []byte("config:\n sequences:\n - destination: [items]\n key: id\n mode: append\nitems: [{id: overlay}]\n")},
})
definition := Definition[map[string]any]{sequenceIdentityRegistrations: []sequenceIdentityRegistration{{selector: sequenceIdentitySelector{literalSequenceSelector("items")}, identityFields: []string{"id"}}}}
request = loadRequest[map[string]any]{
@@ -433,7 +433,7 @@ func TestGroupedLoadStrictConflictsRepetitionAndBudgets(t *testing.T) {
t.Fatalf("strict conflict code = %s", got)
}
conflicting := NewFilesystem("bundle", fstest.MapFS{
"main.yml": &fstest.MapFile{Data: []byte("configkit: {imports: [{path: fragment.yml}]}\nport: 1\n")},
"main.yml": &fstest.MapFile{Data: []byte("config: {imports: [{path: fragment.yml}]}\nport: 1\n")},
"fragment.yml": &fstest.MapFile{Data: []byte("port: 2\n")},
})
request.main = loadInput{source: conflicting.File("main.yml"), imports: true}
@@ -514,9 +514,9 @@ func groupedErrorCode(t *testing.T, err error) Code {
func TestGroupedAccountingChargesMixedOccurrencesOnce(t *testing.T) {
const (
one = "configkit: {imports: [{path: child-one.yml}]}\nleft: first\n"
one = "config: {imports: [{path: child-one.yml}]}\nleft: first\n"
child = "extra: imported\n"
two = "configkit: {imports: [{path: child-two.yml}]}\nright: second\n"
two = "config: {imports: [{path: child-two.yml}]}\nright: second\n"
)
filesystem := NewFilesystem("bundle", fstest.MapFS{
"one.yml": &fstest.MapFile{Data: []byte(one)},
@@ -551,7 +551,7 @@ func TestGroupedAccountingChargesMixedOccurrencesOnce(t *testing.T) {
func TestGroupedGlobEntryBudgetIsShared(t *testing.T) {
filesystem := NewFilesystem("bundle", fstest.MapFS{
"main.yml": &fstest.MapFile{Data: []byte("configkit: {imports: [{glob: 'parts/*.yml'}]}\n")},
"main.yml": &fstest.MapFile{Data: []byte("config: {imports: [{glob: 'parts/*.yml'}]}\n")},
"parts/a.yml": &fstest.MapFile{Data: []byte("left: one\n")},
"parts/b.yml": &fstest.MapFile{Data: []byte("right: two\n")},
})

View File

@@ -11,7 +11,7 @@ import (
func TestNativeFilesystemImportsAndOverlay(t *testing.T) {
filesystem := fstest.MapFS{
"config/main.yml": &fstest.MapFile{Data: []byte(`configkit:
"config/main.yml": &fstest.MapFile{Data: []byte(`config:
imports:
- path: ../shared.yml
- glob: fragments/*.yml
@@ -52,8 +52,8 @@ func TestNativeFilesystemItemImportUsesSharedScopedAssembly(t *testing.T) {
Items []item `yaml:"items"`
}
filesystem := fstest.MapFS{
"main.yml": &fstest.MapFile{Data: []byte("configkit:\n imports:\n - path: records/item.yml\n destination: [items]\n placement: sequence-item\n")},
"records/item.yml": &fstest.MapFile{Data: []byte("configkit:\n imports:\n - path: helper.yml\nid: native\n")},
"main.yml": &fstest.MapFile{Data: []byte("config:\n imports:\n - path: records/item.yml\n destination: [items]\n placement: sequence-item\n")},
"records/item.yml": &fstest.MapFile{Data: []byte("config:\n imports:\n - path: helper.yml\nid: native\n")},
"records/helper.yml": &fstest.MapFile{Data: []byte("name: helper\n")},
}
namespace := newNativeNamespace("bundle", filesystem)
@@ -109,7 +109,7 @@ func TestNativeFilesystemNamespaceAndPathFailures(t *testing.T) {
t.Errorf("%q diagnostics = %#v", name, diagnostics)
}
}
missingImport := fstest.MapFS{"main.yml": &fstest.MapFile{Data: []byte("configkit: {imports: [{path: host-only.yml, required: true}]}\n")}}
missingImport := fstest.MapFS{"main.yml": &fstest.MapFile{Data: []byte("config: {imports: [{path: host-only.yml, required: true}]}\n")}}
_, err := testLoad[importTestConfig](filesystemFile(newNativeNamespace("bundle", missingImport), "main.yml"), Options[importTestConfig]{Imports: true})
if err == nil {
t.Fatal("missing virtual import fell back to the host filesystem")
@@ -124,7 +124,7 @@ func TestNativeFilesystemClosesFilesOnSuccessAndFailure(t *testing.T) {
for _, fallback := range []bool{false, true} {
t.Run(map[bool]string{false: "ReadDirFile", true: "ReadDir fallback"}[fallback], func(t *testing.T) {
filesystem := &observedFilesystem{files: fstest.MapFS{
"main.yml": &fstest.MapFile{Data: []byte("configkit: {imports: [{glob: 'parts/*.yml'}]}\nitems: {main: main}\n")},
"main.yml": &fstest.MapFile{Data: []byte("config: {imports: [{glob: 'parts/*.yml'}]}\nitems: {main: main}\n")},
"parts/one.yml": &fstest.MapFile{Data: []byte("items: {one: one}\n")},
}, fallback: fallback}
result, err := testLoad[importTestConfig](filesystemFile(newNativeNamespace("bundle", filesystem), "main.yml"), Options[importTestConfig]{Imports: true})
@@ -149,7 +149,7 @@ func TestNativeFilesystemClosesFilesOnSuccessAndFailure(t *testing.T) {
} {
t.Run(failure.name, func(t *testing.T) {
filesystem := &observedFilesystem{files: fstest.MapFS{
"main.yml": &fstest.MapFile{Data: []byte("configkit: {imports: [{glob: 'parts/*.yml'}]}\n")},
"main.yml": &fstest.MapFile{Data: []byte("config: {imports: [{glob: 'parts/*.yml'}]}\n")},
"parts/one.yml": &fstest.MapFile{Data: []byte(failure.file)},
}, failRead: failure.failRead, failStat: failure.failStat, failDir: failure.failDir}
_, err := testLoad[importTestConfig](filesystemFile(newNativeNamespace("bundle", filesystem), "main.yml"), Options[importTestConfig]{Imports: true})
@@ -166,7 +166,7 @@ func TestNativeFilesystemClosesFilesOnSuccessAndFailure(t *testing.T) {
func TestNativeFilesystemRootAndOptionalImports(t *testing.T) {
filesystem := fstest.MapFS{
"config/sub/main.yml": &fstest.MapFile{Data: []byte(`configkit:
"config/sub/main.yml": &fstest.MapFile{Data: []byte(`config:
imports:
- path: ../shared.yml
- path: absent.yml
@@ -193,7 +193,7 @@ func TestNativeFilesystemRootAndOptionalImports(t *testing.T) {
}
outside := fstest.MapFS{
"config/sub/main.yml": &fstest.MapFile{Data: []byte("configkit: {imports: [{path: ../../outside.yml}]}\n")},
"config/sub/main.yml": &fstest.MapFile{Data: []byte("config: {imports: [{path: ../../outside.yml}]}\n")},
"outside.yml": &fstest.MapFile{Data: []byte("items: {outside: blocked}\n")},
}
outsideNamespace := newNativeNamespace("bundle", outside)
@@ -221,7 +221,7 @@ func TestNativeFilesystemDetectsRepeatedAndCyclicImports(t *testing.T) {
{
name: "repeated",
files: fstest.MapFS{
"main.yml": &fstest.MapFile{Data: []byte("configkit: {imports: [{path: child.yml}, {path: child.yml}]}\n")},
"main.yml": &fstest.MapFile{Data: []byte("config: {imports: [{path: child.yml}, {path: child.yml}]}\n")},
"child.yml": &fstest.MapFile{Data: []byte("items: {child: child}\n")},
},
code: CodeImportRepeated,
@@ -229,8 +229,8 @@ func TestNativeFilesystemDetectsRepeatedAndCyclicImports(t *testing.T) {
{
name: "cycle",
files: fstest.MapFS{
"main.yml": &fstest.MapFile{Data: []byte("configkit: {imports: [{path: child.yml}]}\n")},
"child.yml": &fstest.MapFile{Data: []byte("configkit: {imports: [{path: main.yml}]}\n")},
"main.yml": &fstest.MapFile{Data: []byte("config: {imports: [{path: child.yml}]}\n")},
"child.yml": &fstest.MapFile{Data: []byte("config: {imports: [{path: main.yml}]}\n")},
},
code: CodeImportCycle,
},

View File

@@ -28,7 +28,7 @@ type layeredConfig struct {
func TestLayeredProvenanceAgreesWithResolvedSnapshot(t *testing.T) {
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", `configkit:
mainPath := writeImportFile(t, directory, "main.yml", `config:
imports: [{path: imported.yml}]
shared: {equal: same}
values: [1, 2]
@@ -209,7 +209,7 @@ func TestSelectedOverlayLoadsRemainIndependentConcurrently(t *testing.T) {
func TestResolutionInputKeepsLayeredOriginsAndSources(t *testing.T) {
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", `configkit:
mainPath := writeImportFile(t, directory, "main.yml", `config:
imports: [{path: first.yml}, {path: second.yml}]
main: main
equal: same
@@ -361,7 +361,7 @@ func TestResolutionInputDistinguishesNonFileRootsAndImportedFiles(t *testing.T)
Imported string `yaml:"imported"`
Default string `yaml:"default"`
}
input := "configkit: {imports: [{path: fragment.yml}]}\nroot: memory\n"
input := "config: {imports: [{path: fragment.yml}]}\nroot: memory\n"
context := &FilesystemContext{BaseDir: directory, Root: directory}
for _, test := range []struct {
name string

View File

@@ -151,11 +151,11 @@ func TestLoadingClosesNativeFilesAcrossPipelineOutcomes(t *testing.T) {
{name: "success", main: "value: retained\n"},
{name: "acquisition", main: "value: retained\n", failRead: "main.yml", wantErr: true},
{name: "parse", main: "value: [broken\n", wantErr: true},
{name: "composition", main: "configkit: {imports: [{path: child.yml}]}\nvalue: first\n", child: "value: second\n", options: Options[config]{Imports: true}, wantErr: true},
{name: "composition", main: "config: {imports: [{path: child.yml}]}\nvalue: first\n", child: "value: second\n", options: Options[config]{Imports: true}, wantErr: true},
{
name: "nested item composition",
main: "configkit: {imports: [{path: child.yml, destination: [children], placement: sequence-item}]}\nid: parent\n",
child: "configkit: {imports: [{path: helper.yml}]}\nid: child\nvalue: child\n",
main: "config: {imports: [{path: child.yml, destination: [children], placement: sequence-item}]}\nid: parent\n",
child: "config: {imports: [{path: helper.yml}]}\nid: child\nvalue: child\n",
helper: "value: helper\n",
options: Options[config]{
Imports: true, Destination: Keys("groups"), PlacementMode: PlacementModeSequenceItem,
@@ -206,7 +206,7 @@ func TestDirectorySelectorsFailOnPostOpenNotExistErrors(t *testing.T) {
{name: "glob no progress", selector: "glob", noProgress: true},
} {
t.Run(test.name, func(t *testing.T) {
main := "configkit:\n imports:\n"
main := "config:\n imports:\n"
if test.selector == "directory" {
main += " - dir: [broken, good]\n pattern: '*.yml'\n"
} else {
@@ -324,7 +324,7 @@ func TestReadDirectoryVisitStopCloseNotExistIsPostOpen(t *testing.T) {
func TestDirectorySelectorsKeepMissingRootsOptional(t *testing.T) {
for _, selector := range []string{"directory", "glob"} {
t.Run(selector, func(t *testing.T) {
main := "configkit:\n imports:\n"
main := "config:\n imports:\n"
if selector == "directory" {
main += " - dir: [missing, good]\n pattern: '*.yml'\n required: true\n"
} else {
@@ -347,7 +347,7 @@ func TestDirectorySelectorsKeepMissingRootsOptional(t *testing.T) {
func TestDirectorySelectorsTreatMissingOnOpenAsOptional(t *testing.T) {
for _, selector := range []string{"directory", "glob"} {
t.Run(selector, func(t *testing.T) {
main := "configkit:\n imports:\n"
main := "config:\n imports:\n"
if selector == "directory" {
main += " - dir: [broken, good]\n pattern: '*.yml'\n required: true\n"
} else {

View File

@@ -43,7 +43,7 @@ func TestNonregularSourcesDoNotBlock(t *testing.T) {
root := t.TempDir()
input := "value: 1\n"
if mode == "import" {
input = "configkit:\n imports:\n - path: pipe.yml\n"
input = "config:\n imports:\n - path: pipe.yml\n"
}
if err := os.WriteFile(filepath.Join(root, "config.yml"), []byte(input), 0600); err != nil {
t.Fatal(err)

View File

@@ -87,7 +87,7 @@ func BenchmarkUnderlayNativeImports(b *testing.B) {
for _, count := range []int{16, 32, 64} {
b.Run(strconv.Itoa(count), func(b *testing.B) {
files := fstest.MapFS{
"main.yml": &fstest.MapFile{Data: []byte("configkit: {imports: [{glob: 'defaults/*.yml'}]}\n")},
"main.yml": &fstest.MapFile{Data: []byte("config: {imports: [{glob: 'defaults/*.yml'}]}\n")},
}
for index := range count {
name := "item-" + strconv.Itoa(index)