package engine import ( "reflect" "testing" ) type sliceViewConfig struct { Value []any `yaml:"value"` } func finiteSliceView() []any { shared := []any{"leaf", nil} shared[1] = shared[:1] return shared } func TestFiniteSliceViewsAreAcceptedAcrossValueBoundaries(t *testing.T) { want := []any{"leaf", []any{"leaf"}} mappingSource := Mapping("mapping.yml", map[string]any{"value": finiteSliceView()}) mapping, err := testLoad[sliceViewConfig](mappingSource) if err != nil || !reflect.DeepEqual(mapping.Config.Value, want) { t.Fatalf("mapping value = %#v, error = %v", mapping, err) } defaults, err := testLoad[sliceViewConfig](NoSource(), Options[sliceViewConfig]{Definition: Definition[sliceViewConfig]{ Defaults: func() sliceViewConfig { return sliceViewConfig{Value: finiteSliceView()} }, }}) if err != nil || !reflect.DeepEqual(defaults.Config.Value, want) { t.Fatalf("typed default value = %#v, error = %v", defaults, err) } override, err := testLoad[sliceViewConfig](NoSource(), Options[sliceViewConfig]{Overrides: []Override{{ Path: Keys("value"), Value: finiteSliceView(), Flag: "--value", }}}) if err != nil || !reflect.DeepEqual(override.Config.Value, want) { t.Fatalf("CLI override value = %#v, error = %v", override, err) } original := sliceViewConfig{Value: finiteSliceView()} schema := mustSchemaFor[sliceViewConfig](t) projected, issue := projectConfiguration(schema, reflect.ValueOf(original), defaultProjectionLimits()) if issue != nil { t.Fatalf("finite view projection issue = %#v", issue) } cloned, issue := cloneConfiguration(schema, reflect.ValueOf(original), defaultProjectionLimits()) if issue != nil { t.Fatalf("finite view clone issue = %#v", issue) } if !reflect.DeepEqual(cloned.Interface(), original) || !reflect.DeepEqual(projected, mappingSource.mapping) { t.Fatalf("equivalent finite values differ: clone=%#v projected=%#v mapping=%#v", cloned.Interface(), projected, mappingSource.mapping) } cloned.FieldByName("Value").Index(1).Interface().([]any)[0] = "changed" if original.Value[0] != "leaf" || original.Value[1].([]any)[0] != "leaf" { t.Fatal("mutating a cloned descendant changed the original value") } } func TestSliceCyclesRemainRejected(t *testing.T) { schema := mustSchemaFor[sliceViewConfig](t) self := make([]any, 1) self[0] = self first := make([]any, 1) second := make([]any, 1) first[0], second[0] = second, first for name, value := range map[string][]any{"self": self, "mutual": first} { t.Run(name, func(t *testing.T) { configuration := sliceViewConfig{Value: value} if _, issue := projectConfiguration(schema, reflect.ValueOf(configuration), defaultProjectionLimits()); issue == nil || issue.code != CodeSchemaCycle { t.Fatalf("projection cycle issue = %#v", issue) } if _, issue := cloneConfiguration(schema, reflect.ValueOf(configuration), defaultProjectionLimits()); issue == nil || issue.code != CodeSchemaCycle { t.Fatalf("clone cycle issue = %#v", issue) } }) } }