1package otto
2
3import (
4	"errors"
5	"strings"
6	"testing"
7	"time"
8
9	"github.com/robertkrimen/otto/terst"
10)
11
12func tt(t *testing.T, arguments ...func()) {
13	halt := errors.New("A test was taking too long")
14	timer := time.AfterFunc(2*time.Second, func() {
15		panic(halt)
16	})
17	defer func() {
18		timer.Stop()
19	}()
20	terst.Terst(t, arguments...)
21}
22
23func is(arguments ...interface{}) bool {
24	var got, expect interface{}
25
26	switch len(arguments) {
27	case 0, 1:
28		return terst.Is(arguments...)
29	case 2:
30		got, expect = arguments[0], arguments[1]
31	default:
32		got, expect = arguments[0], arguments[2]
33	}
34
35	switch value := got.(type) {
36	case Value:
37		if value.value != nil {
38			got = value.value
39		}
40	case *Error:
41		if value != nil {
42			got = value.Error()
43		}
44		if expect == nil {
45			// FIXME This is weird
46			expect = ""
47		}
48	}
49
50	if len(arguments) == 2 {
51		arguments[0] = got
52		arguments[1] = expect
53	} else {
54		arguments[0] = got
55		arguments[2] = expect
56	}
57
58	return terst.Is(arguments...)
59}
60
61func test(arguments ...interface{}) (func(string, ...interface{}) Value, *_tester) {
62	tester := newTester()
63	if len(arguments) > 0 {
64		tester.test(arguments[0].(string))
65	}
66	return tester.test, tester
67}
68
69type _tester struct {
70	vm *Otto
71}
72
73func newTester() *_tester {
74	return &_tester{
75		vm: New(),
76	}
77}
78
79func (self *_tester) Get(name string) (Value, error) {
80	return self.vm.Get(name)
81}
82
83func (self *_tester) Set(name string, value interface{}) Value {
84	err := self.vm.Set(name, value)
85	is(err, nil)
86	if err != nil {
87		terst.Caller().T().FailNow()
88	}
89	return self.vm.getValue(name)
90}
91
92func (self *_tester) Run(src interface{}) (Value, error) {
93	return self.vm.Run(src)
94}
95
96func (self *_tester) test(name string, expect ...interface{}) Value {
97	vm := self.vm
98	raise := false
99	defer func() {
100		if caught := recover(); caught != nil {
101			if exception, ok := caught.(*_exception); ok {
102				caught = exception.eject()
103			}
104			if raise {
105				if len(expect) > 0 {
106					is(caught, expect[0])
107				}
108			} else {
109				dbg("Panic, caught:", caught)
110				panic(caught)
111			}
112		}
113	}()
114	var value Value
115	var err error
116	if isIdentifier(name) {
117		value = vm.getValue(name)
118	} else {
119		source := name
120		index := strings.Index(source, "raise:")
121		if index == 0 {
122			raise = true
123			source = source[6:]
124			source = strings.TrimLeft(source, " ")
125		}
126		value, err = vm.runtime.cmpl_run(source, nil)
127		if err != nil {
128			panic(err)
129		}
130	}
131	value = value.resolve()
132	if len(expect) > 0 {
133		is(value, expect[0])
134	}
135	return value
136}
137