package pointer import ( "os" "testing" "git.adyxax.org/adyxax/gofunge98/pkg/field" "git.adyxax.org/adyxax/gofunge98/pkg/stack" "github.com/stretchr/testify/require" ) func TestBegin(t *testing.T) { t.Run("empty", func(t *testing.T) { expected := NewStackStack() expected.head = stack.NewStack(0, expected.head) expected.head.Next().Push(0) expected.head.Next().Push(0) expected.height++ p := NewPointer() ss := p.ss ss.Begin(p) require.Equal(t, expected, ss) x, y := p.GetStorageOffset() require.Equal(t, 1, x) require.Equal(t, 0, y) // Let's push another one expected.head = stack.NewStack(0, expected.head) expected.head.Next().Push(1) expected.head.Next().Push(0) expected.height++ ss.Begin(p) require.Equal(t, expected, ss) x, y = p.GetStorageOffset() require.Equal(t, 1, x) require.Equal(t, 0, y) }) t.Run("negative", func(t *testing.T) { expected := NewStackStack() expected.head = stack.NewStack(5, expected.head) expected.head.Next().Push(0) expected.head.Next().Push(0) expected.head.Next().Push(0) expected.head.Next().Push(0) expected.head.Next().Push(0) expected.head.Next().Push(0) expected.head.Next().Push(0) expected.height++ p := NewPointer() file, err := os.Open("../field/test_data/hello.b98") require.NoError(t, err, "Failed to open file") f, err := field.Load(file) p.Step(*f) ss := p.ss ss.head.Push(-5) ss.Begin(p) require.Equal(t, expected, ss) x, y := p.GetStorageOffset() require.Equal(t, 2, x) require.Equal(t, 0, y) }) t.Run("ask to copy more than we have", func(t *testing.T) { expected := NewStackStack() expected.head = stack.NewStack(34, expected.head) for i := 0; i < 33; i++ { expected.head.Push(0) } expected.head.Push(18) expected.head.Next().Push(2) expected.head.Next().Push(3) expected.height++ p := NewPointer() p.SetStorageOffset(2, 3) file, err := os.Open("../field/test_data/hello.b98") require.NoError(t, err, "Failed to open file") f, err := field.Load(file) p.Step(*f) ss := p.ss ss.head.Push(18) ss.head.Push(34) ss.Begin(p) require.Equal(t, expected, ss) x, y := p.GetStorageOffset() require.Equal(t, 2, x) require.Equal(t, 0, y) }) t.Run("normal", func(t *testing.T) { expected := NewStackStack() expected.head = stack.NewStack(4, expected.head) expected.head.Push(12) expected.head.Push(14) expected.head.Push(-2) expected.head.Push(5) expected.head.Next().Push(7) expected.head.Next().Push(36) expected.head.Next().Push(42) expected.head.Next().Push(-2) expected.head.Next().Push(5) expected.head.Next().Push(4) expected.head.Next().Pop() expected.head.Next().Pop() expected.head.Next().Pop() expected.height++ p := NewPointer() p.SetStorageOffset(36, 42) ss := p.ss ss.head.Push(7) ss.head.Push(12) ss.head.Push(14) ss.head.Push(-2) ss.head.Push(5) ss.head.Push(4) ss.Begin(p) require.Equal(t, expected, ss) }) } func TestEnd(t *testing.T) { t.Run("empty", func(t *testing.T) { expected := NewStackStack() p := NewPointer() ss := p.ss ss.Begin(p) reflect := ss.End(p) require.Equal(t, false, reflect) require.Equal(t, expected, ss) }) t.Run("drop", func(t *testing.T) { expected := NewStackStack() expected.head.Push(7) expected.head.Push(12) expected.head.Push(14) expected.head.Push(-2) expected.head.Push(5) expected.head.Pop() expected.head.Pop() expected.head.Pop() p := NewPointer() ss := p.ss ss.head.Push(7) ss.head.Push(12) ss.head.Push(14) ss.head.Push(-2) ss.head.Push(5) ss.head.Push(0) ss.Begin(p) ss.head.Push(18) ss.head.Push(42) ss.head.Push(-3) reflect := ss.End(p) require.Equal(t, false, reflect) require.Equal(t, expected, ss) }) t.Run("drop too much", func(t *testing.T) { expected := NewStackStack() p := NewPointer() ss := p.ss ss.Begin(p) ss.head.Push(-3) reflect := ss.End(p) require.Equal(t, false, reflect) require.Equal(t, expected, ss) }) t.Run("reflect", func(t *testing.T) { expected := NewStackStack() p := NewPointer() ss := p.ss reflect := ss.End(p) require.Equal(t, true, reflect) require.Equal(t, expected, ss) }) t.Run("transfert", func(t *testing.T) { expected := NewStackStack() expected.head.Push(7) expected.head.Push(12) expected.head.Push(14) expected.head.Push(-2) expected.head.Push(5) p := NewPointer() ss := p.ss ss.head.Push(7) ss.head.Push(0) ss.Begin(p) ss.head.Push(0) ss.head.Push(18) ss.head.Push(42) ss.head.Push(7) ss.head.Push(12) ss.head.Push(14) ss.head.Push(-2) ss.head.Push(5) ss.head.Push(4) reflect := ss.End(p) require.Equal(t, false, reflect) require.Equal(t, expected, ss) }) } func TestUnder(t *testing.T) { t.Run("empty", func(t *testing.T) { expected := NewStackStack() p := NewPointer() reflect := p.ss.Under() require.Equal(t, true, reflect) require.Equal(t, expected, p.ss) }) t.Run("positive", func(t *testing.T) { pe := NewPointer() expected := NewStackStack() expected.head.Push(1) expected.head.Push(2) expected.head.Push(3) expected.head.Push(6) expected.head.Push(0) expected.Begin(pe) expected.head.Push(0) expected.head.Push(0) expected.head.Push(6) expected.head.Next().Pop() expected.head.Next().Pop() expected.head.Next().Pop() p := NewPointer() ss := p.ss ss.head.Push(1) ss.head.Push(2) ss.head.Push(3) ss.head.Push(6) ss.head.Push(0) ss.Begin(p) ss.head.Push(3) reflect := ss.Under() require.Equal(t, false, reflect) require.Equal(t, expected, ss) }) t.Run("negative", func(t *testing.T) { pe := NewPointer() expected := NewStackStack() expected.Begin(pe) expected.head.Next().Push(12) expected.head.Next().Push(5) expected.head.Next().Push(8) expected.head.Push(8) expected.head.Push(5) expected.head.Push(12) expected.head.Push(-3) expected.head.Pop() expected.head.Pop() expected.head.Pop() expected.head.Pop() p := NewPointer() ss := p.ss ss.Begin(p) ss.head.Push(8) ss.head.Push(5) ss.head.Push(12) ss.head.Push(-3) reflect := ss.Under() require.Equal(t, false, reflect) require.Equal(t, expected, ss) }) }