1// +build js
2
3package jsbuiltin
4
5import (
6	"testing"
7
8	"github.com/gopherjs/gopherjs/js"
9)
10
11func TestEncodeURI(t *testing.T) {
12	data := map[string]string{
13		"http://foo.com/?msg=Привет мир.": "http://foo.com/?msg=%D0%9F%D1%80%D0%B8%D0%B2%D0%B5%D1%82%20%D0%BC%D0%B8%D1%80.",
14		"http://user:host@foo.com/":       "http://user:host@foo.com/",
15	}
16	for url, expected := range data {
17		result := EncodeURI(url)
18		if result != expected {
19			t.Fatalf("EncodeURI(%s) returned '%s', not '%s'", url, result, expected)
20		}
21	}
22}
23
24type testData struct {
25	URL           string
26	ExpectedURL   string
27	ExpectedError string
28}
29
30func TestDecodeURI(t *testing.T) {
31	data := []testData{
32		testData{
33			"http://foo.com/?msg=%D0%9F%D1%80%D0%B8%D0%B2%D0%B5%D1%82%20%D0%BC%D0%B8%D1%80.", "http://foo.com/?msg=Привет мир.", "",
34		},
35		testData{
36			"http://user:host@foo.com/", "http://user:host@foo.com/", "",
37		},
38		testData{
39			"http://foo.com/?invalidutf8=%80", "", "JavaScript error: URI malformed",
40		},
41	}
42	for _, test := range data {
43		result, err := DecodeURI(test.URL)
44		if test.ExpectedError != "" {
45			if err == nil {
46				t.Fatalf("DecodeURI(%s) should have resulted in an error", test.URL)
47			}
48			if err.Error() != test.ExpectedError {
49				t.Fatalf("DecodeURI(%s) should have resulted in error '%s', got '%s'", test.URL, test.ExpectedError, err)
50			}
51		} else {
52			if err != nil {
53				t.Fatalf("DecodeURI() resulted in an error: %s", err)
54			}
55			if result != test.ExpectedURL {
56				t.Fatalf("DecodeURI(%s) returned '%s', not '%s'", test.URL, result, test.ExpectedURL)
57			}
58		}
59	}
60}
61
62func TestEncodeURIComponentn(t *testing.T) {
63	data := map[string]string{
64		"Привет мир.": "%D0%9F%D1%80%D0%B8%D0%B2%D0%B5%D1%82%20%D0%BC%D0%B8%D1%80.",
65		"bar": "bar",
66	}
67	for url, expected := range data {
68		result := EncodeURIComponent(url)
69		if result != expected {
70			t.Fatalf("EncodeURIComponent(%s) returned '%s', not '%s'", url, result, expected)
71		}
72	}
73}
74
75func TestDecodeURIComponentn(t *testing.T) {
76	data := []testData{
77		testData{
78			"%D0%9F%D1%80%D0%B8%D0%B2%D0%B5%D1%82%20%D0%BC%D0%B8%D1%80.", "Привет мир.", "",
79		},
80		testData{
81			"bar", "bar", "",
82		},
83		testData{
84			"%80", "", "JavaScript error: URI malformed",
85		},
86	}
87	for _, test := range data {
88		result, err := DecodeURIComponent(test.URL)
89		if test.ExpectedError != "" {
90			if err == nil {
91				t.Fatalf("DecodeURIComponent(%s) should have resulted in an error", test.URL)
92			}
93			if err.Error() != test.ExpectedError {
94				t.Fatalf("DecodeURIComponent(%s) should have resulted in error '%s', got '%s'", test.URL, test.ExpectedError, err)
95			}
96		} else {
97			if err != nil {
98				t.Fatalf("DecodeURIComponent() resulted in an error: %s", err)
99			}
100			if result != test.ExpectedURL {
101				t.Fatalf("DecodeURIComponent(%s) returned '%s', not '%s'", test.URL, result, test.ExpectedURL)
102			}
103		}
104	}
105}
106
107func TestIsFinite(t *testing.T) {
108	data := map[interface{}]bool{
109		123:          true,
110		-1.23:        true,
111		5 - 2:        true,
112		0:            true,
113		"123":        true,
114		"Hello":      false,
115		"2005/12/12": false,
116	}
117	for value, expected := range data {
118		result := IsFinite(value)
119		if result != expected {
120			t.Fatalf("IsFinite(%s) returned %t, not %t", value, result, expected)
121		}
122	}
123}
124
125func TestIsNaN(t *testing.T) {
126	data := map[interface{}]bool{
127		123:          false,
128		-1.23:        false,
129		5 - 2:        false,
130		0:            false,
131		"123":        false,
132		"Hello":      true,
133		"2005/12/12": true,
134	}
135	for value, expected := range data {
136		result := IsNaN(value)
137		if result != expected {
138			t.Fatalf("IsNaN(%s) returned %t, not %t", value, result, expected)
139		}
140	}
141}
142
143type toTest struct {
144	value  interface{}
145	result string
146}
147
148func TestTypeOf(t *testing.T) {
149	data := []toTest{
150		// Standard JS types
151		toTest{js.Undefined, "undefined"},
152		toTest{nil, "object"},
153		toTest{true, "boolean"},
154		toTest{false, "boolean"},
155		toTest{12345, "number"},
156		toTest{"one two three", "string"},
157		toTest{js.Global.Call, "function"},
158		toTest{js.Global, "object"},
159	}
160	// Check whether the JS interpretor supports the 'symbol' type (Node >= 0.12)
161	if TypeOf(js.Global.Get("Symbol")) == "function" {
162		symbol := js.Global.Call("Symbol", "foo")
163		data = append(data, toTest{&symbol, "symbol"})
164	}
165	for _, test := range data {
166		result := TypeOf(test.value)
167		if result != test.result {
168			t.Fatalf("Typeof(%s) returned %s, not %s", test.value, result, test.result)
169		}
170	}
171
172	if to := TypeOf(map[string]string{}); to != "object" {
173		t.Fatalf("Obscure type not recognized as object")
174	}
175	if to := TypeOf(js.Object{}); to != "object" {
176		t.Fatal("Invalid/empty JS object not recognized as object")
177	}
178}
179
180type ioTest struct {
181	value  interface{}
182	object *js.Object
183	result bool
184}
185
186func TestInstanceOf(t *testing.T) {
187	data := []ioTest{
188		// Standard JS types
189		ioTest{js.Undefined, js.Global.Get("Object"), false},
190		ioTest{"a string", js.Global.Get("String"), false},
191		ioTest{js.Global.Get("String").New("foo"), js.Global.Get("String"), true},
192		ioTest{js.Global.Get("String").New("foo"), js.Global.Get("Object"), true},
193	}
194	for _, test := range data {
195		result := InstanceOf(test.value, test.object)
196		if result != test.result {
197			t.Errorf("InstanceOf(%s,%s) returned %t, not %t", test.value, test.object, result, test.result)
198		}
199	}
200}
201
202type inTest struct {
203	obj    *js.Object
204	key    string
205	result bool
206	err    string
207}
208
209func TestIn(t *testing.T) {
210	obj := js.Global.Get("Object").New()
211	obj.Set("foo", "bar")
212	jsString := js.Global.Call("eval", `'"test string"'`)
213	data := []inTest{
214		{obj: obj, key: "foo", result: true},
215		{obj: obj, key: "bar", result: false},
216		{obj: js.Undefined, key: "foo", err: "obj not a JavaScript function"},
217		{obj: nil, key: "foo", err: "obj not a JavaScript function"},
218		{obj: jsString, key: "foo", err: "obj not a JavaScript function"},
219	}
220	for _, test := range data {
221		result, err := In(test.key, test.obj)
222		var msg string
223		if err != nil {
224			msg = err.Error()
225		}
226		if msg != test.err {
227			t.Errorf("Unexpected error: %s", msg)
228		}
229		if result != test.result {
230			t.Errorf("In(%v, %s) returned %t, not %t", test.obj, test.key, result, test.result)
231		}
232	}
233}
234