Files
commandkit/integrations/ckconfig/focused_reports_test.go

127 lines
6.1 KiB
Go

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