| // Copyright (c) The OpenTofu Authors | |
| // SPDX-License-Identifier: MPL-2.0 | |
| // Copyright (c) 2023 HashiCorp, Inc. | |
| // SPDX-License-Identifier: MPL-2.0 | |
| package views | |
| import ( | |
| "encoding/json" | |
| "testing" | |
| "github.com/google/go-cmp/cmp" | |
| "github.com/opentofu/opentofu/internal/tfdiags" | |
| ) | |
| func TestMetadataFunctions_Diagnostics(t *testing.T) { | |
| tests := map[string]struct { | |
| viewCall func(v MetadataFunctions) | |
| wantStdout string | |
| wantStderr string | |
| }{ | |
| // Diagnostics | |
| "warning": { | |
| viewCall: func(v MetadataFunctions) { | |
| diags := tfdiags.Diagnostics{ | |
| tfdiags.Sourceless(tfdiags.Warning, "A warning occurred", "foo bar"), | |
| } | |
| v.Diagnostics(diags) | |
| }, | |
| wantStdout: withNewline("\nWarning: A warning occurred\n\nfoo bar"), | |
| wantStderr: "", | |
| }, | |
| "error": { | |
| viewCall: func(v MetadataFunctions) { | |
| diags := tfdiags.Diagnostics{ | |
| tfdiags.Sourceless(tfdiags.Error, "An error occurred", "foo bar"), | |
| } | |
| v.Diagnostics(diags) | |
| }, | |
| wantStdout: "", | |
| wantStderr: withNewline("\nError: An error occurred\n\nfoo bar"), | |
| }, | |
| "multiple_diagnostics": { | |
| viewCall: func(v MetadataFunctions) { | |
| diags := tfdiags.Diagnostics{ | |
| tfdiags.Sourceless(tfdiags.Warning, "A warning", "foo bar warning"), | |
| tfdiags.Sourceless(tfdiags.Error, "An error", "foo bar error"), | |
| } | |
| v.Diagnostics(diags) | |
| }, | |
| wantStdout: withNewline("\nWarning: A warning\n\nfoo bar warning"), | |
| wantStderr: withNewline("\nError: An error\n\nfoo bar error"), | |
| }, | |
| } | |
| for name, tc := range tests { | |
| t.Run(name, func(t *testing.T) { | |
| testMetadataFunctions(t, tc.viewCall, tc.wantStdout, tc.wantStderr) | |
| }) | |
| } | |
| } | |
| func TestMetadataFunctions_printFunctions(t *testing.T) { | |
| view, done := testView(t) | |
| v := NewMetadataFunctions(view) | |
| status := v.PrintFunctions() | |
| output := done(t) | |
| if !status { | |
| t.Fatalf("failed to generate the functions output: %s", output.All()) | |
| } | |
| var got functions | |
| gotString := output.Stdout() | |
| err := json.Unmarshal([]byte(gotString), &got) | |
| if err != nil { | |
| t.Fatal(err) | |
| } | |
| if len(got.Signatures) < 100 { | |
| t.Fatalf("expected at least 100 function signatures, got %d", len(got.Signatures)) | |
| } | |
| // check if one particular stable function is correct | |
| gotMax, ok := got.Signatures["max"] | |
| wantMax := "{\"description\":\"`max` takes one or more numbers and returns the greatest number from the set.\",\"return_type\":\"number\",\"variadic_parameter\":{\"name\":\"numbers\",\"type\":\"number\"}}" | |
| if !ok { | |
| t.Fatal(`missing function signature for "max"`) | |
| } | |
| if string(gotMax) != wantMax { | |
| t.Fatalf("wrong function signature for \"max\":\ngot: %q\nwant: %q", gotMax, wantMax) | |
| } | |
| stderr := output.Stderr() | |
| if stderr != "" { | |
| t.Fatalf("expected empty stderr, got:\n%s", stderr) | |
| } | |
| // test that ignored functions are not part of the json | |
| for _, v := range ignoredFunctions { | |
| if _, ok := got.Signatures[v.Name]; ok { | |
| t.Errorf("found ignored function %q inside output", v) | |
| } | |
| corePrefixed := v.String() | |
| if _, ok := got.Signatures[corePrefixed]; ok { | |
| t.Fatalf("found ignored function %q inside output", corePrefixed) | |
| } | |
| } | |
| } | |
| type functions struct { | |
| FormatVersion string `json:"format_version"` | |
| Signatures map[string]json.RawMessage `json:"function_signatures,omitempty"` | |
| } | |
| func testMetadataFunctions(t *testing.T, call func(v MetadataFunctions), wantStdout, wantStderr string) { | |
| view, done := testView(t) | |
| v := NewMetadataFunctions(view) | |
| call(v) | |
| output := done(t) | |
| if diff := cmp.Diff(wantStderr, output.Stderr()); diff != "" { | |
| t.Errorf("invalid stderr (-want, +got):\n%s", diff) | |
| } | |
| if diff := cmp.Diff(wantStdout, output.Stdout()); diff != "" { | |
| t.Errorf("invalid stdout (-want, +got):\n%s", diff) | |
| } | |
| } |