runner_test.go (18940B)
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/internal/resourcetest" 12 "git.defalsify.org/vise.git/render" 13 "git.defalsify.org/vise.git/resource" 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 func uhOh(ctx context.Context, sym string, input []byte) (resource.Result, error) { 101 return resource.Result{}, fmt.Errorf("uh-oh spaghetti'ohs") 102 } 103 104 func setFlag(ctx context.Context, sym string, input []byte) (resource.Result, error) { 105 s := fmt.Sprintf("ping") 106 r := resource.Result{ 107 Content: s, 108 } 109 if len(input) > 0 { 110 r.FlagSet = append(r.FlagSet, uint32(input[0])) 111 } 112 if len(input) > 1 { 113 r.FlagReset = append(r.FlagReset, uint32(input[1])) 114 } 115 log.Printf("setflag %v", r) 116 return r, nil 117 118 } 119 120 func set_lang(ctx context.Context, sym string, input []byte) (resource.Result, error) { 121 return resource.Result{ 122 Content: string(input), 123 FlagSet: []uint32{state.FLAG_LANG}, 124 }, nil 125 } 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 func TestRunLoadInput(t *testing.T) { 536 st := state.NewState(5) 537 rs := newTestResource(st) 538 rs.Lock() 539 ca := cache.NewCache() 540 vm := NewVm(st, &rs, ca, nil) 541 542 var err error 543 544 st.Down("root") 545 st.SetInput([]byte("foobar")) 546 547 b := NewLine(nil, LOAD, []string{"echo"}, []byte{0x00}, nil) 548 b = NewLine(b, HALT, nil, nil, nil) 549 550 ctx := context.Background() 551 552 b, err = vm.Run(ctx, b) 553 if err != nil { 554 t.Fatal(err) 555 } 556 557 r, err := ca.Get("echo") 558 if err != nil { 559 t.Fatal(err) 560 } 561 if r != "echo: foobar" { 562 t.Fatalf("expected 'echo: foobar', got %s", r) 563 } 564 } 565 566 func TestInputBranch(t *testing.T) { 567 st := state.NewState(5) 568 rs := newTestResource(st) 569 ca := cache.NewCache() 570 vm := NewVm(st, &rs, ca, nil) 571 572 var err error 573 574 st.Down("root") 575 576 b := NewLine(nil, LOAD, []string{"setFlagOne"}, []byte{0x00}, nil) 577 b = NewLine(b, RELOAD, []string{"setFlagOne"}, nil, nil) 578 b = NewLine(b, CATCH, []string{"flagCatch"}, []byte{8}, []uint8{1}) 579 b = NewLine(b, CATCH, []string{"one"}, []byte{9}, []uint8{1}) 580 rs.RootCode = b 581 rs.AddBytecode(ctx, "root", rs.RootCode) 582 rs.Lock() 583 584 ctx := context.Background() 585 586 st.SetInput([]byte{0x08}) 587 b, err = vm.Run(ctx, b) 588 if err != nil { 589 t.Fatal(err) 590 } 591 location, _ := st.Where() 592 if location != "flagCatch" { 593 t.Fatalf("expected 'flagCatch', got %s", location) 594 } 595 596 st.SetInput([]byte{0x09, 0x08}) 597 b, err = vm.Run(ctx, b) 598 if err != nil { 599 t.Fatal(err) 600 } 601 location, _ = st.Where() 602 if location != "one" { 603 t.Fatalf("expected 'one', got %s", location) 604 } 605 } 606 607 func TestInputIgnore(t *testing.T) { 608 st := state.NewState(5) 609 rs := newTestResource(st) 610 rs.Lock() 611 ca := cache.NewCache() 612 vm := NewVm(st, &rs, ca, nil) 613 614 var err error 615 616 st.Down("root") 617 618 b := NewLine(nil, INCMP, []string{"one", "foo"}, nil, nil) 619 b = NewLine(b, INCMP, []string{"two", "bar"}, nil, nil) 620 b = NewLine(b, HALT, nil, nil, nil) 621 622 ctx := context.Background() 623 624 st.SetInput([]byte("foo")) 625 b, err = vm.Run(ctx, b) 626 if err != nil { 627 t.Fatal(err) 628 } 629 630 location, _ := st.Where() 631 if location != "one" { 632 t.Fatalf("expected 'one', got %s", location) 633 } 634 } 635 636 func TestInputIgnoreWildcard(t *testing.T) { 637 st := state.NewState(5) 638 rs := newTestResource(st) 639 rs.Lock() 640 ca := cache.NewCache() 641 vm := NewVm(st, &rs, ca, nil) 642 643 var err error 644 645 st.Down("root") 646 647 b := NewLine(nil, INCMP, []string{"one", "foo"}, nil, nil) 648 b = NewLine(b, INCMP, []string{"two", "*"}, nil, nil) 649 650 ctx := context.Background() 651 652 st.SetInput([]byte("foo")) 653 b, err = vm.Run(ctx, b) 654 if err != nil { 655 t.Fatal(err) 656 } 657 658 location, _ := st.Where() 659 if location != "one" { 660 t.Fatalf("expected 'one', got %s", location) 661 } 662 } 663 664 func TestCatchCleanMenu(t *testing.T) { 665 st := state.NewState(5) 666 rs := newTestResource(st) 667 rs.Lock() 668 ca := cache.NewCache() 669 vm := NewVm(st, &rs, ca, nil) 670 671 var err error 672 673 st.Down("root") 674 675 b := NewLine(nil, MOUT, []string{"1", "one"}, nil, nil) 676 b = NewLine(b, MOUT, []string{"2", "two"}, nil, nil) 677 b = NewLine(b, HALT, nil, nil, nil) 678 b = NewLine(b, INCMP, []string{"foo", "1"}, nil, nil) 679 b = NewLine(b, CATCH, []string{"ouf"}, []byte{0x08}, []uint8{0x00}) 680 681 ctx := context.Background() 682 683 st.SetInput([]byte("foo")) 684 b, err = vm.Run(ctx, b) 685 if err != nil { 686 t.Fatal(err) 687 } 688 689 st.SetInput([]byte("foo")) 690 b, err = vm.Run(ctx, b) 691 if err != nil { 692 t.Fatal(err) 693 } 694 695 _, err = vm.Render(ctx) 696 if err != nil { 697 t.Fatal(err) 698 } 699 } 700 701 func TestSetLang(t *testing.T) { 702 st := state.NewState(0) 703 rs := newTestResource(st) 704 rs.Lock() 705 ca := cache.NewCache() 706 vm := NewVm(st, &rs, ca, nil) 707 708 var err error 709 710 st.Down("root") 711 712 st.SetInput([]byte("no")) 713 b := NewLine(nil, LOAD, []string{"set_lang"}, []byte{0x01, 0x00}, nil) 714 b = NewLine(b, HALT, nil, nil, nil) 715 716 ctx := context.Background() 717 b, err = vm.Run(ctx, b) 718 if err != nil { 719 t.Fatal(err) 720 } 721 lang := *st.Language 722 if lang.Code != "nor" { 723 t.Fatalf("expected language 'nor',, got %s", lang.Code) 724 } 725 } 726 727 func TestLoadError(t *testing.T) { 728 st := state.NewState(0) 729 st.UseDebug() 730 rs := newTestResource(st) 731 rs.Lock() 732 ca := cache.NewCache() 733 vm := NewVm(st, &rs, ca, nil) 734 735 st.Down("root") 736 st.SetInput([]byte{}) 737 b := NewLine(nil, LOAD, []string{"aiee"}, []byte{0x01, 0x10}, nil) 738 b = NewLine(b, HALT, nil, nil, nil) 739 740 var err error 741 ctx := context.Background() 742 b, err = vm.Run(ctx, b) 743 if err != nil { 744 t.Fatal(err) 745 } 746 747 r, err := vm.Render(ctx) 748 if err != nil { 749 t.Fatal(err) 750 } 751 expect := `error aiee:0 752 0:repent` 753 if r != expect { 754 t.Fatalf("expected: \n\t%s\ngot:\n\t%s", expect, r) 755 } 756 } 757 758 func TestMatchFlag(t *testing.T) { 759 var err error 760 ctx := context.Background() 761 762 st := state.NewState(1) 763 st.UseDebug() 764 rs := newTestResource(st) 765 rs.Lock() 766 ca := cache.NewCache() 767 vm := NewVm(st, &rs, ca, nil) 768 769 st.Down("root") 770 st.SetFlag(state.FLAG_USERSTART) 771 st.SetInput([]byte{}) 772 b := NewLine(nil, CATCH, []string{"aiee"}, []byte{state.FLAG_USERSTART}, []uint8{1}) 773 b = NewLine(b, HALT, nil, nil, nil) 774 b, err = vm.Run(ctx, b) 775 if err == nil { 776 t.Fatal(err) 777 } 778 779 st.SetFlag(state.FLAG_USERSTART) 780 st.SetInput([]byte{}) 781 b = NewLine(nil, CATCH, []string{"aiee"}, []byte{state.FLAG_USERSTART}, []uint8{0}) 782 b = NewLine(b, HALT, nil, nil, nil) 783 b, err = vm.Run(ctx, b) 784 if err != nil { 785 t.Fatal(err) 786 } 787 788 st.Restart() 789 st.SetFlag(state.FLAG_USERSTART) 790 st.SetInput([]byte{}) 791 b = NewLine(nil, CROAK, nil, []byte{state.FLAG_USERSTART}, []uint8{1}) 792 b = NewLine(b, HALT, nil, nil, nil) 793 b, err = vm.Run(ctx, b) 794 if err != nil { 795 t.Fatal(err) 796 } 797 if st.MatchFlag(state.FLAG_TERMINATE, false) { 798 t.Fatalf("expected terminate set") 799 } 800 801 st.Restart() 802 st.SetFlag(state.FLAG_USERSTART) 803 st.SetInput([]byte{}) 804 b = NewLine(nil, CROAK, nil, []byte{state.FLAG_USERSTART}, []uint8{0}) 805 b = NewLine(b, HALT, nil, nil, nil) 806 b, err = vm.Run(ctx, b) 807 if err != nil { 808 t.Fatal(err) 809 } 810 if st.MatchFlag(state.FLAG_TERMINATE, true) { 811 t.Fatalf("expected no terminate") 812 } 813 } 814 815 func TestBatchRun(t *testing.T) { 816 var err error 817 ctx := context.Background() 818 st := state.NewState(0) 819 st.Down("root") 820 st.Down("one") 821 st.Down("two") 822 ca := cache.NewCache() 823 rs := newTestResource(st) 824 rs.Lock() 825 b := NewLine(nil, MNEXT, []string{"fwd", "0"}, nil, nil) 826 b = NewLine(b, MPREV, []string{"back", "11"}, nil, nil) 827 b = NewLine(b, MSINK, nil, nil, nil) 828 b = NewLine(b, HALT, nil, nil, nil) 829 vm := NewVm(st, rs, ca, nil) 830 831 b, err = vm.Run(ctx, b) 832 if err != nil { 833 t.Fatal(err) 834 } 835 }