package ckconfig import ( "bytes" "context" "encoding/json" "errors" "io" "reflect" "strings" "testing" commandkit "go.maximumdirect.net/commandkit" configkit "go.maximumdirect.net/configkit" ) func TestFocusedShowUsesSafeNativeValue(t *testing.T) { loads := 0 scope := FromConfigKit("app", "", func(_ context.Context, selection Selection, _, _ struct{}) (*configkit.Result[map[string]any], error) { loads++ return configkit.Load(configkit.Mapping("fixture", map[string]any{"object": map[string]any{"x": "y"}, "text": "hello", "false": false, "zero": 0, "null": nil, "gone": map[string]any{"x": 1}}), configkit.Options[map[string]any]{Overrides: selection.Overrides}) }) scope.Features.Overrides = true app := newConfigTestApp(t, Command(Suite[struct{}, struct{}]{Scopes: []Scope[struct{}, struct{}]{scope}})) for _, test := range []struct { path string want any }{{"/object", map[string]any{"x": "y"}}, {"/text", "hello"}, {"/false", false}, {"/zero", float64(0)}, {"/null", nil}} { var out bytes.Buffer result := app.Execute(context.Background(), []string{"config", "show", "--path=" + test.path, "--format=json"}, commandkit.Streams{Out: &out, Err: io.Discard}) var got any if result.Kind != commandkit.OutcomeSuccess || json.Unmarshal(out.Bytes(), &got) != nil || !reflect.DeepEqual(got, test.want) { t.Fatalf("%s: %#v %q", test.path, result, out.String()) } } var out bytes.Buffer result := app.Execute(context.Background(), []string{"config", "show", "--path=/text"}, commandkit.Streams{Out: &out, Err: io.Discard}) if result.Kind != commandkit.OutcomeSuccess || out.String() != "hello\n" { t.Fatalf("automatic text: %#v %q", result, out.String()) } out.Reset() result = app.Execute(context.Background(), []string{"config", "show", "--path=/false", "--format=yaml"}, commandkit.Streams{Out: &out, Err: io.Discard}) if result.Kind != commandkit.OutcomeSuccess || strings.TrimSpace(out.String()) != "false" { t.Fatalf("yaml false: %#v %q", result, out.String()) } for _, args := range [][]string{{"--path=/missing"}, {"--path=/gone/x", "--set=/gone=null"}} { result = app.Execute(context.Background(), append([]string{"config", "show"}, args...), commandkit.Streams{Out: io.Discard, Err: io.Discard}) if result.Kind != commandkit.OutcomeOperational { t.Fatalf("missing %v: %#v", args, result) } } before := loads for _, args := range [][]string{{"--path=bad"}, {"--scope=all", "--path=/text"}} { result = app.Execute(context.Background(), append([]string{"config", "show"}, args...), commandkit.Streams{Out: io.Discard, Err: io.Discard}) if result.Kind != commandkit.OutcomeUsage || loads != before { t.Fatalf("preflight %v: %#v", args, result) } } } func TestFocusedShowChecksCapabilityAndFacet(t *testing.T) { calls := 0 scope := Scope[struct{}, struct{}]{Name: "app", Operations: []Operation{Show}, Acquire: func(context.Context, Request, struct{}, struct{}) (commandkit.Acquired[View], error) { calls++ return commandkit.Acquired[View]{}, nil }} app := newConfigTestApp(t, Command(Suite[struct{}, struct{}]{Scopes: []Scope[struct{}, struct{}]{scope}})) result := app.Execute(context.Background(), []string{"config", "show", "--path=/x"}, commandkit.Streams{Out: io.Discard, Err: io.Discard}) if result.Kind != commandkit.OutcomeUsage || calls != 0 { t.Fatalf("unsupported: %#v", result) } scope.Features.PathShow = true app = newConfigTestApp(t, Command(Suite[struct{}, struct{}]{Scopes: []Scope[struct{}, struct{}]{scope}})) result = app.Execute(context.Background(), []string{"config", "show", "--path=/x"}, commandkit.Streams{Out: io.Discard, Err: io.Discard}) if result.Kind != commandkit.OutcomeOperational || calls != 1 { t.Fatalf("missing facet: %#v", result) } } func TestSourcesFilterAndFailureEvidence(t *testing.T) { cause := errors.New("load failed") reader := &sourceInventory{values: []configkit.SourceInfo{{ID: "one", Label: "first"}, {ID: "two", Label: "second"}}} var returnedErr error var source SourceReader = reader scope := Scope[struct{}, struct{}]{Name: "app", Operations: []Operation{Sources}, Acquire: func(context.Context, Request, struct{}, struct{}) (commandkit.Acquired[View], error) { return commandkit.Acquired[View]{Value: View{Sources: source}}, returnedErr }} app := newConfigTestApp(t, Command(Suite[struct{}, struct{}]{Scopes: []Scope[struct{}, struct{}]{scope}})) run := func(args ...string) (commandkit.Outcome, string, string) { var out, diag bytes.Buffer result := app.Execute(context.Background(), append([]string{"config", "sources"}, args...), commandkit.Streams{Out: &out, Err: &diag}) return result, out.String(), diag.String() } result, out, _ := run("--source-id=two", "--format=json") if result.Kind != commandkit.OutcomeSuccess || !strings.Contains(out, `"id": "two"`) || strings.Contains(out, `"id": "one"`) { t.Fatalf("selected source: %#v %q", result, out) } result, _, _ = run("--source-id=missing") if result.Kind != commandkit.OutcomeOperational { t.Fatalf("unknown source: %#v", result) } returnedErr = cause result, out, _ = run("--source-id=one", "--format=json") if !errors.Is(result.Cause, cause) || !strings.Contains(out, `"id": "one"`) || strings.Contains(out, `"id": "two"`) { t.Fatalf("failed selection: %#v %q", result, out) } result, _, diag := run("--source-id=missing") if !errors.Is(result.Cause, cause) || !strings.Contains(diag, "not found") { t.Fatalf("failed missing source: %#v %q", result, diag) } source = &sourceInventory{} result, out, _ = run("--format=json") if !errors.Is(result.Cause, cause) || !strings.Contains(out, `"sources": []`) { t.Fatalf("empty evidence: %#v %q", result, out) } source = nil result, out, diag = run() if !errors.Is(result.Cause, cause) || out != "" || !strings.Contains(diag, "unavailable") { t.Fatalf("unavailable evidence: %#v %q %q", result, out, diag) } source = reader result = app.Execute(context.Background(), []string{"config", "sources"}, commandkit.Streams{Out: shortWriter{}, Err: io.Discard}) if !errors.Is(result.Cause, cause) || result.Presentation.Output.State != commandkit.DeliveryIncomplete { t.Fatalf("delivery failure: %#v", result) } }