Migrate acquisition fixtures to document-root controls
This commit is contained in:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user