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] }