runner_test.go (18929B)
1 package vm 2 3 import ( 4 "bytes" 5 "context" 6 "fmt" 7 "log" 8 "testing" 9 10 "git.defalsify.org/vise.git/cache" 11 "git.defalsify.org/vise.git/render" 12 "git.defalsify.org/vise.git/resource" 13 "git.defalsify.org/vise.git/internal/resourcetest" 14 "git.defalsify.org/vise.git/state" 15 ) 16 17 var ( 18 ctx = context.Background() 19 dynVal = "three" 20 ) 21 22 type testResource struct { 23 *resourcetest.TestResource 24 state *state.State 25 RootCode []byte 26 CatchContent string 27 } 28 29 func newTestResource(st *state.State) testResource { 30 rs := resourcetest.NewTestResource() 31 tr := testResource{ 32 TestResource: rs, 33 state: st, 34 } 35 rs.AddTemplate(ctx, "foo", "inky pinky blinky clyde") 36 rs.AddTemplate(ctx, "bar", "inky pinky {{.one}} blinky {{.two}} clyde") 37 rs.AddTemplate(ctx, "baz", "inky pinky {{.baz}} blinky clyde") 38 rs.AddTemplate(ctx, "three", "{{.one}} inky pinky {{.three}} blinky clyde {{.two}}") 39 rs.AddTemplate(ctx, "root", "root") 40 rs.AddTemplate(ctx, "_catch", tr.CatchContent) 41 rs.AddTemplate(ctx, "ouf", "ouch") 42 rs.AddTemplate(ctx, "flagCatch", "flagiee") 43 rs.AddMenu(ctx, "one", "one") 44 rs.AddMenu(ctx, "two", "two") 45 rs.AddLocalFunc("two", getTwo) 46 rs.AddLocalFunc("dyn", getDyn) 47 rs.AddLocalFunc("arg", tr.getInput) 48 rs.AddLocalFunc("echo", getEcho) 49 rs.AddLocalFunc("setFlagOne", setFlag) 50 rs.AddLocalFunc("set_lang", set_lang) 51 rs.AddLocalFunc("aiee", uhOh) 52 53 var b []byte 54 b = NewLine(nil, HALT, nil, nil, nil) 55 rs.AddBytecode(ctx, "one", b) 56 57 b = NewLine(nil, MOUT, []string{"repent", "0"}, nil, nil) 58 b = NewLine(b, HALT, nil, nil, nil) 59 rs.AddBytecode(ctx, "_catch", b) 60 61 b = NewLine(nil, MOUT, []string{"repent", "0"}, nil, nil) 62 b = NewLine(b, HALT, nil, nil, nil) 63 b = NewLine(b, MOVE, []string{"_"}, nil, nil) 64 rs.AddBytecode(ctx, "flagCatch", b) 65 66 b = NewLine(nil, MOUT, []string{"oo", "1"}, nil, nil) 67 b = NewLine(b, HALT, nil, nil, nil) 68 rs.AddBytecode(ctx, "ouf", b) 69 70 rs.AddBytecode(ctx, "root", tr.RootCode) 71 72 return tr 73 } 74 75 func getOne(ctx context.Context, sym string, input []byte) (resource.Result, error) { 76 return resource.Result{ 77 Content: "one", 78 }, nil 79 } 80 81 func getTwo(ctx context.Context, sym string, input []byte) (resource.Result, error) { 82 return resource.Result{ 83 Content: "two", 84 }, nil 85 } 86 87 func getDyn(ctx context.Context, sym string, input []byte) (resource.Result, error) { 88 return resource.Result{ 89 Content: dynVal, 90 }, nil 91 } 92 93 func getEcho(ctx context.Context, sym string, input []byte) (resource.Result, error) { 94 r := fmt.Sprintf("echo: %s", input) 95 return resource.Result{ 96 Content: r, 97 }, nil 98 } 99 100 101 func uhOh(ctx context.Context, sym string, input []byte) (resource.Result, error) { 102 return resource.Result{}, fmt.Errorf("uh-oh spaghetti'ohs") 103 } 104 105 func setFlag(ctx context.Context, sym string, input []byte) (resource.Result, error) { 106 s := fmt.Sprintf("ping") 107 r := resource.Result{ 108 Content: s, 109 } 110 if len(input) > 0 { 111 r.FlagSet = append(r.FlagSet, uint32(input[0])) 112 } 113 if len(input) > 1 { 114 r.FlagReset = append(r.FlagReset, uint32(input[1])) 115 } 116 log.Printf("setflag %v", r) 117 return r, nil 118 119 } 120 121 func set_lang(ctx context.Context, sym string, input []byte) (resource.Result, error) { 122 return resource.Result{ 123 Content: string(input), 124 FlagSet: []uint32{state.FLAG_LANG}, 125 }, nil 126 } 127 // 128 //type TestStatefulResolver struct { 129 // state *state.State 130 //} 131 132 func (r testResource) FuncFor(ctx context.Context, sym string) (resource.EntryFunc, error) { 133 switch sym { 134 case "one": 135 return getOne, nil 136 case "two": 137 return getTwo, nil 138 case "dyn": 139 return getDyn, nil 140 case "arg": 141 return r.getInput, nil 142 case "echo": 143 return getEcho, nil 144 case "setFlagOne": 145 return setFlag, nil 146 case "set_lang": 147 return set_lang, nil 148 case "aiee": 149 return uhOh, nil 150 } 151 return nil, fmt.Errorf("invalid function: '%s'", sym) 152 } 153 154 func(r testResource) getInput(ctx context.Context, sym string, input []byte) (resource.Result, error) { 155 v, err := r.state.GetInput() 156 return resource.Result{ 157 Content: string(v), 158 }, err 159 } 160 161 func(r testResource) getCode(sym string) ([]byte, error) { 162 var b []byte 163 switch sym { 164 case "_catch": 165 b = NewLine(b, MOUT, []string{"repent", "0"}, nil, nil) 166 b = NewLine(b, HALT, nil, nil, nil) 167 case "flagCatch": 168 b = NewLine(b, MOUT, []string{"repent", "0"}, nil, nil) 169 b = NewLine(b, HALT, nil, nil, nil) 170 b = NewLine(b, MOVE, []string{"_"}, nil, nil) 171 case "root": 172 b = r.RootCode 173 case "ouf": 174 b = NewLine(b, MOUT, []string{"oo", "1"}, nil, nil) 175 b = NewLine(b, HALT, nil, nil, nil) 176 } 177 178 return b, nil 179 } 180 181 func TestRun(t *testing.T) { 182 st := state.NewState(5) 183 rs := newTestResource(st) 184 rs.Lock() 185 ca := cache.NewCache() 186 vm := NewVm(st, &rs, ca, nil) 187 188 b := NewLine(nil, MOVE, []string{"foo"}, nil, nil) 189 b = NewLine(b, HALT, nil, nil, nil) 190 ctx := context.Background() 191 _, err := vm.Run(ctx, b) 192 if err == nil { 193 t.Fatalf("expected error") 194 } 195 196 b = []byte{0x01, 0x02} 197 _, err = vm.Run(ctx, b) 198 if err == nil { 199 t.Fatalf("no error on invalid opcode") 200 } 201 } 202 203 func TestRunLoadRender(t *testing.T) { 204 st := state.NewState(5) 205 rs := newTestResource(st) 206 rs.Lock() 207 ca := cache.NewCache() 208 vm := NewVm(st, &rs, ca, nil) 209 210 st.Down("bar") 211 212 var err error 213 ctx := context.Background() 214 b := NewLine(nil, LOAD, []string{"one"}, []byte{0x0a}, nil) 215 b = NewLine(b, MAP, []string{"one"}, nil, nil) 216 b = NewLine(b, LOAD, []string{"two"}, []byte{0x0a}, nil) 217 b = NewLine(b, MAP, []string{"two"}, nil, nil) 218 b = NewLine(b, HALT, nil, nil, nil) 219 b, err = vm.Run(ctx, b) 220 if err != nil { 221 t.Fatal(err) 222 } 223 r, err := vm.Render(ctx) 224 if err != nil { 225 t.Fatal(err) 226 } 227 expect := "inky pinky one blinky two clyde" 228 if r != expect { 229 t.Fatalf("Expected\n\t%s\ngot\n\t%s\n", expect, r) 230 } 231 232 b = NewLine(nil, LOAD, []string{"two"}, []byte{0x0a}, nil) 233 b = NewLine(b, MAP, []string{"two"}, nil, nil) 234 b = NewLine(b, HALT, nil, nil, nil) 235 b, err = vm.Run(ctx, b) 236 if err != nil { 237 t.Fatal(err) 238 } 239 b = NewLine(nil, MAP, []string{"one"}, nil, nil) 240 b = NewLine(b, MAP, []string{"two"}, nil, nil) 241 b = NewLine(b, HALT, nil, nil, nil) 242 _, err = vm.Run(ctx, b) 243 if err != nil { 244 t.Fatal(err) 245 } 246 r, err = vm.Render(ctx) 247 if err != nil { 248 t.Fatal(err) 249 } 250 expect = "inky pinky one blinky two clyde" 251 if r != expect { 252 t.Fatalf("Expected %v, got %v", expect, r) 253 } 254 } 255 256 func TestRunMultiple(t *testing.T) { 257 st := state.NewState(5) 258 rs := newTestResource(st) 259 rs.Lock() 260 ca := cache.NewCache() 261 vm := NewVm(st, &rs, ca, nil) 262 263 ctx := context.Background() 264 b := NewLine(nil, MOVE, []string{"test"}, nil, nil) 265 b = NewLine(b, LOAD, []string{"one"}, []byte{0x00}, nil) 266 b = NewLine(b, LOAD, []string{"two"}, []byte{42}, nil) 267 b = NewLine(b, HALT, nil, nil, nil) 268 var err error 269 b, err = vm.Run(ctx, b) 270 if err == nil { 271 t.Fatal(err) 272 } 273 } 274 275 func TestRunReload(t *testing.T) { 276 st := state.NewState(5) 277 rs := newTestResource(st) 278 rs.Lock() 279 ca := cache.NewCache() 280 szr := render.NewSizer(128) 281 vm := NewVm(st, &rs, ca, szr) 282 283 ctx := context.Background() 284 b := NewLine(nil, MOVE, []string{"root"}, nil, nil) 285 b = NewLine(b, LOAD, []string{"dyn"}, nil, []uint8{0}) 286 b = NewLine(b, MAP, []string{"dyn"}, nil, nil) 287 b = NewLine(b, HALT, nil, nil, nil) 288 _, err := vm.Run(ctx, b) 289 if err != nil { 290 t.Fatal(err) 291 } 292 r, err := vm.Render(ctx) 293 if err != nil { 294 t.Fatal(err) 295 } 296 if r != "root" { 297 t.Fatalf("expected result 'root', got %v", r) 298 } 299 dynVal = "baz" 300 b = NewLine(nil, RELOAD, []string{"dyn"}, nil, nil) 301 b = NewLine(b, HALT, nil, nil, nil) 302 _, err = vm.Run(ctx, b) 303 if err != nil { 304 t.Fatal(err) 305 } 306 } 307 308 func TestHalt(t *testing.T) { 309 st := state.NewState(5) 310 rs := newTestResource(st) 311 rs.Lock() 312 ca := cache.NewCache() 313 vm := NewVm(st, &rs, ca, nil) 314 315 b := NewLine(nil, MOVE, []string{"root"}, nil, nil) 316 b = NewLine(b, LOAD, []string{"one"}, nil, []uint8{0}) 317 b = NewLine(b, HALT, nil, nil, nil) 318 b = NewLine(b, MOVE, []string{"foo"}, nil, nil) 319 var err error 320 ctx := context.Background() 321 b, err = vm.Run(ctx, b) 322 if err != nil { 323 t.Error(err) 324 } 325 r, _ := st.Where() 326 if r == "foo" { 327 t.Fatalf("Expected where-symbol not to be 'foo'") 328 } 329 if !bytes.Equal(b[:2], []byte{0x00, MOVE}) { 330 t.Fatalf("Expected MOVE instruction, found '%v'", b) 331 } 332 } 333 334 func TestRunArg(t *testing.T) { 335 st := state.NewState(5) 336 rs := newTestResource(st) 337 rs.Lock() 338 ca := cache.NewCache() 339 vm := NewVm(st, &rs, ca, nil) 340 341 input := []byte("bar") 342 _ = st.SetInput(input) 343 344 bi := NewLine(nil, INCMP, []string{"baz", "bar"}, nil, nil) 345 ctx := context.Background() 346 347 var err error 348 b, err := vm.Run(ctx, bi) 349 if err == nil { 350 t.Fatalf("expected error") 351 } 352 l := len(b) 353 if l != 0 { 354 t.Fatalf("expected empty remainder, got length %v: %v", l, b) 355 } 356 r, _ := st.Where() 357 if r != "baz" { 358 t.Fatalf("expected where-state baz, got %v", r) 359 } 360 } 361 362 func TestRunInputHandler(t *testing.T) { 363 st := state.NewState(5) 364 rs := newTestResource(st) 365 rs.Lock() 366 ca := cache.NewCache() 367 vm := NewVm(st, &rs, ca, nil) 368 369 _ = st.SetInput([]byte("baz")) 370 371 bi := NewLine([]byte{}, INCMP, []string{"aiee", "bar"}, nil, nil) 372 bi = NewLine(bi, INCMP, []string{"foo", "baz"}, nil, nil) 373 bi = NewLine(bi, LOAD, []string{"one"}, []byte{0x00}, nil) 374 bi = NewLine(bi, LOAD, []string{"two"}, []byte{0x03}, nil) 375 bi = NewLine(bi, MAP, []string{"one"}, nil, nil) 376 bi = NewLine(bi, MAP, []string{"two"}, nil, nil) 377 bi = NewLine(bi, HALT, nil, nil, nil) 378 379 var err error 380 ctx := context.Background() 381 _, err = vm.Run(ctx, bi) 382 if err == nil { 383 t.Fatalf("expected error") 384 } 385 r, _ := st.Where() 386 if r != "foo" { 387 t.Fatalf("expected where-sym 'foo', got '%v'", r) 388 } 389 } 390 391 func TestRunArgInvalid(t *testing.T) { 392 st := state.NewState(5) 393 rs := newTestResource(st) 394 rs.Lock() 395 ca := cache.NewCache() 396 vm := NewVm(st, &rs, ca, nil) 397 398 _ = st.SetInput([]byte("foo")) 399 400 var err error 401 402 st.Down("root") 403 b := NewLine(nil, INCMP, []string{"baz", "bar"}, nil, nil) 404 405 ctx := context.Background() 406 b, err = vm.Run(ctx, b) 407 if err != nil { 408 t.Fatal(err) 409 } 410 location, _ := st.Where() 411 if location != "_catch" { 412 t.Fatalf("expected where-state _catch, got %v", location) 413 } 414 415 r, err := vm.Render(ctx) 416 if err != nil { 417 t.Fatal(err) 418 } 419 expect := `invalid input: 'foo' 420 0:repent` 421 if r != expect { 422 t.Fatalf("expected:\n\t%s\ngot:\n\t%s", expect, r) 423 } 424 } 425 426 func TestRunMenu(t *testing.T) { 427 st := state.NewState(5) 428 rs := newTestResource(st) 429 ca := cache.NewCache() 430 vm := NewVm(st, &rs, ca, nil) 431 432 var err error 433 434 ctx := context.Background() 435 436 rs.AddBytecode(ctx, "foo", []byte{}) 437 rs.Lock() 438 b := NewLine(nil, MOVE, []string{"foo"}, nil, nil) 439 b = NewLine(b, MOUT, []string{"one", "0"}, nil, nil) 440 b = NewLine(b, MOUT, []string{"two", "1"}, nil, nil) 441 b = NewLine(b, HALT, nil, nil, nil) 442 443 b, err = vm.Run(ctx, b) 444 if err != nil { 445 t.Error(err) 446 } 447 l := len(b) 448 if l != 0 { 449 t.Errorf("expected empty remainder, got length %v: %v", l, b) 450 } 451 452 r, err := vm.Render(ctx) 453 if err != nil { 454 t.Fatal(err) 455 } 456 expect := "inky pinky blinky clyde\n0:one\n1:two" 457 if r != expect { 458 t.Fatalf("expected:\n\t%s\ngot:\n\t%s\n", expect, r) 459 } 460 } 461 462 func TestRunMenuBrowse(t *testing.T) { 463 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.") 464 st := state.NewState(5) 465 rs := newTestResource(st) 466 ca := cache.NewCache() 467 vm := NewVm(st, &rs, ca, nil) 468 469 var err error 470 471 ctx := context.Background() 472 473 rs.AddBytecode(ctx, "foo", []byte{}) 474 rs.Lock() 475 b := NewLine(nil, MOVE, []string{"foo"}, nil, nil) 476 b = NewLine(b, MOUT, []string{"one", "0"}, nil, nil) 477 b = NewLine(b, MOUT, []string{"two", "1"}, nil, nil) 478 b = NewLine(b, HALT, nil, nil, nil) 479 480 b, err = vm.Run(ctx, b) 481 if err != nil { 482 t.Error(err) 483 } 484 l := len(b) 485 if l != 0 { 486 t.Errorf("expected empty remainder, got length %v: %v", l, b) 487 } 488 489 r, err := vm.Render(ctx) 490 if err != nil { 491 t.Fatal(err) 492 } 493 expect := "inky pinky blinky clyde\n0:one\n1:two" 494 if r != expect { 495 t.Fatalf("expected:\n\t%s\ngot:\n\t%s\n", expect, r) 496 } 497 } 498 499 func TestRunReturn(t *testing.T) { 500 st := state.NewState(5) 501 rs := newTestResource(st) 502 rs.Lock() 503 ca := cache.NewCache() 504 vm := NewVm(st, &rs, ca, nil) 505 506 var err error 507 508 st.Down("root") 509 b := NewLine(nil, INCMP, []string{"bar", "0"}, nil, nil) 510 b = NewLine(b, INCMP, []string{"_", "1"}, nil, nil) 511 512 ctx := context.Background() 513 514 st.SetInput([]byte("0")) 515 b, err = vm.Run(ctx, b) 516 if err == nil { 517 t.Fatalf("expected error") 518 } 519 location, _ := st.Where() 520 if location != "bar" { 521 t.Fatalf("expected location 'bar', got '%s'", location) 522 } 523 524 st.SetInput([]byte("1")) 525 b, err = vm.Run(ctx, b) 526 if err != nil { 527 t.Fatal(err) 528 } 529 location, _ = st.Where() 530 if location != "root" { 531 t.Fatalf("expected location 'root', got '%s'", location) 532 } 533 } 534 535 536 func TestRunLoadInput(t *testing.T) { 537 st := state.NewState(5) 538 rs := newTestResource(st) 539 rs.Lock() 540 ca := cache.NewCache() 541 vm := NewVm(st, &rs, ca, nil) 542 543 var err error 544 545 st.Down("root") 546 st.SetInput([]byte("foobar")) 547 548 b := NewLine(nil, LOAD, []string{"echo"}, []byte{0x00}, nil) 549 b = NewLine(b, HALT, nil, nil, nil) 550 551 ctx := context.Background() 552 553 b, err = vm.Run(ctx, b) 554 if err != nil { 555 t.Fatal(err) 556 } 557 558 r, err := ca.Get("echo") 559 if err != nil { 560 t.Fatal(err) 561 } 562 if r != "echo: foobar" { 563 t.Fatalf("expected 'echo: foobar', got %s", r) 564 } 565 } 566 567 func TestInputBranch(t *testing.T) { 568 st := state.NewState(5) 569 rs := newTestResource(st) 570 ca := cache.NewCache() 571 vm := NewVm(st, &rs, ca, nil) 572 573 var err error 574 575 st.Down("root") 576 577 b := NewLine(nil, LOAD, []string{"setFlagOne"}, []byte{0x00}, nil) 578 b = NewLine(b, RELOAD, []string{"setFlagOne"}, nil, nil) 579 b = NewLine(b, CATCH, []string{"flagCatch"}, []byte{8}, []uint8{1}) 580 b = NewLine(b, CATCH, []string{"one"}, []byte{9}, []uint8{1}) 581 rs.RootCode = b 582 rs.AddBytecode(ctx, "root", rs.RootCode) 583 rs.Lock() 584 585 ctx := context.Background() 586 587 st.SetInput([]byte{0x08}) 588 b, err = vm.Run(ctx, b) 589 if err != nil { 590 t.Fatal(err) 591 } 592 location, _ := st.Where() 593 if location != "flagCatch" { 594 t.Fatalf("expected 'flagCatch', got %s", location) 595 } 596 597 st.SetInput([]byte{0x09, 0x08}) 598 b, err = vm.Run(ctx, b) 599 if err != nil { 600 t.Fatal(err) 601 } 602 location, _ = st.Where() 603 if location != "one" { 604 t.Fatalf("expected 'one', got %s", location) 605 } 606 } 607 608 func TestInputIgnore(t *testing.T) { 609 st := state.NewState(5) 610 rs := newTestResource(st) 611 rs.Lock() 612 ca := cache.NewCache() 613 vm := NewVm(st, &rs, ca, nil) 614 615 var err error 616 617 st.Down("root") 618 619 b := NewLine(nil, INCMP, []string{"one", "foo"}, nil, nil) 620 b = NewLine(b, INCMP, []string{"two", "bar"}, nil, nil) 621 b = NewLine(b, HALT, nil, nil, nil) 622 623 ctx := context.Background() 624 625 st.SetInput([]byte("foo")) 626 b, err = vm.Run(ctx, b) 627 if err != nil { 628 t.Fatal(err) 629 } 630 631 location, _ := st.Where() 632 if location != "one" { 633 t.Fatalf("expected 'one', got %s", location) 634 } 635 } 636 637 func TestInputIgnoreWildcard(t *testing.T) { 638 st := state.NewState(5) 639 rs := newTestResource(st) 640 rs.Lock() 641 ca := cache.NewCache() 642 vm := NewVm(st, &rs, ca, nil) 643 644 var err error 645 646 st.Down("root") 647 648 b := NewLine(nil, INCMP, []string{"one", "foo"}, nil, nil) 649 b = NewLine(b, INCMP, []string{"two", "*"}, nil, nil) 650 651 ctx := context.Background() 652 653 st.SetInput([]byte("foo")) 654 b, err = vm.Run(ctx, b) 655 if err != nil { 656 t.Fatal(err) 657 } 658 659 location, _ := st.Where() 660 if location != "one" { 661 t.Fatalf("expected 'one', got %s", location) 662 } 663 } 664 665 func TestCatchCleanMenu(t *testing.T) { 666 st := state.NewState(5) 667 rs := newTestResource(st) 668 rs.Lock() 669 ca := cache.NewCache() 670 vm := NewVm(st, &rs, ca, nil) 671 672 var err error 673 674 st.Down("root") 675 676 b := NewLine(nil, MOUT, []string{"1", "one"}, nil, nil) 677 b = NewLine(b, MOUT, []string{"2", "two"}, nil, nil) 678 b = NewLine(b, HALT, nil, nil, nil) 679 b = NewLine(b, INCMP, []string{"foo", "1"}, nil, nil) 680 b = NewLine(b, CATCH, []string{"ouf"}, []byte{0x08}, []uint8{0x00}) 681 682 ctx := context.Background() 683 684 st.SetInput([]byte("foo")) 685 b, err = vm.Run(ctx, b) 686 if err != nil { 687 t.Fatal(err) 688 } 689 690 st.SetInput([]byte("foo")) 691 b, err = vm.Run(ctx, b) 692 if err != nil { 693 t.Fatal(err) 694 } 695 696 _, err = vm.Render(ctx) 697 if err != nil { 698 t.Fatal(err) 699 } 700 } 701 702 func TestSetLang(t *testing.T) { 703 st := state.NewState(0) 704 rs := newTestResource(st) 705 rs.Lock() 706 ca := cache.NewCache() 707 vm := NewVm(st, &rs, ca, nil) 708 709 var err error 710 711 st.Down("root") 712 713 st.SetInput([]byte("no")) 714 b := NewLine(nil, LOAD, []string{"set_lang"}, []byte{0x01, 0x00}, nil) 715 b = NewLine(b, HALT, nil, nil, nil) 716 717 ctx := context.Background() 718 b, err = vm.Run(ctx, b) 719 if err != nil { 720 t.Fatal(err) 721 } 722 lang := *st.Language 723 if lang.Code != "nor" { 724 t.Fatalf("expected language 'nor',, got %s", lang.Code) 725 } 726 } 727 728 func TestLoadError(t *testing.T) { 729 st := state.NewState(0) 730 st.UseDebug() 731 rs := newTestResource(st) 732 rs.Lock() 733 ca := cache.NewCache() 734 vm := NewVm(st, &rs, ca, nil) 735 736 st.Down("root") 737 st.SetInput([]byte{}) 738 b := NewLine(nil, LOAD, []string{"aiee"}, []byte{0x01, 0x10}, nil) 739 b = NewLine(b, HALT, nil, nil, nil) 740 741 var err error 742 ctx := context.Background() 743 b, err = vm.Run(ctx, b) 744 if err != nil { 745 t.Fatal(err) 746 } 747 748 r, err := vm.Render(ctx) 749 if err != nil { 750 t.Fatal(err) 751 } 752 expect := `error aiee:0 753 0:repent` 754 if r != expect { 755 t.Fatalf("expected: \n\t%s\ngot:\n\t%s", expect, r) 756 } 757 } 758 759 func TestMatchFlag(t *testing.T) { 760 var err error 761 ctx := context.Background() 762 763 st := state.NewState(1) 764 st.UseDebug() 765 rs := newTestResource(st) 766 rs.Lock() 767 ca := cache.NewCache() 768 vm := NewVm(st, &rs, ca, nil) 769 770 st.Down("root") 771 st.SetFlag(state.FLAG_USERSTART) 772 st.SetInput([]byte{}) 773 b := NewLine(nil, CATCH, []string{"aiee"}, []byte{state.FLAG_USERSTART}, []uint8{1}) 774 b = NewLine(b, HALT, nil, nil, nil) 775 b, err = vm.Run(ctx, b) 776 if err == nil { 777 t.Fatal(err) 778 } 779 780 st.SetFlag(state.FLAG_USERSTART) 781 st.SetInput([]byte{}) 782 b = NewLine(nil, CATCH, []string{"aiee"}, []byte{state.FLAG_USERSTART}, []uint8{0}) 783 b = NewLine(b, HALT, nil, nil, nil) 784 b, err = vm.Run(ctx, b) 785 if err != nil { 786 t.Fatal(err) 787 } 788 789 st.Restart() 790 st.SetFlag(state.FLAG_USERSTART) 791 st.SetInput([]byte{}) 792 b = NewLine(nil, CROAK, nil, []byte{state.FLAG_USERSTART}, []uint8{1}) 793 b = NewLine(b, HALT, nil, nil, nil) 794 b, err = vm.Run(ctx, b) 795 if err != nil { 796 t.Fatal(err) 797 } 798 if st.MatchFlag(state.FLAG_TERMINATE, false) { 799 t.Fatalf("expected terminate set") 800 } 801 802 st.Restart() 803 st.SetFlag(state.FLAG_USERSTART) 804 st.SetInput([]byte{}) 805 b = NewLine(nil, CROAK, nil, []byte{state.FLAG_USERSTART}, []uint8{0}) 806 b = NewLine(b, HALT, nil, nil, nil) 807 b, err = vm.Run(ctx, b) 808 if err != nil { 809 t.Fatal(err) 810 } 811 if st.MatchFlag(state.FLAG_TERMINATE, true) { 812 t.Fatalf("expected no terminate") 813 } 814 } 815 816 func TestBatchRun(t *testing.T) { 817 var err error 818 ctx := context.Background() 819 st := state.NewState(0) 820 st.Down("root") 821 st.Down("one") 822 st.Down("two") 823 ca := cache.NewCache() 824 rs := newTestResource(st) 825 rs.Lock() 826 b := NewLine(nil, MNEXT, []string{"fwd", "0"}, nil, nil) 827 b = NewLine(b, MPREV, []string{"back", "11"}, nil, nil) 828 b = NewLine(b, MSINK, nil, nil, nil) 829 b = NewLine(b, HALT, nil, nil, nil) 830 vm := NewVm(st, rs, ca, nil) 831 832 b, err = vm.Run(ctx, b) 833 if err != nil { 834 t.Fatal(err) 835 } 836 }