package engine import ( "reflect" "testing" "go.maximumdirect.net/configkit/internal/document" ) func TestDocumentRootControlScope(t *testing.T) { root := parseRootDirectiveDocument(t, `config: imports: [{path: fragment.yaml}] sequences: [] service: config: {imports: ordinary, sequences: ordinary} records: - config: {imports: ordinary} configkit: {imports: [{path: absent.yaml}]} _configkit: ordinary `) extracted, diagnostics := extractRootDirectives(root, rootDirectiveContextSource) if len(diagnostics) != 0 || len(extracted.imports) != 1 { t.Fatalf("extraction = %#v, diagnostics = %#v", extracted, diagnostics) } if len(root.Mapping) != 5 || len(extracted.body.Mapping) != 4 { t.Fatalf("source mutated or payload lost: root=%#v body=%#v", root.Mapping, extracted.body.Mapping) } for _, key := range []string{"service", "records", "configkit", "_configkit"} { got := documentEntryIndex(extracted.body.Mapping, key) if got < 0 { t.Errorf("payload missing %q", key) continue } original := documentEntryIndex(root.Mapping, key) if !reflect.DeepEqual(extracted.body.Mapping[got].Value, root.Mapping[original].Value) { t.Errorf("payload for %q changed", key) } } for _, guard := range []func(*document.Node) []Diagnostic{ func(node *document.Node) []Diagnostic { return disabledDirectiveDiagnostics(node, Path{}) }, disabledRootImportDiagnostics, func(node *document.Node) []Diagnostic { return overlayDirectiveDiagnostics(node, Path{}, true) }, } { if got := guard(extracted.body); len(got) != 0 { t.Errorf("nested application data rejected: %#v", got) } } } func TestDocumentRootControlValidation(t *testing.T) { for _, test := range []struct { name string input string code Code path string }{ {"not a mapping", "config: wrong\n", CodeImportInvalid, "/config"}, {"unknown field", "config: {unknown: true}\n", CodeImportInvalid, "/config/unknown"}, {"bad imports", "config: {imports: wrong}\n", CodeImportInvalid, "/config/imports"}, } { t.Run(test.name, func(t *testing.T) { _, diagnostics := extractRootDirectives(parseRootDirectiveDocument(t, test.input), rootDirectiveContextSource) if len(diagnostics) == 0 || diagnostics[0].Code != test.code || diagnostics[0].Path.String() != test.path { t.Fatalf("diagnostics = %#v", diagnostics) } }) } } func TestDocumentRootControlGuards(t *testing.T) { imports := parseRootDirectiveDocument(t, "config: {imports: [{path: fragment.yaml}]}\n") for _, got := range [][]Diagnostic{disabledDirectiveDiagnostics(imports, Path{}), disabledRootImportDiagnostics(imports)} { if len(got) != 1 || got[0].Code != CodeImportDisabled || got[0].Path.String() != "/config" { t.Fatalf("disabled diagnostics = %#v", got) } } if got := overlayDirectiveDiagnostics(imports, Path{}, true); len(got) != 1 || got[0].Code != CodeOverlayDirective { t.Fatalf("overlay imports diagnostics = %#v", got) } sequences := parseRootDirectiveDocument(t, "config: {sequences: []}\n") if got := disabledRootImportDiagnostics(sequences); len(got) != 0 { t.Fatalf("sequences with imports disabled = %#v", got) } if got := disabledDirectiveDiagnostics(sequences, Path{}); len(got) != 1 || got[0].Code != CodeImportDisabled { t.Fatalf("imports-only guard = %#v", got) } if got := overlayDirectiveDiagnostics(sequences, Path{}, true); len(got) != 0 { t.Fatalf("overlay sequences diagnostics = %#v", got) } if _, got := extractRootDirectives(sequences, rootDirectiveContextImportsOnly); len(got) == 0 || got[0].Code != CodeSequenceInvalid { t.Fatalf("imports-only extraction diagnostics = %#v", got) } }