Verify mounted diagnostic paths and locations
This commit is contained in:
142
internal/engine/destination_diagnostic_test.go
Normal file
142
internal/engine/destination_diagnostic_test.go
Normal file
@@ -0,0 +1,142 @@
|
||||
package engine
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"testing/fstest"
|
||||
)
|
||||
|
||||
func TestLayeredDestinationDiagnosticsUseEffectivePathsAndAuthoredLocations(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
t.Run("strict conflict retains both source locations", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
loaded, err := LoadLayered(
|
||||
Input{Source: NoSource()},
|
||||
testSecretBinding(),
|
||||
LayeredOptions[map[string]any]{Underlays: []Underlay{{Inputs: []Input{
|
||||
{Source: Bytes("left", []byte("section:\n value: left\n")), Destination: Keys("application")},
|
||||
{Source: Bytes("right", []byte("section:\n value: right\n")), Destination: Keys("application")},
|
||||
}}}},
|
||||
)
|
||||
if loaded != nil {
|
||||
t.Fatalf("conflicting load returned a result: %#v", loaded)
|
||||
}
|
||||
diagnostic := firstDestinationDiagnostic(t, err)
|
||||
if diagnostic.Code != CodeComposeConflict || diagnostic.Path.String() != "/application/section/value" {
|
||||
t.Fatalf("conflict diagnostic = %#v", diagnostic)
|
||||
}
|
||||
if diagnostic.Primary == nil || diagnostic.Primary.SourceID != "source-1" || diagnostic.Primary.Line != 2 {
|
||||
t.Fatalf("primary location = %#v", diagnostic.Primary)
|
||||
}
|
||||
if len(diagnostic.Related) != 1 || diagnostic.Related[0].SourceID != "source-2" || diagnostic.Related[0].Line != 2 {
|
||||
t.Fatalf("related locations = %#v", diagnostic.Related)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("decode failure keeps effective path and content line", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
type section struct {
|
||||
Count int `yaml:"count"`
|
||||
}
|
||||
type config struct {
|
||||
Application struct {
|
||||
Section section `yaml:"section"`
|
||||
} `yaml:"application"`
|
||||
}
|
||||
loaded, err := LoadLayered(
|
||||
Input{Source: Bytes("main", []byte("section:\n count: invalid\n")), Destination: Keys("application")},
|
||||
testSecretBinding(),
|
||||
LayeredOptions[config]{},
|
||||
)
|
||||
if loaded != nil {
|
||||
t.Fatalf("invalid load returned a result: %#v", loaded)
|
||||
}
|
||||
diagnostic := firstDestinationDiagnostic(t, err)
|
||||
if diagnostic.Code != CodeDecodeType || diagnostic.Path.String() != "/application/section/count" {
|
||||
t.Fatalf("decode diagnostic = %#v", diagnostic)
|
||||
}
|
||||
if diagnostic.Primary == nil || diagnostic.Primary.SourceID != "source-1" || diagnostic.Primary.Line != 2 {
|
||||
t.Fatalf("decode location = %#v", diagnostic.Primary)
|
||||
}
|
||||
})
|
||||
|
||||
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, "fragment.yml", "version: forbidden\n")
|
||||
rule := &VersionRule{Path: Keys("application", "version"), Check: func(Version, *Validation) error { return nil }}
|
||||
loaded, err := LoadLayered(
|
||||
Input{Source: NoSource()},
|
||||
testSecretBinding(),
|
||||
LayeredOptions[map[string]any]{
|
||||
Definition: Definition[map[string]any]{Version: rule},
|
||||
Underlays: []Underlay{{Inputs: []Input{{
|
||||
Source: File(filepath.Join(directory, "main.yml")), Imports: true, Destination: Keys("application"),
|
||||
}}}},
|
||||
},
|
||||
)
|
||||
if loaded != nil {
|
||||
t.Fatalf("invalid import returned a result: %#v", loaded)
|
||||
}
|
||||
diagnostic := firstDestinationDiagnostic(t, err)
|
||||
if diagnostic.Code != CodeImportVersion || diagnostic.Path.String() != "/application/version" {
|
||||
t.Fatalf("import version diagnostic = %#v", diagnostic)
|
||||
}
|
||||
if diagnostic.Primary == nil || diagnostic.Primary.SourceID != "source-2" || diagnostic.Primary.Line != 1 {
|
||||
t.Fatalf("import version location = %#v", diagnostic.Primary)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("invalid destination has no fictional source location", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
loaded, err := LoadLayered(
|
||||
Input{Source: Bytes("main", []byte("value: present\n")), Destination: Keys("configkit")},
|
||||
testSecretBinding(),
|
||||
LayeredOptions[map[string]any]{},
|
||||
)
|
||||
if loaded != nil {
|
||||
t.Fatalf("invalid destination returned a result: %#v", loaded)
|
||||
}
|
||||
diagnostic := firstDestinationDiagnostic(t, err)
|
||||
if diagnostic.Code != CodeOptionsInvalid || diagnostic.Path.String() != "/configkit" || diagnostic.Primary != nil {
|
||||
t.Fatalf("invalid destination diagnostic = %#v", diagnostic)
|
||||
}
|
||||
})
|
||||
|
||||
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")},
|
||||
})
|
||||
loaded, err := LoadLayered(
|
||||
Input{Source: filesystem.File("main.yml"), Imports: true, Destination: Keys("application")},
|
||||
testSecretBinding(),
|
||||
LayeredOptions[map[string]any]{},
|
||||
)
|
||||
if loaded != nil {
|
||||
t.Fatalf("malformed directive returned a result: %#v", loaded)
|
||||
}
|
||||
diagnostic := firstDestinationDiagnostic(t, err)
|
||||
if diagnostic.Code != CodeImportInvalid || diagnostic.Path.String() != "/configkit/imports/0" {
|
||||
t.Fatalf("malformed directive diagnostic = %#v", diagnostic)
|
||||
}
|
||||
if diagnostic.Primary == nil || diagnostic.Primary.SourceID != "source-1" || diagnostic.Primary.Line != 1 {
|
||||
t.Fatalf("malformed directive location = %#v", diagnostic.Primary)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func firstDestinationDiagnostic(t *testing.T, err error) Diagnostic {
|
||||
t.Helper()
|
||||
loadError, ok := err.(*LoadError)
|
||||
if !ok {
|
||||
t.Fatalf("load error = %#v", err)
|
||||
}
|
||||
diagnostics := loadError.Diagnostics()
|
||||
if len(diagnostics) == 0 {
|
||||
t.Fatal("load error has no diagnostics")
|
||||
}
|
||||
return diagnostics[0]
|
||||
}
|
||||
Reference in New Issue
Block a user