package gg import ( "bytes" "strconv" "testing" . "code.betamike.com/mediocregopher/ginger/gg/grammar" "code.betamike.com/mediocregopher/ginger/graph" "github.com/stretchr/testify/assert" ) func TestDecoder(t *testing.T) { type test struct { in string exp Located[Value] expErr string } runTests := func( t *testing.T, name string, sym Symbol[Located[Value]], tests []test, ) { t.Run(name, func(t *testing.T) { for i, test := range tests { t.Run(strconv.Itoa(i), func(t *testing.T) { r := NewReader(bytes.NewBufferString(test.in)) got, err := sym.Decode(r) if test.expErr != "" { assert.Error(t, err) assert.Equal(t, test.expErr, err.Error()) } else if assert.NoError(t, err) { assert.True(t, test.exp.Value.Equal(got.Value), "\nexp:%v\ngot:%v", test.exp, got, ) assert.Equal(t, test.exp.Location, got.Location) } }) } }) } expNum := func(row, col int, n int64) Located[Value] { return Located[Value]{Location{row, col}, Number(n)} } runTests(t, "number", number, []test{ {in: `0`, exp: expNum(1, 1, 0)}, {in: `100`, exp: expNum(1, 1, 100)}, {in: `-100`, exp: expNum(1, 1, -100)}, {in: `0foo`, exp: expNum(1, 1, 0)}, {in: `100foo`, exp: expNum(1, 1, 100)}, }) expName := func(row, col int, name string) Located[Value] { return Located[Value]{Location{row, col}, Name(name)} } expGraph := func(row, col int, g *Graph) Located[Value] { return Located[Value]{Location{row, col}, Value{Graph: g}} } runTests(t, "name", name, []test{ {in: `a`, exp: expName(1, 1, "a")}, {in: `ab`, exp: expName(1, 1, "ab")}, {in: `ab2c`, exp: expName(1, 1, "ab2c")}, {in: `ab2c,`, exp: expName(1, 1, "ab2c")}, }) runTests(t, "graph", graphSym, []test{ {in: `{}`, exp: expGraph(1, 1, new(Graph))}, {in: `{`, expErr: `1:2: expected '}' or name`}, {in: `{a}`, expErr: `1:3: expected '='`}, {in: `{a=}`, expErr: `1:4: expected name or number or graph or tuple`}, { in: `{foo=a}`, exp: expGraph( 1, 1, new(Graph). AddValueIn(Name("foo"), graph.ValueOut(None, Name("a"))), ), }, { in: `{ foo = a }`, exp: expGraph( 1, 1, new(Graph). AddValueIn(Name("foo"), graph.ValueOut(None, Name("a"))), ), }, {in: `{1=a}`, expErr: `1:2: expected '}' or name`}, {in: `{foo=a ,}`, expErr: `1:8: expected '}' or ';' or '<'`}, {in: `{foo=a`, expErr: `1:7: expected '}' or ';' or '<'`}, { in: `{foo=a