github.com/mvdan/u-root-coreutils@v0.0.0-20230122170626-c2eef2898555/pkg/forth/forth_test.go (about)

     1  // Copyright 2018 the u-root Authors. All rights reserved
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package forth
     6  
     7  import (
     8  	"errors"
     9  	"os"
    10  	"strconv"
    11  	"testing"
    12  )
    13  
    14  type forthTest struct {
    15  	val   string
    16  	res   Cell
    17  	err   error
    18  	empty bool
    19  }
    20  
    21  var forthTests = []forthTest{
    22  	{val: "hostname", res: "", empty: true},
    23  	{val: "2", res: "2", empty: true},
    24  	{val: "2 2 +", res: "4", empty: true},
    25  	{val: "4 2 -", res: "2", empty: true},
    26  	{val: "4 2 *", res: "8", empty: true},
    27  	{val: "4 2 /", res: "2", empty: true},
    28  	{val: "5 2 %", res: "1", empty: true},
    29  	{val: "sb43 hostbase", res: "43", empty: true},
    30  	{val: "sb43 hostbase dup 20 / swap 20 % dup ifelse", res: "3", empty: true},
    31  	{val: "sb40 hostbase dup 20 / swap 20 % dup ifelse", res: "2", empty: true},
    32  	{val: "2 4 swap /", res: "2", empty: true},
    33  	{val: "0 1 1 ifelse", res: "1", empty: true},
    34  	{val: "0 1 0 ifelse", res: "0", empty: true},
    35  	{val: "str cat strcat", res: "strcat", empty: true},
    36  	{val: "1 dup +", res: "2", empty: true},
    37  	{val: "4095 4096 roundup", res: "4096", empty: true},
    38  	{val: "4097 8192 roundup", res: "8192", empty: true},
    39  	{val: "2 x +", res: "2", err: strconv.ErrSyntax, empty: false},
    40  	{val: "1 dd +", res: "2", empty: true},
    41  	{val: "1 d3d", res: "3", empty: true},
    42  	{val: "drop", res: "", err: ErrEmptyStack, empty: true},
    43  	{val: "5 5 + hostbase", res: "", err: strconv.ErrSyntax, empty: true},
    44  	{val: "1 1 '+ newword 1 1 '+ newword", res: "", err: ErrWordExist, empty: true},
    45  	{val: "1 4 bad newword", res: "", err: ErrNotEnoughElements, empty: false},
    46  }
    47  
    48  func TestForth(t *testing.T) {
    49  	forthTests[0].res, _ = os.Hostname()
    50  	f := New()
    51  	if f.Length() != 0 {
    52  		t.Errorf("Test: stack is %d and should be 0", f.Length())
    53  	}
    54  	if f.Empty() != true {
    55  		t.Errorf("Test: stack is %v and should be false", f.Empty())
    56  	}
    57  	f.Push("test")
    58  	if f.Length() != 1 {
    59  		t.Errorf("Test: stack is %d and should be 1", f.Length())
    60  	}
    61  	if f.Empty() == true {
    62  		t.Errorf("Test: stack is %v and should be false", f.Empty())
    63  	}
    64  	f.Reset()
    65  	if f.Length() != 0 {
    66  		t.Errorf("Test: After Reset(): stack is %d and should be 0", f.Length())
    67  	}
    68  	if f.Empty() != true {
    69  		t.Errorf("Test: After Reset(): stack is %v and should be true", f.Empty())
    70  	}
    71  	NewWord(f, "dd", "dup")
    72  	NewWord(f, "d3d", "dup", "dup", "+", "+")
    73  	for i, tt := range forthTests {
    74  		var err error
    75  		res, err := EvalPop(f, tt.val)
    76  		t.Logf("tt %v res %v err %v", tt, res, err)
    77  		if res == tt.res || errors.Is(err, tt.err) {
    78  			t.Logf("Test: '%v' '%v' '%v': Pass\n", tt.val, res, err)
    79  		} else {
    80  			t.Errorf("Test %d: '%v' got (%v, %v): want (%v, %v): Fail\n", i, tt.val, res, err, tt.res, tt.err)
    81  			t.Logf("ops %v\n", Ops())
    82  			continue
    83  		}
    84  		if f.Empty() != tt.empty {
    85  			t.Errorf("Test %d: %v: stack is %v and should be %v", i, tt, f.Empty(), tt.empty)
    86  		}
    87  		/* stack may not be right; reset it. */
    88  		f.Reset()
    89  	}
    90  }
    91  
    92  func TestBadPop(t *testing.T) {
    93  	var b [3]byte
    94  	f := New()
    95  	f.Push(b)
    96  	res, err := EvalPop(f, "2 +")
    97  	t.Logf("%v, %v", res, err)
    98  	if !errors.Is(err, strconv.ErrSyntax) {
    99  		t.Errorf("got %v, want %v", err, strconv.ErrSyntax)
   100  	}
   101  	if res != nil {
   102  		t.Errorf("got %v, want nil", res)
   103  	}
   104  }
   105  
   106  func TestOpmap(t *testing.T) {
   107  	f := New()
   108  	err := Eval(f, "words")
   109  	if err != nil {
   110  		t.Fatalf("words: got %v, nil", err)
   111  	}
   112  	if f.Length() != 1 {
   113  		t.Fatalf("words: got length %d, want 1", f.Length())
   114  	}
   115  	w := f.Pop()
   116  	switch w.(type) {
   117  	case []string:
   118  	default:
   119  		t.Fatalf("words: got %T, want []string", w)
   120  	}
   121  	t.Logf("words are %v", w)
   122  }
   123  
   124  func TestNewWord(t *testing.T) {
   125  	Debug = t.Logf
   126  	f := New()
   127  	// This test creates a word, tp, with 3 args, which simply
   128  	// pushes 1 and 3 on the stack and applies +.
   129  	// Note the use of ' so we can evaluate + as a string,
   130  	// not an operator.
   131  	err := Eval(f, "1", "3", "'+", "3", "tp", "newword")
   132  	if err != nil {
   133  		t.Fatalf("newword: got %v, nil", err)
   134  	}
   135  	err = Eval(f, "tp")
   136  	if err != nil {
   137  		t.Fatalf("newword: got %v, want nil", err)
   138  	}
   139  	t.Logf("stack %v", f.Stack())
   140  }
   141  
   142  // make sure that if we die in an Eval nested in an Eval, we fall all the way
   143  // back out.
   144  func TestEvalPanic(t *testing.T) {
   145  	f := New()
   146  	Debug = t.Logf
   147  	err := Eval(f, "0", "'+", "2", "p", "newword")
   148  	if err != nil {
   149  		t.Fatalf("newword: got %v, nil", err)
   150  	}
   151  	t.Logf("p created, now try problems")
   152  	err = Eval(f, "0", uint8(0), "+")
   153  	if err == nil {
   154  		t.Fatal("Got nil, want error")
   155  	}
   156  	t.Logf("Test plus with wrong types: %v", err)
   157  	f.Reset()
   158  	err = Eval(f, "p")
   159  	if err == nil {
   160  		t.Fatal("P with too few args: Got nil, want error")
   161  	}
   162  	t.Logf("p with too few args: %v", err)
   163  	err2 := Eval(f, "p", "0", uint8(0), "+")
   164  	if err2.Error() != err.Error() {
   165  		t.Fatalf("Got %v, want %v", err2, err)
   166  	}
   167  }