Skip to content

Commit

Permalink
Tests for other bad inputs, add new translate impl
Browse files Browse the repository at this point in the history
  • Loading branch information
sam boyer committed Jul 21, 2023
1 parent 1ed2db3 commit eea4ec7
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 3 deletions.
58 changes: 56 additions & 2 deletions gomig_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package thema
import (
"testing"

"github.com/stretchr/testify/assert"

"cuelang.org/go/cue/cuecontext"
"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -141,7 +143,7 @@ schemas: [{
}]
`

lenses := []ImperativeLens{
correctLenses := []ImperativeLens{
{
To: SV(0, 0),
From: SV(0, 1),
Expand Down Expand Up @@ -313,8 +315,60 @@ schemas: [{
ctx := cuecontext.New()
rt := NewRuntime(ctx)
linval := rt.Context().CompileString(multivlin)
_, err := BindLineage(linval, rt, ImperativeLenses(lenses...))
_, err := BindLineage(linval, rt, ImperativeLenses(correctLenses...))
require.NoError(t, err)

_, err = BindLineage(linval, rt, ImperativeLenses(correctLenses[1:]...))
assert.Error(t, err, "expected error when missing a reverse Go migration")
_, err = BindLineage(linval, rt, ImperativeLenses(correctLenses[:1]...))
assert.Error(t, err, "expected error when missing a forward Go migration")

_, err = BindLineage(linval, rt, ImperativeLenses(append(correctLenses, ImperativeLens{
To: SV(2, 0),
From: SV(2, 1),
Mapper: func(inst *Instance, to Schema) (*Instance, error) { return nil, nil },
})...))
assert.Error(t, err, "expected error when adding Go migration pointing to nonexistent version")

_, err = BindLineage(linval, rt, ImperativeLenses(append(correctLenses, ImperativeLens{
To: SV(2, 1),
From: SV(2, 0),
Mapper: func(inst *Instance, to Schema) (*Instance, error) { return nil, nil },
})...))
assert.Error(t, err, "expected error when adding Go migration pointing to nonexistent version")

_, err = BindLineage(linval, rt, ImperativeLenses(append(correctLenses, ImperativeLens{
To: SV(2, 0),
From: SV(1, 1),
Mapper: func(inst *Instance, to Schema) (*Instance, error) { return nil, nil },
})...))
assert.Error(t, err, "expected error when adding duplicate Go migration")

_, err = BindLineage(linval, rt, ImperativeLenses(append(correctLenses, ImperativeLens{
Mapper: func(inst *Instance, to Schema) (*Instance, error) { return nil, nil },
})...))
assert.Error(t, err, "expected error when providing a Go migration with same to and from")

_, err = BindLineage(linval, rt, ImperativeLenses(append(correctLenses, ImperativeLens{
To: SV(2, 0),
From: SV(1, 0),
Mapper: func(inst *Instance, to Schema) (*Instance, error) { return nil, nil },
})...))
assert.Error(t, err, "expected error when providing Go migration with wrong successor")

_, err = BindLineage(linval, rt, ImperativeLenses(append(correctLenses, ImperativeLens{
To: SV(1, 0),
From: SV(2, 0),
Mapper: func(inst *Instance, to Schema) (*Instance, error) { return nil, nil },
})...))
assert.Error(t, err, "expected error when providing Go migration with wrong predecessor")

_, err = BindLineage(linval, rt, ImperativeLenses(append(correctLenses, ImperativeLens{
To: SV(1, 1),
From: SV(1, 0),
Mapper: func(inst *Instance, to Schema) (*Instance, error) { return nil, nil },
})...))
assert.Error(t, err, "expected error when providing Go migration for minor version upgrade")
}

func tomap(inst *Instance) map[string]any {
Expand Down
38 changes: 38 additions & 0 deletions instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,10 @@ func (inst *TypedInstance[T]) ValueP() T {
func (i *Instance) Translate(to SyntacticVersion) (*Instance, TranslationLacunas, error) {
i.check()

if len(i.Schema().Lineage().(*baseLineage).lensmap) > 0 {
return i.translateGo(to)
}

// TODO define this in terms of AsSuccessor and AsPredecessor, rather than those in terms of this.
newsch, err := i.Schema().Lineage().Schema(to)
if err != nil {
Expand Down Expand Up @@ -240,6 +244,40 @@ func (i *Instance) Translate(to SyntacticVersion) (*Instance, TranslationLacunas
return inst, lac, err
}

func (i *Instance) translateGo(to SyntacticVersion) (*Instance, TranslationLacunas, error) {
from := i.Schema().Version()
if to == from {
// TODO make sure this mirrors the pure CUE behavior
return i, nil, nil
}
lensmap := i.Schema().Lineage().(*baseLineage).lensmap

sch := i.Schema()
ti := new(Instance)
*ti = *i
for sch.Version() != to {
rti, err := lensmap[lid(sch.Version(), ti.Schema().Version())].Mapper(ti, sch)
if err != nil {
return nil, nil, err
}
// Ensure the returned instance exists and the caller returned an instance of the expected schema version
if rti == nil {
return nil, nil, fmt.Errorf("lens returned a nil instance")
}
if rti.Schema().Version() != sch.Version() {
return nil, nil, fmt.Errorf("lens returned an instance of the wrong schema version: expected %v, got %v", sch.Version(), ti.Schema().Version())
}
*ti = *rti
if to.Less(from) {
sch = sch.Predecessor()
} else {
sch = sch.Successor()
}
}

return ti, nil, nil
}

type multiTranslationLacunas []struct {
V SyntacticVersion `json:"v"`
Lac []Lacuna `json:"lacunas"`
Expand Down
3 changes: 2 additions & 1 deletion lineage.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ type baseLineage struct {
// all the schemas
allsch []*schemaDef

implens []ImperativeLens
lensmap map[lensID]ImperativeLens
}

// BindLineage takes a raw [cue.Value], checks that it correctly follows Thema's
Expand Down Expand Up @@ -143,6 +143,7 @@ func BindLineage(v cue.Value, rt *Runtime, opts ...BindOption) (Lineage, error)
uni: ml.uni,
allsch: ml.schlist,
allv: ml.allv,
lensmap: ml.lensmap,
}

for _, sch := range lin.allsch {
Expand Down

0 comments on commit eea4ec7

Please sign in to comment.