go-vise

Constrained Size Output Virtual Machine
Info | Log | Files | Refs | README | LICENSE

commit d183ec18242261f2307c8ae7b1e71f7be1e571f4
parent 7e01f2725d9c90b00f0bb5e624cb70d5e635e581
Author: lash <dev@holbrook.no>
Date:   Sun,  9 Apr 2023 09:44:32 +0100

Add render interface defs, rehabilitate vm

Diffstat:
Mgo/cache/cache.go | 8++------
Ago/cache/memory.go | 11+++++++++++
Mgo/render/menu.go | 5+++++
Mgo/render/page.go | 2+-
Ago/render/page_test.go | 114+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ago/render/render.go | 7+++++++
Mgo/state/state.go | 18+++---------------
Mgo/vm/runner.go | 147++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------
Mgo/vm/runner_test.go | 96++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------
9 files changed, 297 insertions(+), 111 deletions(-)

diff --git a/go/cache/cache.go b/go/cache/cache.go @@ -108,6 +108,8 @@ func(ca *Cache) Update(key string, value string) error { ca.CacheUseSize += l return fmt.Errorf("Cache capacity exceeded %v of %v", baseUseSize + sz, ca.CacheSize) } + ca.Cache[checkFrame][key] = value + ca.CacheUseSize += uint32(len(value)) return nil } @@ -162,12 +164,6 @@ func(ca *Cache) Check(key string) bool { return ca.frameOf(key) == -1 } -// flush relveant properties for level change -//func(ca *Cache) resetCurrent() { -// ca.sink = nil -// ca.CacheMap = make(map[string]string) -//} - // bytes that will be added to cache use size for string // returns 0 if capacity would be exceeded func(ca *Cache) checkCapacity(v string) uint32 { diff --git a/go/cache/memory.go b/go/cache/memory.go @@ -0,0 +1,11 @@ +package cache + +type Memory interface { + Add(key string, val string, sizeLimit uint16) error + Update(key string, val string) error + ReservedSize(key string) (uint16, error) + Get() (map[string]string, error) + Push() error + Pop() error + Reset() +} diff --git a/go/render/menu.go b/go/render/menu.go @@ -58,6 +58,11 @@ func(m *Menu) WithBrowseConfig(cfg BrowseConfig) *Menu { return m } +// GetBrowseConfig returns a copy of the current state of the browse configuration. +func(m *Menu) GetBrowseConfig() BrowseConfig { + return m.browse +} + // Put adds a menu option to the menu rendering. func(m *Menu) Put(selector string, title string) error { m.menu = append(m.menu, [2]string{selector, title}) diff --git a/go/render/page.go b/go/render/page.go @@ -80,7 +80,7 @@ func(pg *Page) Map(key string) error { return err } if l == 0 { - if pg.sink != nil { + if pg.sink != nil && *pg.sink != key { return fmt.Errorf("sink already set to symbol '%v'", *pg.sink) } pg.sink = &key diff --git a/go/render/page_test.go b/go/render/page_test.go @@ -0,0 +1,114 @@ +package render + +import ( + "testing" + + "git.defalsify.org/festive/cache" +) + + +func TestPageCurrentSize(t *testing.T) { + ca := cache.NewCache() + pg := NewPage(ca, nil) + err := ca.Push() + if err != nil { + t.Error(err) + } + err = ca.Add("foo", "inky", 0) + if err != nil { + t.Error(err) + } + err = ca.Push() + pg.Reset() + err = ca.Add("bar", "pinky", 10) + if err != nil { + t.Error(err) + } + err = ca.Add("baz", "tinkywinkydipsylalapoo", 51) + if err != nil { + t.Error(err) + } + err = pg.Map("foo") + if err != nil { + t.Error(err) + } + err = pg.Map("bar") + if err != nil { + t.Error(err) + } + err = pg.Map("baz") + if err != nil { + t.Error(err) + } + l, c, err := pg.Usage() + if err != nil { + t.Error(err) + } + if l != 27 { + t.Errorf("expected actual length 27, got %v", l) + } + if c != 34 { + t.Errorf("expected remaining length 34, got %v", c) + } + + mn := NewMenu().WithOutputSize(32) + pg = pg.WithMenu(mn) + l, c, err = pg.Usage() + if err != nil { + t.Error(err) + } + if l != 59 { + t.Errorf("expected actual length 59, got %v", l) + } + if c != 2 { + t.Errorf("expected remaining length 2, got %v", c) + } +} + +func TestStateMapSink(t *testing.T) { + ca := cache.NewCache() + pg := NewPage(ca, nil) + ca.Push() + err := ca.Add("foo", "bar", 0) + if err != nil { + t.Error(err) + } + ca.Push() + pg.Reset() + err = ca.Add("bar", "xyzzy", 6) + if err != nil { + t.Error(err) + } + err = ca.Add("baz", "bazbaz", 18) + if err != nil { + t.Error(err) + } + err = ca.Add("xyzzy", "plugh", 0) + if err != nil { + t.Error(err) + } + err = pg.Map("foo") + if err != nil { + t.Error(err) + } + err = pg.Map("xyzzy") + if err == nil { + t.Errorf("Expected fail on duplicate sink") + } + err = pg.Map("baz") + if err != nil { + t.Error(err) + } + ca.Push() + pg.Reset() + err = pg.Map("foo") + if err != nil { + t.Error(err) + } + ca.Pop() + pg.Reset() + err = pg.Map("foo") + if err != nil { + t.Error(err) + } +} diff --git a/go/render/render.go b/go/render/render.go @@ -0,0 +1,7 @@ +package render + +type Renderer interface { + Map(key string) error + Render(sym string, values map[string]string, idx uint16) (string, error) + Reset() +} diff --git a/go/state/state.go b/go/state/state.go @@ -275,21 +275,6 @@ func(st *State) Depth() uint8 { return uint8(len(st.execPath)-1) } -//func(st *State) SetMenuSize(size uint16) error { -// st.menuSize = size -// log.Printf("menu size changed to %v", st.menuSize) -// return nil -//} -// -//func(st *State) GetMenuSize() uint16 { -// return st.menuSize -//} -// -//func(st *State) GetOutputSize() uint32 { -// return st.outputSize -//} - - // Appendcode adds the given bytecode to the end of the existing code. func(st *State) AppendCode(b []byte) error { st.code = append(st.code, b...) @@ -328,3 +313,6 @@ func(st *State) SetInput(input []byte) error { return nil } +// Reset to initial state (start navigation over). +func(st *State) Reset() { +} diff --git a/go/vm/runner.go b/go/vm/runner.go @@ -5,10 +5,31 @@ import ( "fmt" "log" + "git.defalsify.org/festive/cache" + "git.defalsify.org/festive/render" "git.defalsify.org/festive/resource" "git.defalsify.org/festive/state" ) +type Vm struct { + st *state.State + rs resource.Resource + pg render.Renderer + ca cache.Memory + mn *render.Menu +} + + +func NewVm(st *state.State, rs resource.Resource, ca cache.Memory, mn *render.Menu, pg render.Renderer) *Vm { + return &Vm{ + st: st, + rs: rs, + pg: pg, + ca: ca, + mn: mn, + } +} + //type Runner func(instruction []byte, st state.State, rs resource.Resource, ctx context.Context) (state.State, []byte, error) // Run extracts individual op codes and arguments and executes them. @@ -16,7 +37,7 @@ import ( // Each step may update the state. // // On error, the remaining instructions will be returned. State will not be rolled back. -func Run(b []byte, st *state.State, rs resource.Resource, ctx context.Context) ([]byte, error) { +func(vm *Vm) Run(b []byte, ctx context.Context) ([]byte, error) { running := true for running { op, bb, err := opSplit(b) @@ -27,29 +48,29 @@ func Run(b []byte, st *state.State, rs resource.Resource, ctx context.Context) ( log.Printf("execute code %x (%s) %x", op, OpcodeString[op], b) switch op { case CATCH: - b, err = RunCatch(b, st, rs, ctx) + b, err = vm.RunCatch(b, ctx) case CROAK: - b, err = RunCroak(b, st, rs, ctx) + b, err = vm.RunCroak(b, ctx) case LOAD: - b, err = RunLoad(b, st, rs, ctx) + b, err = vm.RunLoad(b, ctx) case RELOAD: - b, err = RunReload(b, st, rs, ctx) + b, err = vm.RunReload(b, ctx) case MAP: - b, err = RunMap(b, st, rs, ctx) + b, err = vm.RunMap(b, ctx) case MOVE: - b, err = RunMove(b, st, rs, ctx) + b, err = vm.RunMove(b, ctx) case INCMP: - b, err = RunInCmp(b, st, rs, ctx) + b, err = vm.RunInCmp(b, ctx) case MSIZE: - b, err = RunMSize(b, st, rs, ctx) + b, err = vm.RunMSize(b, ctx) case MOUT: - b, err = RunMOut(b, st, rs, ctx) + b, err = vm.RunMOut(b, ctx) case MNEXT: - b, err = RunMNext(b, st, rs, ctx) + b, err = vm.RunMNext(b, ctx) case MPREV: - b, err = RunMPrev(b, st, rs, ctx) + b, err = vm.RunMPrev(b, ctx) case HALT: - b, err = RunHalt(b, st, rs, ctx) + b, err = vm.RunHalt(b, ctx) return b, err default: err = fmt.Errorf("Unhandled state: %v", op) @@ -58,7 +79,7 @@ func Run(b []byte, st *state.State, rs resource.Resource, ctx context.Context) ( return b, err } if len(b) == 0 { - b, err = RunDeadCheck(b, st, rs, ctx) + b, err = vm.RunDeadCheck(b, ctx) if err != nil { return b, err } @@ -77,19 +98,19 @@ func Run(b []byte, st *state.State, rs resource.Resource, ctx context.Context) ( // If input has not been matched, a default invalid input page should be generated aswell as a possiblity of return to last screen (or exit). // // If the termination flag has been set but not yet handled, execution is allowed to terminate. -func RunDeadCheck(b []byte, st *state.State, rs resource.Resource, ctx context.Context) ([]byte, error) { +func(vm *Vm) RunDeadCheck(b []byte, ctx context.Context) ([]byte, error) { if len(b) > 0 { return b, nil } log.Printf("no code remaining, let's check if we terminate") - r, err := st.MatchFlag(state.FLAG_TERMINATE, false) + r, err := vm.st.MatchFlag(state.FLAG_TERMINATE, false) if err != nil { panic(err) } if r { return b, nil } - location, _ := st.Where() + location, _ := vm.st.Where() if location == "" { return b, fmt.Errorf("dead runner with no current location") } @@ -99,92 +120,102 @@ func RunDeadCheck(b []byte, st *state.State, rs resource.Resource, ctx context.C } // RunMap executes the MAP opcode -func RunMap(b []byte, st *state.State, rs resource.Resource, ctx context.Context) ([]byte, error) { +func(vm *Vm) RunMap(b []byte, ctx context.Context) ([]byte, error) { sym, b, err := ParseMap(b) - err = st.Map(sym) + err = vm.pg.Map(sym) return b, err } // RunMap executes the CATCH opcode -func RunCatch(b []byte, st *state.State, rs resource.Resource, ctx context.Context) ([]byte, error) { +func(vm *Vm) RunCatch(b []byte, ctx context.Context) ([]byte, error) { log.Printf("zzz %x", b) sym, sig, mode, b, err := ParseCatch(b) if err != nil { return b, err } - r, err := st.MatchFlag(sig, mode) + r, err := vm.st.MatchFlag(sig, mode) if err != nil { return b, err } if r { log.Printf("catch at flag %v, moving to %v", sig, sym) //bitField, d) - st.Down(sym) + vm.st.Down(sym) b = []byte{} } return b, nil } // RunMap executes the CROAK opcode -func RunCroak(b []byte, st *state.State, rs resource.Resource, ctx context.Context) ([]byte, error) { +func(vm *Vm) RunCroak(b []byte, ctx context.Context) ([]byte, error) { sig, mode, b, err := ParseCroak(b) if err != nil { return b, err } - r, err := st.MatchFlag(sig, mode) + r, err := vm.st.MatchFlag(sig, mode) if err != nil { return b, err } if r { log.Printf("croak at flag %v, purging and moving to top", sig) - st.Reset() + vm.st.Reset() + vm.pg.Reset() + vm.ca.Reset() b = []byte{} } return []byte{}, nil } // RunLoad executes the LOAD opcode -func RunLoad(b []byte, st *state.State, rs resource.Resource, ctx context.Context) ([]byte, error) { +func(vm *Vm) RunLoad(b []byte, ctx context.Context) ([]byte, error) { sym, sz, b, err := ParseLoad(b) if err != nil { return b, err } - r, err := refresh(sym, rs, ctx) + r, err := refresh(sym, vm.rs, ctx) if err != nil { return b, err } - err = st.Add(sym, r, uint16(sz)) + err = vm.ca.Add(sym, r, uint16(sz)) return b, err } // RunLoad executes the RELOAD opcode -func RunReload(b []byte, st *state.State, rs resource.Resource, ctx context.Context) ([]byte, error) { +func(vm *Vm) RunReload(b []byte, ctx context.Context) ([]byte, error) { sym, b, err := ParseReload(b) if err != nil { return b, err } - r, err := refresh(sym, rs, ctx) + r, err := refresh(sym, vm.rs, ctx) if err != nil { return b, err } - st.Update(sym, r) + vm.ca.Update(sym, r) + if vm.pg != nil { + err := vm.pg.Map(sym) + if err != nil { + return b, err + } + } return b, nil } // RunLoad executes the MOVE opcode -func RunMove(b []byte, st *state.State, rs resource.Resource, ctx context.Context) ([]byte, error) { +func(vm *Vm) RunMove(b []byte, ctx context.Context) ([]byte, error) { sym, b, err := ParseMove(b) if err != nil { return b, err } if sym == "_" { - st.Up() - sym, _ = st.Where() + vm.st.Up() + vm.ca.Pop() + sym, _ = vm.st.Where() } else { - st.Down(sym) + vm.st.Down(sym) + vm.ca.Push() } - code, err := rs.GetCode(sym) + code, err := vm.rs.GetCode(sym) if err != nil { return b, err } @@ -194,19 +225,19 @@ func RunMove(b []byte, st *state.State, rs resource.Resource, ctx context.Contex } // RunIncmp executes the INCMP opcode -func RunInCmp(b []byte, st *state.State, rs resource.Resource, ctx context.Context) ([]byte, error) { +func(vm *Vm) RunInCmp(b []byte, ctx context.Context) ([]byte, error) { sym, target, b, err := ParseInCmp(b) if err != nil { return b, err } - v, err := st.GetFlag(state.FLAG_INMATCH) + v, err := vm.st.GetFlag(state.FLAG_INMATCH) if err != nil { return b, err } if v { return b, nil } - input, err := st.GetInput() + input, err := vm.st.GetInput() if err != nil { return b, err } @@ -215,11 +246,11 @@ func RunInCmp(b []byte, st *state.State, rs resource.Resource, ctx context.Conte } log.Printf("input match for '%s'", input) - _, err = st.SetFlag(state.FLAG_INMATCH) + _, err = vm.st.SetFlag(state.FLAG_INMATCH) - sym, _, err = applyTarget([]byte(target), st, ctx) + sym, _, err = applyTarget([]byte(target), vm.st, ctx) - code, err := rs.GetCode(target) + code, err := vm.rs.GetCode(target) if err != nil { return b, err } @@ -229,52 +260,60 @@ func RunInCmp(b []byte, st *state.State, rs resource.Resource, ctx context.Conte } // RunHalt executes the HALT opcode -func RunHalt(b []byte, st *state.State, rs resource.Resource, ctx context.Context) ([]byte, error) { +func(vm *Vm) RunHalt(b []byte, ctx context.Context) ([]byte, error) { var err error b, err = ParseHalt(b) if err != nil { return b, err } log.Printf("found HALT, stopping") - _, err = st.ResetFlag(state.FLAG_INMATCH) + _, err = vm.st.ResetFlag(state.FLAG_INMATCH) return b, err } -// RunMSize executes the HALT opcode -func RunMSize(b []byte, st *state.State, rs resource.Resource, ctx context.Context) ([]byte, error) { +// RunMSize executes the MSIZE opcode +func(vm *Vm) RunMSize(b []byte, ctx context.Context) ([]byte, error) { log.Printf("WARNING MSIZE not yet implemented") _, _, b, err := ParseMSize(b) return b, err } // RunMOut executes the MOUT opcode -func RunMOut(b []byte, st *state.State, rs resource.Resource, ctx context.Context) ([]byte, error) { +func(vm *Vm) RunMOut(b []byte, ctx context.Context) ([]byte, error) { choice, title, b, err := ParseMOut(b) if err != nil { return b, err } - err = rs.PutMenu(choice, title) + err = vm.mn.Put(choice, title) return b, err } // RunMNext executes the MNEXT opcode -func RunMNext(b []byte, st *state.State, rs resource.Resource, ctx context.Context) ([]byte, error) { +func(vm *Vm) RunMNext(b []byte, ctx context.Context) ([]byte, error) { selector, display, b, err := ParseMNext(b) if err != nil { return b, err } - err = rs.SetMenuBrowse(selector, display, false) - return b, err + cfg := vm.mn.GetBrowseConfig() + cfg.NextSelector = selector + cfg.NextTitle = display + cfg.NextAvailable = true + vm.mn = vm.mn.WithBrowseConfig(cfg) + return b, nil } // RunMPrev executes the MPREV opcode -func RunMPrev(b []byte, st *state.State, rs resource.Resource, ctx context.Context) ([]byte, error) { +func(vm *Vm) RunMPrev(b []byte, ctx context.Context) ([]byte, error) { selector, display, b, err := ParseMPrev(b) if err != nil { return b, err } - err = rs.SetMenuBrowse(selector, display, false) - return b, err + cfg := vm.mn.GetBrowseConfig() + cfg.PreviousSelector = selector + cfg.PreviousTitle = display + cfg.PreviousAvailable = true + vm.mn = vm.mn.WithBrowseConfig(cfg) + return b, nil } // retrieve data for key diff --git a/go/vm/runner_test.go b/go/vm/runner_test.go @@ -7,6 +7,8 @@ import ( "log" "testing" + "git.defalsify.org/festive/cache" + "git.defalsify.org/festive/render" "git.defalsify.org/festive/resource" "git.defalsify.org/festive/state" ) @@ -34,7 +36,7 @@ type TestStatefulResolver struct { state *state.State } -func (r *TestResource) GetTemplate(sym string, sizer *resource.Sizer) (string, error) { +func (r TestResource) GetTemplate(sym string) (string, error) { switch sym { case "foo": return "inky pinky blinky clyde", nil @@ -51,11 +53,7 @@ func (r *TestResource) GetTemplate(sym string, sizer *resource.Sizer) (string, e return "", fmt.Errorf("unknown symbol %s", sym) } -func (r *TestResource) RenderTemplate(sym string, values map[string]string, idx uint16, sizer *resource.Sizer) (string, error) { - return resource.DefaultRenderTemplate(r, sym, values, idx, sizer) -} - -func (r *TestResource) FuncFor(sym string) (resource.EntryFunc, error) { +func (r TestResource) FuncFor(sym string) (resource.EntryFunc, error) { switch sym { case "one": return getOne, nil @@ -69,12 +67,12 @@ func (r *TestResource) FuncFor(sym string) (resource.EntryFunc, error) { return nil, fmt.Errorf("invalid function: '%s'", sym) } -func(r *TestResource) getInput(ctx context.Context) (string, error) { +func(r TestResource) getInput(ctx context.Context) (string, error) { v, err := r.state.GetInput() return string(v), err } -func(r *TestResource) GetCode(sym string) ([]byte, error) { +func(r TestResource) GetCode(sym string) ([]byte, error) { var b []byte if sym == "_catch" { b = NewLine(b, MOUT, []string{"0", "repent"}, nil, nil) @@ -86,16 +84,18 @@ func(r *TestResource) GetCode(sym string) ([]byte, error) { func TestRun(t *testing.T) { st := state.NewState(5) rs := TestResource{} + ca := cache.NewCache() + vm := NewVm(&st, &rs, ca, nil, nil) b := NewLine(nil, MOVE, []string{"foo"}, nil, nil) b = NewLine(b, HALT, nil, nil, nil) - _, err := Run(b, &st, &rs, context.TODO()) + _, err := vm.Run(b, context.TODO()) if err != nil { t.Errorf("run error: %v", err) } b = []byte{0x01, 0x02} - _, err = Run(b, &st, &rs, context.TODO()) + _, err = vm.Run(b, context.TODO()) if err == nil { t.Errorf("no error on invalid opcode") } @@ -103,21 +103,25 @@ func TestRun(t *testing.T) { func TestRunLoadRender(t *testing.T) { st := state.NewState(5) - st.Down("barbarbar") rs := TestResource{} + ca := cache.NewCache() + pg := render.NewPage(ca, rs) + vm := NewVm(&st, &rs, ca, nil, pg) + + st.Down("barbarbar") var err error b := NewLine(nil, LOAD, []string{"one"}, []byte{0x0a}, nil) b = NewLine(b, HALT, nil, nil, nil) - b, err = Run(b, &st, &rs, context.TODO()) + b, err = vm.Run(b, context.TODO()) if err != nil { t.Error(err) } - m, err := st.Get() + m, err := ca.Get() if err != nil { t.Error(err) } - r, err := rs.RenderTemplate("foo", m, 0, nil) + r, err := pg.RenderTemplate("foo", m, 0) if err != nil { t.Error(err) } @@ -126,28 +130,28 @@ func TestRunLoadRender(t *testing.T) { t.Errorf("Expected %v, got %v", []byte(expect), []byte(r)) } - r, err = rs.RenderTemplate("bar", m, 0, nil) + r, err = pg.RenderTemplate("bar", m, 0) if err == nil { t.Errorf("expected error for render of bar: %v" ,err) } b = NewLine(nil, LOAD, []string{"two"}, []byte{0x0a}, nil) b = NewLine(b, HALT, nil, nil, nil) - b, err = Run(b, &st, &rs, context.TODO()) + b, err = vm.Run(b, context.TODO()) if err != nil { t.Error(err) } b = NewLine(nil, MAP, []string{"one"}, nil, nil) b = NewLine(b, HALT, nil, nil, nil) - _, err = Run(b, &st, &rs, context.TODO()) + _, err = vm.Run(b, context.TODO()) if err != nil { t.Error(err) } - m, err = st.Get() + m, err = ca.Get() if err != nil { t.Error(err) } - r, err = rs.RenderTemplate("bar", m, 0, nil) + r, err = pg.RenderTemplate("bar", m, 0) if err != nil { t.Error(err) } @@ -160,11 +164,14 @@ func TestRunLoadRender(t *testing.T) { func TestRunMultiple(t *testing.T) { st := state.NewState(5) rs := TestResource{} + ca := cache.NewCache() + vm := NewVm(&st, &rs, ca, nil, nil) + b := NewLine(nil, MOVE, []string{"test"}, nil, nil) b = NewLine(b, LOAD, []string{"one"}, []byte{0x00}, nil) b = NewLine(b, LOAD, []string{"two"}, []byte{42}, nil) b = NewLine(b, HALT, nil, nil, nil) - b, err := Run(b, &st, &rs, context.TODO()) + b, err := vm.Run(b, context.TODO()) if err != nil { t.Error(err) } @@ -176,15 +183,19 @@ func TestRunMultiple(t *testing.T) { func TestRunReload(t *testing.T) { st := state.NewState(5) rs := TestResource{} + ca := cache.NewCache() + pg := render.NewPage(ca, rs) + vm := NewVm(&st, &rs, ca, nil, pg) + b := NewLine(nil, MOVE, []string{"root"}, nil, nil) b = NewLine(b, LOAD, []string{"dyn"}, nil, []uint8{0}) b = NewLine(b, MAP, []string{"dyn"}, nil, nil) b = NewLine(b, HALT, nil, nil, nil) - _, err := Run(b, &st, &rs, context.TODO()) + _, err := vm.Run(b, context.TODO()) if err != nil { t.Fatal(err) } - r, err := st.Val("dyn") + r, err := pg.Val("dyn") if err != nil { t.Fatal(err) } @@ -194,11 +205,11 @@ func TestRunReload(t *testing.T) { dynVal = "baz" b = NewLine(nil, RELOAD, []string{"dyn"}, nil, nil) b = NewLine(b, HALT, nil, nil, nil) - _, err = Run(b, &st, &rs, context.TODO()) + _, err = vm.Run(b, context.TODO()) if err != nil { t.Fatal(err) } - r, err = st.Val("dyn") + r, err = pg.Val("dyn") if err != nil { t.Fatal(err) } @@ -206,18 +217,20 @@ func TestRunReload(t *testing.T) { if r != "baz" { t.Fatalf("expected result 'baz', got %v", r) } - } func TestHalt(t *testing.T) { st := state.NewState(5) rs := TestResource{} + ca := cache.NewCache() + vm := NewVm(&st, &rs, ca, nil, nil) + b := NewLine(nil, MOVE, []string{"root"}, nil, nil) b = NewLine(b, LOAD, []string{"one"}, nil, []uint8{0}) b = NewLine(b, HALT, nil, nil, nil) b = NewLine(b, MOVE, []string{"foo"}, nil, nil) var err error - b, err = Run(b, &st, &rs, context.TODO()) + b, err = vm.Run(b, context.TODO()) if err != nil { t.Error(err) } @@ -233,13 +246,15 @@ func TestHalt(t *testing.T) { func TestRunArg(t *testing.T) { st := state.NewState(5) rs := TestResource{} - + ca := cache.NewCache() + vm := NewVm(&st, &rs, ca, nil, nil) + input := []byte("bar") _ = st.SetInput(input) bi := NewLine(nil, INCMP, []string{"bar", "baz"}, nil, nil) bi = NewLine(bi, HALT, nil, nil, nil) - b, err := Run(bi, &st, &rs, context.TODO()) + b, err := vm.Run(bi, context.TODO()) if err != nil { t.Error(err) } @@ -256,6 +271,9 @@ func TestRunArg(t *testing.T) { func TestRunInputHandler(t *testing.T) { st := state.NewState(5) rs := TestResource{} + ca := cache.NewCache() + pg := render.NewPage(ca, rs) + vm := NewVm(&st, &rs, ca, nil, pg) _ = st.SetInput([]byte("baz")) @@ -268,7 +286,7 @@ func TestRunInputHandler(t *testing.T) { bi = NewLine(bi, HALT, nil, nil, nil) var err error - _, err = Run(bi, &st, &rs, context.TODO()) + _, err = vm.Run(bi, context.TODO()) if err != nil { t.Fatal(err) } @@ -281,6 +299,9 @@ func TestRunInputHandler(t *testing.T) { func TestRunArgInvalid(t *testing.T) { st := state.NewState(5) rs := TestResource{} + ca := cache.NewCache() + mn := render.NewMenu() + vm := NewVm(&st, &rs, ca, mn, nil) _ = st.SetInput([]byte("foo")) @@ -289,7 +310,7 @@ func TestRunArgInvalid(t *testing.T) { st.Down("root") b := NewLine(nil, INCMP, []string{"bar", "baz"}, nil, nil) - b, err = Run(b, &st, &rs, context.TODO()) + b, err = vm.Run(b, context.TODO()) if err != nil { t.Fatal(err) } @@ -302,6 +323,9 @@ func TestRunArgInvalid(t *testing.T) { func TestRunMenu(t *testing.T) { st := state.NewState(5) rs := TestResource{} + ca := cache.NewCache() + mn := render.NewMenu() + vm := NewVm(&st, &rs, ca, mn, nil) var err error @@ -310,7 +334,7 @@ func TestRunMenu(t *testing.T) { b = NewLine(b, MOUT, []string{"1", "two"}, nil, nil) b = NewLine(b, HALT, nil, nil, nil) - b, err = Run(b, &st, &rs, context.TODO()) + b, err = vm.Run(b, context.TODO()) if err != nil { t.Error(err) } @@ -319,7 +343,7 @@ func TestRunMenu(t *testing.T) { t.Errorf("expected empty remainder, got length %v: %v", l, b) } - r, err := rs.RenderMenu(0) + r, err := mn.Render(0) if err != nil { t.Fatal(err) } @@ -329,11 +353,13 @@ func TestRunMenu(t *testing.T) { } } - func TestRunMenuBrowse(t *testing.T) { log.Printf("This test is incomplete, it must check the output of a menu browser once one is implemented. For now it only checks whether it can execute the runner endpoints for the instrucitons.") st := state.NewState(5) rs := TestResource{} + ca := cache.NewCache() + mn := render.NewMenu() + vm := NewVm(&st, &rs, ca, mn, nil) var err error @@ -342,7 +368,7 @@ func TestRunMenuBrowse(t *testing.T) { b = NewLine(b, MOUT, []string{"1", "two"}, nil, nil) b = NewLine(b, HALT, nil, nil, nil) - b, err = Run(b, &st, &rs, context.TODO()) + b, err = vm.Run(b, context.TODO()) if err != nil { t.Error(err) } @@ -351,7 +377,7 @@ func TestRunMenuBrowse(t *testing.T) { t.Errorf("expected empty remainder, got length %v: %v", l, b) } - r, err := rs.RenderMenu(0) + r, err := mn.Render(0) if err != nil { t.Fatal(err) }