github.com/masahide/goansible@v0.0.0-20160116054156-01eac649e9f2/lisp/evaler_test.go (about)

     1  package lisp
     2  
     3  import "testing"
     4  import "fmt"
     5  
     6  func TestEval(t *testing.T) {
     7  	var tests = []struct {
     8  		in  string
     9  		out string
    10  	}{
    11  		{"()", "()"},
    12  		{"42", "42"},
    13  		{"1 2 3", "3"},
    14  		{"(+ 42 13)", "55"},
    15  		{"(+ (+ 1 2 3) 4)", "10"},
    16  		{"(quote (1 2 3))", "(1 2 3)"},
    17  		{"(quote (1 (+ 1 2) 3))", "(1 (+ 1 2) 3)"},
    18  		{"(quote hej)", "hej"},
    19  		{"(cons 1 2)", "(1 . 2)"},
    20  		{"(car (cons 1 2))", "1"},
    21  		{"(cdr (cons 1 2))", "2"},
    22  		{"(cons 1 ())", "(1)"},
    23  		{"(cons 1 :(2))", "(1 2)"},
    24  		{":hej", "hej"},
    25  		{"::hej", "(quote hej)"},
    26  		{":(hej hopp)", "(hej hopp)"},
    27  		{"(quote (hej))", "(hej)"},
    28  		{"(if true (+ 1 1) 3)", "2"},
    29  		{"(if false 42 1)", "1"},
    30  		{"(if false 42)", "()"},
    31  		{"(begin (define x) (if x 1 2))", "2"},
    32  		{"(define r 3)", "r"},
    33  		{"(begin 5 (+ 3 4))", "7"},
    34  		{"(begin (define p 3) (+ 39 p))", "42"},
    35  		{"(begin (define p 3) (set! p 4) (+ 1 p))", "5"},
    36  		{"(begin (define p 3) (set! p (+ 1 1)) p)", "2"},
    37  		{"(begin (define pi (+ 3 14)) pi)", "17"},
    38  		{"((lambda (a) (+ a 1)) 42)", "43"},
    39  		{"(begin (define p 10) p)", "10"},
    40  		{"(begin (define inc (lambda (a) (+ a 1))) (inc 42))", "43"},
    41  		// {"(define a 10) ((lambda () (define a 20))) a", "10"},
    42  		{"(define a 0) ((lambda () (set! a 10))) a", "10"},
    43  		{"((lambda (i) i) (+ 5 5))", "10"},
    44  		{"(define inc ((lambda () (begin (define a 0) (lambda () (set! a (+ a 1))))))) (inc) (inc)", "2"},
    45  		{"(define fact (lambda (n) (if (<= n 1) 1 (* n (fact (- n 1)))))) (fact 20)", "2432902008176640000"},
    46  	}
    47  
    48  	for _, test := range tests {
    49  		if actual, err := EvalString(test.in, scope); err != nil {
    50  			t.Error(err)
    51  		} else if fmt.Sprintf("%v", actual) != test.out {
    52  			t.Errorf("Eval \"%v\" gives \"%v\", want \"%v\"", test.in, actual, test.out)
    53  		}
    54  	}
    55  }
    56  
    57  func TestEvalFailures(t *testing.T) {
    58  	var tests = []struct {
    59  		in  string
    60  		out string
    61  	}{
    62  		{"hello", "Unbound variable: hello"},
    63  		{"(set! undefined 42)", "Unbound variable: undefined"},
    64  		{"(lambda (a))", "Ill-formed special form: (lambda (a))"},
    65  		{"(1 2 3)", "The object 1 is not applicable"},
    66  		{"(1", "List was opened but not closed"},
    67  		{"(set! a)", "Ill-formed special form: (set! a)"},
    68  	}
    69  
    70  	for _, test := range tests {
    71  		if _, err := EvalString(test.in, scope); err == nil || err.Error() != test.out {
    72  			t.Errorf("Parse('%v'), want error '%v', got '%v'", test.in, test.out, err)
    73  		}
    74  	}
    75  }