PageRenderTime 23ms CodeModel.GetById 1ms app.highlight 19ms RepoModel.GetById 1ms app.codeStats 1ms

/src/pkg/exp/eval/eval_test.go

https://code.google.com/p/golang-on-cygwin/
Go | 254 lines | 186 code | 43 blank | 25 comment | 24 complexity | dd832e42add30e7e92daa21bedb30a62 MD5 | raw file
  1// Copyright 2009 The Go 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
  5package eval
  6
  7import (
  8	"bignum";
  9	"flag";
 10	"fmt";
 11	"log";
 12	"os";
 13	"reflect";
 14	"testing";
 15)
 16
 17// Print each statement or expression before parsing it
 18var noisy = false
 19
 20func init()	{ flag.BoolVar(&noisy, "noisy", false, "chatter during eval tests") }
 21
 22/*
 23 * Generic statement/expression test framework
 24 */
 25
 26type test []job
 27
 28type job struct {
 29	code	string;
 30	cerr	string;
 31	rterr	string;
 32	val	Value;
 33	noval	bool;
 34}
 35
 36func runTests(t *testing.T, baseName string, tests []test) {
 37	for i, test := range tests {
 38		name := fmt.Sprintf("%s[%d]", baseName, i);
 39		test.run(t, name);
 40	}
 41}
 42
 43func (a test) run(t *testing.T, name string) {
 44	w := newTestWorld();
 45	for _, j := range a {
 46		src := j.code;
 47		if noisy {
 48			println("code:", src)
 49		}
 50
 51		code, err := w.Compile(src);
 52		if err != nil {
 53			if j.cerr == "" {
 54				t.Errorf("%s: Compile %s: %v", name, src, err);
 55				break;
 56			}
 57			if !match(t, err, j.cerr) {
 58				t.Errorf("%s: Compile %s = error %s; want %v", name, src, err, j.cerr);
 59				break;
 60			}
 61			continue;
 62		}
 63		if j.cerr != "" {
 64			t.Errorf("%s: Compile %s succeeded; want %s", name, src, j.cerr);
 65			break;
 66		}
 67
 68		val, err := code.Run();
 69		if err != nil {
 70			if j.rterr == "" {
 71				t.Errorf("%s: Run %s: %v", name, src, err);
 72				break;
 73			}
 74			if !match(t, err, j.rterr) {
 75				t.Errorf("%s: Run %s = error %s; want %v", name, src, err, j.rterr);
 76				break;
 77			}
 78			continue;
 79		}
 80		if j.rterr != "" {
 81			t.Errorf("%s: Run %s succeeded; want %s", name, src, j.rterr);
 82			break;
 83		}
 84
 85		if !j.noval && !reflect.DeepEqual(val, j.val) {
 86			t.Errorf("%s: Run %s = %T(%v) want %T(%v)", name, src, val, val, j.val, j.val)
 87		}
 88	}
 89}
 90
 91func match(t *testing.T, err os.Error, pat string) bool {
 92	ok, errstr := testing.MatchString(pat, err.String());
 93	if errstr != "" {
 94		t.Fatalf("compile regexp %s: %v", pat, errstr)
 95	}
 96	return ok;
 97}
 98
 99
