Retain import inclusion graph during acquisition
This commit is contained in:
@@ -656,6 +656,22 @@ 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:
|
||||
imports:
|
||||
- path: item.yml
|
||||
destination: [items]
|
||||
placement: sequence-item
|
||||
`)
|
||||
writeImportFile(t, directory, "item.yml", "configkit: {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") {
|
||||
t.Fatalf("nested item cycle diagnostic = %#v", diagnostic)
|
||||
}
|
||||
})
|
||||
|
||||
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")
|
||||
@@ -686,6 +702,61 @@ func TestLoadImportIdentityReportsCyclesAndRepeatedRoutes(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestItemAcquisitionRetainsInclusionGraphAndScopeOwnership(t *testing.T) {
|
||||
directory := t.TempDir()
|
||||
mainPath := writeImportFile(t, directory, "main.yml", `configkit:
|
||||
imports:
|
||||
- path: item.yml
|
||||
destination: [items]
|
||||
placement: sequence-item
|
||||
`)
|
||||
itemPath := writeImportFile(t, directory, "item.yml", "configkit: {imports: [{path: helper.yml}]}\nname: item\n")
|
||||
helperPath := writeImportFile(t, directory, "helper.yml", "id: supplied\n")
|
||||
|
||||
input, diagnostics := assembleBaseInput[importTestConfig](File(mainPath), Options[importTestConfig]{Imports: true})
|
||||
if len(diagnostics) != 0 {
|
||||
t.Fatalf("assemble input: %#v", diagnostics)
|
||||
}
|
||||
graph := input.composition.importGraph
|
||||
if len(graph.nodes) != 3 || len(graph.edges) != 2 {
|
||||
t.Fatalf("inclusion graph has %d nodes and %d edges, want 3 and 2", len(graph.nodes), len(graph.edges))
|
||||
}
|
||||
for index, want := range []struct {
|
||||
path string
|
||||
role importContributionRole
|
||||
}{
|
||||
{path: canonicalTestPath(t, mainPath), role: importRoleMain},
|
||||
{path: canonicalTestPath(t, itemPath), role: importRoleItem},
|
||||
{path: canonicalTestPath(t, helperPath), role: importRoleMapping},
|
||||
} {
|
||||
node := graph.nodes[index]
|
||||
if node.canonical != want.path || node.role != want.role || node.sourceID != "source-"+strconv.Itoa(index+1) {
|
||||
t.Errorf("graph node %d = %#v, want %s, %q, source-%d", index, node, want.role, want.path, index+1)
|
||||
}
|
||||
}
|
||||
rootScope := input.composition.acquisition[0]
|
||||
if rootScope.owner != graph.nodes[0].key || len(rootScope.contributions) != 2 {
|
||||
t.Fatalf("root acquisition scope = %#v", rootScope)
|
||||
}
|
||||
item := rootScope.contributions[1]
|
||||
if item.identity != graph.nodes[1].key || item.role != importRoleItem || item.scopeOwner != rootScope.owner || item.nested == nil {
|
||||
t.Fatalf("outer item contribution = %#v", item)
|
||||
}
|
||||
itemScope := item.nested.acquisition[0]
|
||||
if itemScope.owner != item.identity || len(itemScope.contributions) != 2 {
|
||||
t.Fatalf("nested item scope = %#v", itemScope)
|
||||
}
|
||||
for _, contribution := range itemScope.contributions {
|
||||
if contribution.scopeOwner != item.identity {
|
||||
t.Errorf("nested contribution scope owner = %#v, want item %v", contribution.scopeOwner, item.identity)
|
||||
}
|
||||
}
|
||||
if graph.edges[0].importer != graph.nodes[0].key || graph.edges[0].imported != graph.nodes[1].key || graph.edges[0].location.SourceID != "source-1" ||
|
||||
graph.edges[1].importer != graph.nodes[1].key || graph.edges[1].imported != graph.nodes[2].key || graph.edges[1].location.SourceID != "source-2" {
|
||||
t.Fatalf("inclusion edges = %#v", graph.edges)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadImportsCanonicalSymlinksAndKeepsHardLinksDistinct(t *testing.T) {
|
||||
if runtime.GOOS != "linux" && runtime.GOOS != "darwin" {
|
||||
t.Skip("initial filesystem contract covers Linux and macOS")
|
||||
|
||||
Reference in New Issue
Block a user