Remove disconnected facade clone scaffolding
This commit is contained in:
@@ -738,10 +738,10 @@ Type: test cleanup. Priority: low. Source: testing 6; related deadcode 3.
|
|||||||
compile-time interfaces, public construction, and distinct lifecycle checks.
|
compile-time interfaces, public construction, and distinct lifecycle checks.
|
||||||
A literal assignment equality assertion on a new `Result.Config` adds no
|
A literal assignment equality assertion on a new `Result.Config` adds no
|
||||||
protection beyond compilation and ordinary Go assignment.
|
protection beyond compilation and ordinary Go assignment.
|
||||||
- Replace `TestWrappedPathsRetainEngineSegmentIntent` in
|
- Replace the former `TestWrappedPathsRetainEngineSegmentIntent` internal
|
||||||
[facade_internal_test.go](../../facade_internal_test.go), which compares private
|
representation check with public contextual mapping/index behavior under F09.
|
||||||
representations, with public contextual mapping/index behavior under F09.
|
Keep engine segment-intent coverage; public source-form behavior is consolidated
|
||||||
Keep engine segment-intent coverage.
|
in [facade_equivalence_test.go](../../facade_equivalence_test.go).
|
||||||
- Move `TestWrappedSourcesPreserveEngineOwnership` from direct `engine.Load`
|
- Move `TestWrappedSourcesPreserveEngineOwnership` from direct `engine.Load`
|
||||||
through `source.toEngine()` to public `Load` and root error assertions.
|
through `source.toEngine()` to public `Load` and root error assertions.
|
||||||
Consolidate reader cases with [facade_equivalence_test.go](../../facade_equivalence_test.go)
|
Consolidate reader cases with [facade_equivalence_test.go](../../facade_equivalence_test.go)
|
||||||
|
|||||||
@@ -519,6 +519,13 @@ Findings: **F04**, remaining **F12**; requires Stage 15.
|
|||||||
Owners: root `records.go`, `records_test.go`, `facade_internal_test.go`,
|
Owners: root `records.go`, `records_test.go`, `facade_internal_test.go`,
|
||||||
`facade_compatibility_test.go`, `facade_candidate_test.go`, `facade_equivalence_test.go`.
|
`facade_compatibility_test.go`, `facade_candidate_test.go`, `facade_equivalence_test.go`.
|
||||||
|
|
||||||
|
Status: **complete** (F04; remaining F12). Prior completed commits: `2736ddf`,
|
||||||
|
`deb9aa5`, `ae3408a`, `ea27f17`, `08a8c25`, `877c497`, `8aba43d`, `7bf2f0c`,
|
||||||
|
`0f9ecf1`, `119b42c`, `247a12b`, `4fcff5f`, `12d350a`, `08f2a8f`, `826062a`.
|
||||||
|
Validation passed: `env GOTOOLCHAIN=local GOPROXY=off GOTELEMETRY=off go test .`,
|
||||||
|
`env GOTOOLCHAIN=local GOPROXY=off GOTELEMETRY=off go test ./examples/consumers`,
|
||||||
|
and `git diff --check`.
|
||||||
|
|
||||||
Remove the complete private clone family named in audit F04 after reconfirming
|
Remove the complete private clone family named in audit F04 after reconfirming
|
||||||
that only the tests enter it. Preserve engine clones, active `Path.clone`, explicit
|
that only the tests enter it. Preserve engine clones, active `Path.clone`, explicit
|
||||||
root conversions, and nil/empty conversion checks. Remove the ineffective
|
root conversions, and nil/empty conversion checks. Remove the ineffective
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"reflect"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
configkit "gitea.maximumdirect.net/eric/ConfigKit"
|
configkit "gitea.maximumdirect.net/eric/ConfigKit"
|
||||||
@@ -27,23 +26,6 @@ type facadeCompatibilityConfig struct {
|
|||||||
func TestFacadeCompatibility(t *testing.T) {
|
func TestFacadeCompatibility(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
const packagePath = "gitea.maximumdirect.net/eric/ConfigKit"
|
|
||||||
for _, candidate := range []struct {
|
|
||||||
name string
|
|
||||||
type_ reflect.Type
|
|
||||||
}{
|
|
||||||
{"Path", reflect.TypeFor[configkit.Path]()},
|
|
||||||
{"Source", reflect.TypeFor[configkit.Source]()},
|
|
||||||
{"Secret", reflect.TypeFor[configkit.Secret]()},
|
|
||||||
{"Definition", reflect.TypeFor[configkit.Definition[facadeCompatibilityConfig]]()},
|
|
||||||
{"Options", reflect.TypeFor[configkit.Options[facadeCompatibilityConfig]]()},
|
|
||||||
{"Result", reflect.TypeFor[configkit.Result[facadeCompatibilityConfig]]()},
|
|
||||||
} {
|
|
||||||
if candidate.type_.PkgPath() != packagePath {
|
|
||||||
t.Errorf("%s belongs to %q, want %q", candidate.name, candidate.type_.PkgPath(), packagePath)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
constructed := configkit.Options[facadeCompatibilityConfig]{
|
constructed := configkit.Options[facadeCompatibilityConfig]{
|
||||||
Definition: configkit.Definition[facadeCompatibilityConfig]{},
|
Definition: configkit.Definition[facadeCompatibilityConfig]{},
|
||||||
Filesystem: &configkit.FilesystemContext{BaseDir: "configs", Root: "configs"},
|
Filesystem: &configkit.FilesystemContext{BaseDir: "configs", Root: "configs"},
|
||||||
@@ -56,11 +38,6 @@ func TestFacadeCompatibility(t *testing.T) {
|
|||||||
if got := constructed.Overrides[0].Path.String(); got != "/value" {
|
if got := constructed.Overrides[0].Path.String(); got != "/value" {
|
||||||
t.Fatalf("constructed override path = %q, want /value", got)
|
t.Fatalf("constructed override path = %q, want /value", got)
|
||||||
}
|
}
|
||||||
publicResult := configkit.Result[facadeCompatibilityConfig]{Config: facadeCompatibilityConfig{Value: "constructed"}}
|
|
||||||
if publicResult.Config.Value != "constructed" {
|
|
||||||
t.Fatal("constructed result lost its public configuration")
|
|
||||||
}
|
|
||||||
|
|
||||||
result, err := configkit.Load(configkit.Bytes("facade.yml", []byte("value: input\n")), configkit.Options[facadeCompatibilityConfig]{
|
result, err := configkit.Load(configkit.Bytes("facade.yml", []byte("value: input\n")), configkit.Options[facadeCompatibilityConfig]{
|
||||||
Definition: configkit.Definition[facadeCompatibilityConfig]{
|
Definition: configkit.Definition[facadeCompatibilityConfig]{
|
||||||
Resolve: func(configuration *facadeCompatibilityConfig, resolution *configkit.Resolution) error {
|
Resolve: func(configuration *facadeCompatibilityConfig, resolution *configkit.Resolution) error {
|
||||||
|
|||||||
@@ -23,6 +23,9 @@ type equivalentConfig struct {
|
|||||||
|
|
||||||
func TestEquivalentSourceFormsPreserveInputSemantics(t *testing.T) {
|
func TestEquivalentSourceFormsPreserveInputSemantics(t *testing.T) {
|
||||||
const yaml = "version: 1\nname: retained\nenabled: false\ncount: 0\nitems: []\noptional: null\n"
|
const yaml = "version: 1\nname: retained\nenabled: false\ncount: 0\nitems: []\noptional: null\n"
|
||||||
|
bytesData := []byte(yaml)
|
||||||
|
bytesSource := configkit.Bytes("memory", bytesData)
|
||||||
|
bytesData[0] = 'X'
|
||||||
hostPath := filepath.Join(t.TempDir(), "main.yml")
|
hostPath := filepath.Join(t.TempDir(), "main.yml")
|
||||||
if err := os.WriteFile(hostPath, []byte(yaml), 0o600); err != nil {
|
if err := os.WriteFile(hostPath, []byte(yaml), 0o600); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -37,7 +40,7 @@ func TestEquivalentSourceFormsPreserveInputSemantics(t *testing.T) {
|
|||||||
}{
|
}{
|
||||||
{"host", configkit.File(hostPath), nil, configkit.SourceKindFile},
|
{"host", configkit.File(hostPath), nil, configkit.SourceKindFile},
|
||||||
{"native", namespace.File("main.yml"), nil, configkit.SourceKindFilesystem},
|
{"native", namespace.File("main.yml"), nil, configkit.SourceKindFilesystem},
|
||||||
{"bytes", configkit.Bytes("memory", []byte(yaml)), context, configkit.SourceKindBytes},
|
{"bytes", bytesSource, context, configkit.SourceKindBytes},
|
||||||
{"reader", configkit.Reader("stream", strings.NewReader(yaml)), context, configkit.SourceKindReader},
|
{"reader", configkit.Reader("stream", strings.NewReader(yaml)), context, configkit.SourceKindReader},
|
||||||
{"mapping", configkit.Mapping("programmatic", map[string]any{
|
{"mapping", configkit.Mapping("programmatic", map[string]any{
|
||||||
"version": uint64(1), "name": "retained", "enabled": false, "count": 0,
|
"version": uint64(1), "name": "retained", "enabled": false, "count": 0,
|
||||||
@@ -112,6 +115,15 @@ func TestRepeatedImportsAcrossTiersAndReaderConsumption(t *testing.T) {
|
|||||||
if got := layeredErrorCode(t, err); got != configkit.CodeSourceReaderUsed {
|
if got := layeredErrorCode(t, err); got != configkit.CodeSourceReaderUsed {
|
||||||
t.Fatalf("reader re-consumption = %s", got)
|
t.Fatalf("reader re-consumption = %s", got)
|
||||||
}
|
}
|
||||||
|
copiedReader := configkit.Reader("copied-single-use", strings.NewReader("name: retained\n"))
|
||||||
|
readerCopy := copiedReader
|
||||||
|
if _, err := configkit.Load[config](readerCopy, configkit.Options[config]{}); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
_, err = configkit.Load[config](copiedReader, configkit.Options[config]{})
|
||||||
|
if got := layeredErrorCode(t, err); got != configkit.CodeSourceReaderUsed {
|
||||||
|
t.Fatalf("copied reader re-consumption = %s", got)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReplacedSecretRemainsAbsentFromSafeOutput(t *testing.T) {
|
func TestReplacedSecretRemainsAbsentFromSafeOutput(t *testing.T) {
|
||||||
|
|||||||
@@ -1,35 +0,0 @@
|
|||||||
package configkit
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"gitea.maximumdirect.net/eric/ConfigKit/internal/engine"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestWrappedSourcesPreserveEngineOwnership(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
type config struct {
|
|
||||||
Value string `yaml:"value"`
|
|
||||||
}
|
|
||||||
data := []byte("value: retained\n")
|
|
||||||
source := Bytes("snapshot.yml", data)
|
|
||||||
data[7] = 'X'
|
|
||||||
result, err := engine.Load[config](source.toEngine(), engine.SecretBinding{})
|
|
||||||
if err != nil || result.Config.Value != "retained" {
|
|
||||||
t.Fatalf("snapshotted source = %#v, %v", result, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
readerSource := Reader("reader.yml", strings.NewReader("value: once\n"))
|
|
||||||
first := readerSource
|
|
||||||
if _, err := engine.Load[config](first.toEngine(), engine.SecretBinding{}); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
_, err = engine.Load[config](readerSource.toEngine(), engine.SecretBinding{})
|
|
||||||
var loadError *engine.LoadError
|
|
||||||
if !errors.As(err, &loadError) || len(loadError.Diagnostics()) != 1 || loadError.Diagnostics()[0].Code != engine.CodeSourceReaderUsed {
|
|
||||||
t.Fatalf("copied reader source error = %#v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
115
records.go
115
records.go
@@ -313,118 +313,3 @@ type Change struct {
|
|||||||
Reasons []string
|
Reasons []string
|
||||||
Dependencies []Path
|
Dependencies []Path
|
||||||
}
|
}
|
||||||
|
|
||||||
func cloneLocation(location *Location) *Location {
|
|
||||||
if location == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
cloned := *location
|
|
||||||
return &cloned
|
|
||||||
}
|
|
||||||
|
|
||||||
func cloneLocations(locations []Location) []Location {
|
|
||||||
if locations == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return append([]Location(nil), locations...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func cloneSourceInfo(source SourceInfo) SourceInfo {
|
|
||||||
source.Destination = source.Destination.clone()
|
|
||||||
source.ImportedFrom = cloneLocation(source.ImportedFrom)
|
|
||||||
source.VersionCheck = cloneSourceVersionCheck(source.VersionCheck)
|
|
||||||
source.ImportSelections = cloneImportSelections(source.ImportSelections)
|
|
||||||
return source
|
|
||||||
}
|
|
||||||
|
|
||||||
func cloneImportSelections(selections []ImportSelection) []ImportSelection {
|
|
||||||
if selections == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
cloned := make([]ImportSelection, len(selections))
|
|
||||||
for index, selection := range selections {
|
|
||||||
selection.Path = selection.Path.clone()
|
|
||||||
cloned[index] = selection
|
|
||||||
}
|
|
||||||
return cloned
|
|
||||||
}
|
|
||||||
|
|
||||||
func cloneSourceVersionCheck(value *SourceVersionCheck) *SourceVersionCheck {
|
|
||||||
if value == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
cloned := *value
|
|
||||||
cloned.Path = value.Path.clone()
|
|
||||||
cloned.Location = cloneLocation(value.Location)
|
|
||||||
return &cloned
|
|
||||||
}
|
|
||||||
|
|
||||||
func cloneSourceInfos(sources []SourceInfo) []SourceInfo {
|
|
||||||
if sources == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
cloned := make([]SourceInfo, len(sources))
|
|
||||||
for i, source := range sources {
|
|
||||||
cloned[i] = cloneSourceInfo(source)
|
|
||||||
}
|
|
||||||
return cloned
|
|
||||||
}
|
|
||||||
|
|
||||||
func cloneOrigin(origin Origin) Origin {
|
|
||||||
origin.Locations = cloneLocations(origin.Locations)
|
|
||||||
if origin.Inheritance != nil {
|
|
||||||
steps := make([]InheritanceStep, len(origin.Inheritance))
|
|
||||||
for index, step := range origin.Inheritance {
|
|
||||||
steps[index] = InheritanceStep{
|
|
||||||
From: step.From.clone(), To: step.To.clone(), Reference: step.Reference.clone(),
|
|
||||||
Locations: cloneLocations(step.Locations),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
origin.Inheritance = steps
|
|
||||||
}
|
|
||||||
return origin
|
|
||||||
}
|
|
||||||
|
|
||||||
func cloneFieldInfo(info FieldInfo) FieldInfo {
|
|
||||||
info.Origin = cloneOrigin(info.Origin)
|
|
||||||
return info
|
|
||||||
}
|
|
||||||
|
|
||||||
func cloneChange(change Change) Change {
|
|
||||||
change.Path = change.Path.clone()
|
|
||||||
change.Origin = cloneOrigin(change.Origin)
|
|
||||||
if change.Previous != nil {
|
|
||||||
previous := make([]Origin, len(change.Previous))
|
|
||||||
for i, origin := range change.Previous {
|
|
||||||
previous[i] = cloneOrigin(origin)
|
|
||||||
}
|
|
||||||
change.Previous = previous
|
|
||||||
}
|
|
||||||
change.Reasons = append([]string(nil), change.Reasons...)
|
|
||||||
if change.Dependencies != nil {
|
|
||||||
dependencies := make([]Path, len(change.Dependencies))
|
|
||||||
for i, path := range change.Dependencies {
|
|
||||||
dependencies[i] = path.clone()
|
|
||||||
}
|
|
||||||
change.Dependencies = dependencies
|
|
||||||
}
|
|
||||||
return change
|
|
||||||
}
|
|
||||||
|
|
||||||
func cloneDiagnostic(diagnostic Diagnostic) Diagnostic {
|
|
||||||
diagnostic.Path = diagnostic.Path.clone()
|
|
||||||
diagnostic.Primary = cloneLocation(diagnostic.Primary)
|
|
||||||
diagnostic.Related = cloneLocations(diagnostic.Related)
|
|
||||||
return diagnostic
|
|
||||||
}
|
|
||||||
|
|
||||||
func cloneDiagnostics(diagnostics []Diagnostic) []Diagnostic {
|
|
||||||
if diagnostics == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
cloned := make([]Diagnostic, len(diagnostics))
|
|
||||||
for i, diagnostic := range diagnostics {
|
|
||||||
cloned[i] = cloneDiagnostic(diagnostic)
|
|
||||||
}
|
|
||||||
return cloned
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ func TestOverlayPublicValues(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSourceInfoDestinationConversionsAndCopies(t *testing.T) {
|
func TestSourceInfoDestinationConversion(t *testing.T) {
|
||||||
destination := Keys("collections", "a/b", "0")
|
destination := Keys("collections", "a/b", "0")
|
||||||
path := writeRecordConfig(t, "value: main\n")
|
path := writeRecordConfig(t, "value: main\n")
|
||||||
options := engine.OptionsWithPlacement(engine.Options[map[string]any]{}, engine.Keys("collections", "a/b", "0"), uint8(PlacementModeSequenceItem))
|
options := engine.OptionsWithPlacement(engine.Options[map[string]any]{}, engine.Keys("collections", "a/b", "0"), uint8(PlacementModeSequenceItem))
|
||||||
@@ -36,14 +36,9 @@ func TestSourceInfoDestinationConversionsAndCopies(t *testing.T) {
|
|||||||
if converted.Destination.String() != destination.String() || converted.PlacementMode != PlacementModeSequenceItem || converted.DestinationUnresolved {
|
if converted.Destination.String() != destination.String() || converted.PlacementMode != PlacementModeSequenceItem || converted.DestinationUnresolved {
|
||||||
t.Fatalf("public source evidence = %#v", converted)
|
t.Fatalf("public source evidence = %#v", converted)
|
||||||
}
|
}
|
||||||
copy := cloneSourceInfo(converted)
|
|
||||||
copy.Destination = Path{}
|
|
||||||
if converted.Destination.String() != destination.String() {
|
|
||||||
t.Fatalf("source record destination changed through clone: %q", converted.Destination.String())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSourceVersionCheckConversionsAndCopies(t *testing.T) {
|
func TestSourceVersionCheckConversion(t *testing.T) {
|
||||||
path := Keys("version")
|
path := Keys("version")
|
||||||
file := writeRecordConfig(t, "version: '123'\nvalue: main\n")
|
file := writeRecordConfig(t, "version: '123'\nvalue: main\n")
|
||||||
options := engine.Options[recordConfig]{
|
options := engine.Options[recordConfig]{
|
||||||
@@ -67,18 +62,9 @@ func TestSourceVersionCheckConversionsAndCopies(t *testing.T) {
|
|||||||
converted.VersionCheck.Location == nil || converted.VersionCheck.Location.SourceID != internal.ID || converted.VersionCheck.Location.Line != 1 {
|
converted.VersionCheck.Location == nil || converted.VersionCheck.Location.SourceID != internal.ID || converted.VersionCheck.Location.Line != 1 {
|
||||||
t.Fatalf("public source version check = %#v", converted.VersionCheck)
|
t.Fatalf("public source version check = %#v", converted.VersionCheck)
|
||||||
}
|
}
|
||||||
copy := cloneSourceInfo(converted)
|
|
||||||
copy.VersionCheck.Path = Keys("changed")
|
|
||||||
copy.VersionCheck.Version.Text = "changed"
|
|
||||||
copy.VersionCheck.Location.Line = 99
|
|
||||||
copy.VersionCheck.Redacted = true
|
|
||||||
if converted.VersionCheck.Path.String() != path.String() || converted.VersionCheck.Version.Text != "123" ||
|
|
||||||
converted.VersionCheck.Location.Line != 1 || converted.VersionCheck.Redacted {
|
|
||||||
t.Fatalf("source version check changed through a detached copy: %#v", converted.VersionCheck)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestImportSelectionConversionsAndCopies(t *testing.T) {
|
func TestImportSelectionConversion(t *testing.T) {
|
||||||
file := writeRecordConfig(t, "configkit:\n imports:\n - glob: absent/*.yml\nvalue: main\n")
|
file := writeRecordConfig(t, "configkit:\n imports:\n - glob: absent/*.yml\nvalue: main\n")
|
||||||
internal := engineSourceInfoFromLoad(t, file, "source-1", engine.Options[recordConfig]{Imports: true})
|
internal := engineSourceInfoFromLoad(t, file, "source-1", engine.Options[recordConfig]{Imports: true})
|
||||||
converted := fromEngineSourceInfo(internal)
|
converted := fromEngineSourceInfo(internal)
|
||||||
@@ -87,12 +73,6 @@ func TestImportSelectionConversionsAndCopies(t *testing.T) {
|
|||||||
converted.ImportSelections[0].Selector != ImportSelectorGlob || converted.ImportSelections[0].Outcome != ImportSelectionNone {
|
converted.ImportSelections[0].Selector != ImportSelectorGlob || converted.ImportSelections[0].Outcome != ImportSelectionNone {
|
||||||
t.Fatalf("converted selection evidence = %#v", converted.ImportSelections)
|
t.Fatalf("converted selection evidence = %#v", converted.ImportSelections)
|
||||||
}
|
}
|
||||||
copy := cloneSourceInfo(converted)
|
|
||||||
copy.ImportSelections[0].Path = Keys("copy")
|
|
||||||
copy.ImportSelections[0].Selector = ImportSelectorPath
|
|
||||||
if converted.ImportSelections[0].Path.String() != "/configkit/imports/0" || converted.ImportSelections[0].Selector != ImportSelectorGlob {
|
|
||||||
t.Fatalf("source selection evidence changed through copy: %#v", converted.ImportSelections)
|
|
||||||
}
|
|
||||||
if converted.ImportSelections[0].Outcome != ImportSelectionNone {
|
if converted.ImportSelections[0].Outcome != ImportSelectionNone {
|
||||||
t.Fatalf("source selection outcome = %q", converted.ImportSelections[0].Outcome)
|
t.Fatalf("source selection outcome = %q", converted.ImportSelections[0].Outcome)
|
||||||
}
|
}
|
||||||
@@ -102,10 +82,6 @@ func TestImportSelectionConversionsAndCopies(t *testing.T) {
|
|||||||
if fromEngineImportSelections([]engine.ImportSelectionForFacade{}) == nil {
|
if fromEngineImportSelections([]engine.ImportSelectionForFacade{}) == nil {
|
||||||
t.Fatal("converting an empty engine selection slice returned nil")
|
t.Fatal("converting an empty engine selection slice returned nil")
|
||||||
}
|
}
|
||||||
empty := cloneSourceInfo(SourceInfo{ImportSelections: make([]ImportSelection, 0)})
|
|
||||||
if empty.ImportSelections == nil {
|
|
||||||
t.Fatal("cloning collapsed a non-nil empty selection slice")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestOverrideConversionsPreserveSliceShapeAndCopyRecords(t *testing.T) {
|
func TestOverrideConversionsPreserveSliceShapeAndCopyRecords(t *testing.T) {
|
||||||
|
|||||||
Reference in New Issue
Block a user