100/*
101 * Test constructors
102 */
103
104// Expression compile error
105func CErr(expr string, cerr string) test	{ return test([]job{job{code: expr, cerr: cerr}}) }
106
107// Expression runtime error
108func RErr(expr string, rterr string) test	{ return test([]job{job{code: expr, rterr: rterr}}) }
109
110// Expression value
111func Val(expr string, val interface{}) test {
112	return test([]job{job{code: expr, val: toValue(val)}})
113}
114
115// Statement runs without error
116func Run(stmts string) test	{ return test([]job{job{code: stmts, noval: true}}) }
117
118// Two statements without error.
119// TODO(rsc): Should be possible with Run but the parser
120// won't let us do both top-level and non-top-level statements.
121func Run2(stmt1, stmt2 string) test {
122	return test([]job{job{code: stmt1, noval: true}, job{code: stmt2, noval: true}})
123}
124
125// Statement runs and test one expression's value
126func Val1(stmts string, expr1 string, val1 interface{}) test {
127	return test([]job{
128		job{code: stmts, noval: true},
129		job{code: expr1, val: toValue(val1)},
130	})
131}
132
133// Statement runs and test two expressions' values
134func Val2(stmts string, expr1 string, val1 interface{}, expr2 string, val2 interface{}) test {
135	return test([]job{
136		job{code: stmts, noval: true},
137		job{code: expr1, val: toValue(val1)},
138		job{code: expr2, val: toValue(val2)},
139	})
140}
141
142/*
143 * Value constructors
144 */
145
146type vstruct []interface{}
147
148type varray []interface{}
149
150type vslice struct {
151	arr		varray;
152	len, cap	int;
153}
154
155func toValue(val interface{}) Value {
156	switch val := val.(type) {
157	case bool:
158		r := boolV(val);
159		return &r;
160	case uint8:
161		r := uint8V(val);
162		return &r;
163	case uint:
164		r := uintV(val);
165		return &r;
166	case int:
167		r := intV(val);
168		return &r;
169	case *bignum.Integer:
170		return &idealIntV{val}
171	case float:
172		r := floatV(val);
173		return &r;
174	case *bignum.Rational:
175		return &idealFloatV{val}
176	case string:
177		r := stringV(val);
178		return &r;
179	case vstruct:
180		elems := make([]Value, len(val));
181		for i, e := range val {
182			elems[i] = toValue(e)
183		}
184		r := structV(elems);
185		return &r;
186	case varray:
187		elems := make([]Value, len(val));
188		for i, e := range val {
189			elems[i] = toValue(e)
190		}
191		r := arrayV(elems);
192		return &r;
193	case vslice:
194		return &sliceV{Slice{toValue(val.arr).(ArrayValue), int64(val.len), int64(val.cap)}}
195	case Func:
196		return &funcV{val}
197	}
198	log.Crashf("toValue(%T) not implemented", val);
199	panic();
200}
201
202/*
203 * Default test scope
204 */
205
206type testFunc struct{}
207
208func (*testFunc) NewFrame() *Frame	{ return &Frame{nil, &[2]Value{}} }
209
210func (*testFunc) Call(t *Thread) {
211	n := t.f.Vars[0].(IntValue).Get(t);
212
213	res := n + 1;
214
215	t.f.Vars[1].(IntValue).Set(t, res);
216}
217
218type oneTwoFunc struct{}
219
220func (*oneTwoFunc) NewFrame() *Frame	{ return &Frame{nil, &[2]Value{}} }
221
222func (*oneTwoFunc) Call(t *Thread) {
223	t.f.Vars[0].(IntValue).Set(t, 1);
224	t.f.Vars[1].(IntValue).Set(t, 2);
225}
226
227type voidFunc struct{}
228
229func (*voidFunc) NewFrame() *Frame	{ return &Frame{nil, []Value{}} }
230
231func (*voidFunc) Call(t *Thread)	{}
232
233func newTestWorld() *World {
234	w := NewWorld();
235
236	def := func(name string, t Type, val interface{}) { w.DefineVar(name, t, toValue(val)) };
237
238	w.DefineConst("c", IdealIntType, toValue(bignum.Int(1)));
239	def("i", IntType, 1);
240	def("i2", IntType, 2);
241	def("u", UintType, uint(1));
242	def("f", FloatType, 1.0);
243	def("s", StringType, "abc");
244	def("t", NewStructType([]StructField{StructField{"a", IntType, false}}), vstruct{1});
245	def("ai", NewArrayType(2, IntType), varray{1, 2});
246	def("aai", NewArrayType(2, NewArrayType(2, IntType)), varray{varray{1, 2}, varray{3, 4}});
247	def("aai2", NewArrayType(2, NewArrayType(2, IntType)), varray{varray{5, 6}, varray{7, 8}});
248	def("fn", NewFuncType([]Type{IntType}, false, []Type{IntType}), &testFunc{});
249	def("oneTwo", NewFuncType([]Type{}, false, []Type{IntType, IntType}), &oneTwoFunc{});
250	def("void", NewFuncType([]Type{}, false, []Type{}), &voidFunc{});
251	def("sli", NewSliceType(IntType), vslice{varray{1, 2, 3}, 2, 3});
252
253	return w;
254}