Commit | Line | Data |
---|---|---|
6a1aa64f DV |
1 | if (typeof(dojo) != 'undefined') { dojo.require('MochiKit.Base'); } |
2 | if (typeof(JSAN) != 'undefined') { JSAN.use('MochiKit.Base'); } | |
3 | if (typeof(tests) == 'undefined') { tests = {}; } | |
4 | ||
5 | tests.test_Base = function (t) { | |
6 | // test bind | |
7 | var not_self = {"toString": function () { return "not self"; } }; | |
8 | var self = {"toString": function () { return "self"; } }; | |
9 | var func = function (arg) { return this.toString() + " " + arg; }; | |
10 | var boundFunc = bind(func, self); | |
11 | not_self.boundFunc = boundFunc; | |
12 | ||
13 | t.is( isEmpty([], [], ""), true, "isEmpty true" ) | |
14 | t.is( isEmpty([], [1], ""), true, "isEmpty true" ) | |
15 | t.is( isNotEmpty([], [], ""), false, "isNotEmpty false" ) | |
16 | t.is( isNotEmpty([], [1], ""), false, "isNotEmpty false" ) | |
17 | ||
18 | t.is( isEmpty([1], [1], "1"), false, "isEmpty false" ) | |
19 | t.is( isEmpty([1], [1], "1"), false, "isEmpty false" ) | |
20 | t.is( isNotEmpty([1], [1], "1"), true, "isNotEmpty true" ) | |
21 | t.is( isNotEmpty([1], [1], "1"), true, "isNotEmpty true" ) | |
22 | ||
23 | t.is( boundFunc("foo"), "self foo", "boundFunc bound to self properly" ); | |
24 | t.is( not_self.boundFunc("foo"), "self foo", "boundFunc bound to self on another obj" ); | |
25 | t.is( bind(boundFunc, not_self)("foo"), "not self foo", "boundFunc successfully rebound!" ); | |
26 | t.is( bind(boundFunc, undefined, "foo")(), "self foo", "boundFunc partial no self change" ); | |
27 | t.is( bind(boundFunc, not_self, "foo")(), "not self foo", "boundFunc partial self change" ); | |
28 | ||
29 | // test method | |
30 | not_self = {"toString": function () { return "not self"; } }; | |
31 | self = {"toString": function () { return "self"; } }; | |
32 | func = function (arg) { return this.toString() + " " + arg; }; | |
33 | var boundMethod = method(self, func); | |
34 | not_self.boundMethod = boundMethod; | |
35 | ||
36 | t.is( boundMethod("foo"), "self foo", "boundMethod bound to self properly" ); | |
37 | t.is( not_self.boundMethod("foo"), "self foo", "boundMethod bound to self on another obj" ); | |
38 | t.is( method(not_self, boundMethod)("foo"), "not self foo", "boundMethod successfully rebound!" ); | |
39 | t.is( method(undefined, boundMethod, "foo")(), "self foo", "boundMethod partial no self change" ); | |
40 | t.is( method(not_self, boundMethod, "foo")(), "not self foo", "boundMethod partial self change" ); | |
41 | ||
42 | ||
43 | ||
44 | ||
45 | // test bindMethods | |
46 | ||
47 | var O = function (value) { | |
48 | bindMethods(this); | |
49 | this.value = value; | |
50 | }; | |
51 | O.prototype.func = function () { | |
52 | return this.value; | |
53 | }; | |
54 | ||
55 | var o = new O("boring"); | |
56 | var p = {}; | |
57 | p.func = o.func; | |
58 | var func = o.func; | |
59 | t.is( o.func(), "boring", "bindMethods doesn't break shit" ); | |
60 | t.is( p.func(), "boring", "bindMethods works on other objects" ); | |
61 | t.is( func(), "boring", "bindMethods works on functions" ); | |
62 | ||
63 | var p = clone(o); | |
64 | t.ok( p instanceof O, "cloned correct inheritance" ); | |
65 | var q = clone(p); | |
66 | t.ok( q instanceof O, "clone-cloned correct inheritance" ); | |
67 | q.foo = "bar"; | |
68 | t.is( p.foo, undefined, "clone-clone is copy-on-write" ); | |
69 | p.bar = "foo"; | |
70 | t.is( o.bar, undefined, "clone is copy-on-write" ); | |
71 | t.is( q.bar, "foo", "clone-clone has proper delegation" ); | |
72 | // unbind | |
73 | p.func = bind(p.func, null); | |
74 | t.is( p.func(), "boring", "clone function calls correct" ); | |
75 | q.value = "awesome"; | |
76 | t.is( q.func(), "awesome", "clone really does work" ); | |
77 | ||
78 | // test boring boolean funcs | |
79 | ||
80 | t.is( isCallable(isCallable), true, "isCallable returns true on itself" ); | |
81 | t.is( isCallable(1), false, "isCallable returns false on numbers" ); | |
82 | ||
83 | t.is( isUndefined(null), false, "null is not undefined" ); | |
84 | t.is( isUndefined(""), false, "empty string is not undefined" ); | |
85 | t.is( isUndefined(undefined), true, "undefined is undefined" ); | |
86 | t.is( isUndefined({}.foo), true, "missing property is undefined" ); | |
87 | ||
88 | t.is( isUndefinedOrNull(null), true, "null is undefined or null" ); | |
89 | t.is( isUndefinedOrNull(""), false, "empty string is not undefined or null" ); | |
90 | t.is( isUndefinedOrNull(undefined), true, "undefined is undefined or null" ); | |
91 | t.is( isUndefinedOrNull({}.foo), true, "missing property is undefined or null" ); | |
92 | ||
93 | // test extension of arrays | |
94 | var a = []; | |
95 | var b = []; | |
96 | var three = [1, 2, 3]; | |
97 | ||
98 | extend(a, three, 1); | |
99 | t.ok( objEqual(a, [2, 3]), "extend to an empty array" ); | |
100 | extend(a, three, 1) | |
101 | t.ok( objEqual(a, [2, 3, 2, 3]), "extend to a non-empty array" ); | |
102 | ||
103 | extend(b, three); | |
104 | t.ok( objEqual(b, three), "extend of an empty array" ); | |
105 | ||
106 | t.is( compare(1, 2), -1, "numbers compare lt" ); | |
107 | t.is( compare(2, 1), 1, "numbers compare gt" ); | |
108 | t.is( compare(1, 1), 0, "numbers compare eq" ); | |
109 | t.is( compare([1], [1]), 0, "arrays compare eq" ); | |
110 | t.is( compare([1], [1, 2]), -1, "arrays compare lt (length)" ); | |
111 | t.is( compare([1, 2], [2, 1]), -1, "arrays compare lt (contents)" ); | |
112 | t.is( compare([1, 2], [1]), 1, "arrays compare gt (length)" ); | |
113 | t.is( compare([2, 1], [1, 1]), 1, "arrays compare gt (contents)" ); | |
114 | ||
115 | // test partial application | |
116 | var a = []; | |
117 | var func = function (a, b) { | |
118 | if (arguments.length != 2) { | |
119 | return "bad args"; | |
120 | } else { | |
121 | return this.value + a + b; | |
122 | } | |
123 | }; | |
124 | var self = {"value": 1, "func": func}; | |
125 | var self2 = {"value": 2}; | |
126 | t.is( self.func(2, 3), 6, "setup for test is correct" ); | |
127 | self.funcTwo = partial(self.func, 2); | |
128 | t.is( self.funcTwo(3), 6, "partial application works" ); | |
129 | t.is( self.funcTwo(3), 6, "partial application works still" ); | |
130 | t.is( bind(self.funcTwo, self2)(3), 7, "rebinding partial works" ); | |
131 | self.funcTwo = bind(bind(self.funcTwo, self2), null); | |
132 | t.is( self.funcTwo(3), 6, "re-unbinding partial application works" ); | |
133 | ||
134 | ||
135 | // nodeWalk test | |
136 | // ... looks a lot like a DOM tree on purpose | |
137 | var tree = { | |
138 | "id": "nodeWalkTestTree", | |
139 | "test:int": "1", | |
140 | "childNodes": [ | |
141 | { | |
142 | "test:int": "2", | |
143 | "childNodes": [ | |
144 | {"test:int": "5"}, | |
145 | "ignored string", | |
146 | {"ignored": "object"}, | |
147 | ["ignored", "list"], | |
148 | { | |
149 | "test:skipchildren": "1", | |
150 | "childNodes": [{"test:int": 6}] | |
151 | } | |
152 | ] | |
153 | }, | |
154 | {"test:int": "3"}, | |
155 | {"test:int": "4"} | |
156 | ] | |
157 | } | |
158 | ||
159 | var visitedNodes = []; | |
160 | nodeWalk(tree, function (node) { | |
161 | var attr = node["test:int"]; | |
162 | if (attr) { | |
163 | visitedNodes.push(attr); | |
164 | } | |
165 | if (node["test:skipchildren"]) { | |
166 | return; | |
167 | } | |
168 | return node.childNodes; | |
169 | }); | |
170 | ||
171 | t.ok( objEqual(visitedNodes, ["1", "2", "3", "4", "5"]), "nodeWalk looks like it works"); | |
172 | ||
173 | // test map | |
174 | var minusOne = function (x) { return x - 1; }; | |
175 | var res = map(minusOne, [1, 2, 3]); | |
176 | t.ok( objEqual(res, [0, 1, 2]), "map works" ); | |
177 | ||
178 | var res2 = xmap(minusOne, 1, 2, 3); | |
179 | t.ok( objEqual(res2, res), "xmap works" ); | |
180 | ||
181 | res = map(operator.add, [1, 2, 3], [2, 4, 6]); | |
182 | t.ok( objEqual(res, [3, 6, 9]), "map(fn, p, q) works" ); | |
183 | ||
184 | res = map(operator.add, [1, 2, 3], [2, 4, 6, 8]); | |
185 | t.ok( objEqual(res, [3, 6, 9]), "map(fn, p, q) works (q long)" ); | |
186 | ||
187 | res = map(operator.add, [1, 2, 3, 4], [2, 4, 6]); | |
188 | t.ok( objEqual(res, [3, 6, 9]), "map(fn, p, q) works (p long)" ); | |
189 | ||
190 | res = map(null, [1, 2, 3], [2, 4, 6]); | |
191 | t.ok( objEqual(res, [[1, 2], [2, 4], [3, 6]]), "map(null, p, q) works" ); | |
192 | ||
193 | res = zip([1, 2, 3], [2, 4, 6]); | |
194 | t.ok( objEqual(res, [[1, 2], [2, 4], [3, 6]]), "zip(p, q) works" ); | |
195 | ||
196 | res = map(null, [1, 2, 3]); | |
197 | t.ok( objEqual(res, [1, 2, 3]), "map(null, lst) works" ); | |
198 | ||
199 | ||
200 | ||
201 | ||
202 | t.is( isNotEmpty("foo"), true, "3 char string is not empty" ); | |
203 | t.is( isNotEmpty(""), false, "0 char string is empty" ); | |
204 | t.is( isNotEmpty([1, 2, 3]), true, "3 element list is not empty" ); | |
205 | t.is( isNotEmpty([]), false, "0 element list is empty" ); | |
206 | ||
207 | // test filter | |
208 | var greaterThanThis = function (x) { return x > this; }; | |
209 | var greaterThanOne = function (x) { return x > 1; }; | |
210 | var res = filter(greaterThanOne, [-1, 0, 1, 2, 3]); | |
211 | t.ok( objEqual(res, [2, 3]), "filter works" ); | |
212 | var res = filter(greaterThanThis, [-1, 0, 1, 2, 3], 1); | |
213 | t.ok( objEqual(res, [2, 3]), "filter self works" ); | |
214 | var res2 = xfilter(greaterThanOne, -1, 0, 1, 2, 3); | |
215 | t.ok( objEqual(res2, res), "xfilter works" ); | |
216 | ||
217 | t.is(objMax(1, 2, 9, 12, 42, -16, 16), 42, "objMax works (with numbers)"); | |
218 | t.is(objMin(1, 2, 9, 12, 42, -16, 16), -16, "objMin works (with numbers)"); | |
219 | ||
220 | // test adapter registry | |
221 | ||
222 | var R = new AdapterRegistry(); | |
223 | R.register("callable", isCallable, function () { return "callable"; }); | |
224 | R.register("arrayLike", isArrayLike, function () { return "arrayLike"; }); | |
225 | t.is( R.match(function () {}), "callable", "registry found callable" ); | |
226 | t.is( R.match([]), "arrayLike", "registry found ArrayLike" ); | |
227 | try { | |
228 | R.match(null); | |
229 | t.ok( false, "non-matching didn't raise!" ); | |
230 | } catch (e) { | |
231 | t.is( e, NotFound, "non-matching raised correctly" ); | |
232 | } | |
233 | R.register("undefinedOrNull", isUndefinedOrNull, function () { return "undefinedOrNull" }); | |
234 | R.register("undefined", isUndefined, function () { return "undefined" }); | |
235 | t.is( R.match(undefined), "undefinedOrNull", "priorities are as documented" ); | |
236 | t.ok( R.unregister("undefinedOrNull"), "removed adapter" ); | |
237 | t.is( R.match(undefined), "undefined", "adapter was removed" ); | |
238 | R.register("undefinedOrNull", isUndefinedOrNull, function () { return "undefinedOrNull" }, true); | |
239 | t.is( R.match(undefined), "undefinedOrNull", "override works" ); | |
240 | ||
241 | var a1 = {"a": 1, "b": 2, "c": 2}; | |
242 | var a2 = {"a": 2, "b": 1, "c": 2}; | |
243 | t.is( keyComparator("a")(a1, a2), -1, "keyComparator 1 lt" ); | |
244 | t.is( keyComparator("c")(a1, a2), 0, "keyComparator 1 eq" ); | |
245 | t.is( keyComparator("c", "b")(a1, a2), 1, "keyComparator 2 eq gt" ); | |
246 | t.is( keyComparator("c", "a")(a1, a2), -1, "keyComparator 2 eq lt" ); | |
247 | t.is( reverseKeyComparator("a")(a1, a2), 1, "reverseKeyComparator" ); | |
248 | t.is( compare(concat([1], [2], [3]), [1, 2, 3]), 0, "concat" ); | |
249 | t.is( repr("foo"), '"foo"', "string repr" ); | |
250 | t.is( repr(1), '1', "number repr" ); | |
251 | t.is( listMin([1, 3, 5, 3, -1]), -1, "listMin" ); | |
252 | t.is( objMin(1, 3, 5, 3, -1), -1, "objMin" ); | |
253 | t.is( listMax([1, 3, 5, 3, -1]), 5, "listMax" ); | |
254 | t.is( objMax(1, 3, 5, 3, -1), 5, "objMax" ); | |
255 | ||
256 | var v = keys(a1); | |
257 | v.sort(); | |
258 | t.is( compare(v, ["a", "b", "c"]), 0, "keys" ); | |
259 | v = items(a1); | |
260 | v.sort(); | |
261 | t.is( compare(v, [["a", 1], ["b", 2], ["c", 2]]), 0, "items" ); | |
262 | ||
263 | var StringMap = function() {}; | |
264 | a = new StringMap(); | |
265 | a.foo = "bar"; | |
266 | b = new StringMap(); | |
267 | b.foo = "bar"; | |
268 | try { | |
269 | compare(a, b); | |
270 | t.ok( false, "bad comparison registered!?" ); | |
271 | } catch (e) { | |
272 | t.ok( e instanceof TypeError, "bad comparison raised TypeError" ); | |
273 | } | |
274 | ||
275 | t.is( repr(a), "[object Object]", "default repr for StringMap" ); | |
276 | var isStringMap = function () { | |
277 | for (var i = 0; i < arguments.length; i++) { | |
278 | if (!(arguments[i] instanceof StringMap)) { | |
279 | return false; | |
280 | } | |
281 | } | |
282 | return true; | |
283 | }; | |
284 | ||
285 | registerRepr("stringMap", | |
286 | isStringMap, | |
287 | function (obj) { | |
288 | return "StringMap(" + repr(items(obj)) + ")"; | |
289 | } | |
290 | ); | |
291 | ||
292 | t.is( repr(a), 'StringMap([["foo", "bar"]])', "repr worked" ); | |
293 | ||
294 | // not public API | |
295 | MochiKit.Base.reprRegistry.unregister("stringMap"); | |
296 | ||
297 | t.is( repr(a), "[object Object]", "default repr for StringMap" ); | |
298 | ||
299 | registerComparator("stringMap", | |
300 | isStringMap, | |
301 | function (a, b) { | |
302 | // no sorted(...) in base | |
303 | a = items(a); | |
304 | b = items(b); | |
305 | a.sort(compare); | |
306 | b.sort(compare); | |
307 | return compare(a, b); | |
308 | } | |
309 | ); | |
310 | ||
311 | t.is( compare(a, b), 0, "registerComparator" ); | |
312 | ||
313 | update(a, {"foo": "bar"}, {"wibble": "baz"}, undefined, null, {"grr": 1}); | |
314 | t.is( a.foo, "bar", "update worked (first obj)" ); | |
315 | t.is( a.wibble, "baz", "update worked (second obj)" ); | |
316 | t.is( a.grr, 1, "update worked (skipped undefined and null)" ); | |
317 | t.is( compare(a, b), 1, "update worked (comparison)" ); | |
318 | ||
319 | ||
320 | setdefault(a, {"foo": "unf"}, {"bar": "web taco"} ); | |
321 | t.is( a.foo, "bar", "setdefault worked (skipped existing)" ); | |
322 | t.is( a.bar, "web taco", "setdefault worked (set non-existing)" ); | |
323 | ||
324 | var c = items(merge({"foo": "bar"}, {"wibble": "baz"})); | |
325 | c.sort(compare); | |
326 | t.is( compare(c, [["foo", "bar"], ["wibble", "baz"]]), 0, "merge worked" ); | |
327 | ||
328 | // not public API | |
329 | MochiKit.Base.comparatorRegistry.unregister("stringMap"); | |
330 | ||
331 | try { | |
332 | compare(a, b); | |
333 | t.ok( false, "bad comparison registered!?" ); | |
334 | } catch (e) { | |
335 | t.ok( e instanceof TypeError, "bad comparison raised TypeError" ); | |
336 | } | |
337 | ||
338 | var o = {"__repr__": function () { return "__repr__"; }}; | |
339 | t.is( repr(o), "__repr__", "__repr__ protocol" ); | |
340 | t.is( repr(MochiKit.Base), MochiKit.Base.__repr__(), "__repr__ protocol when repr is defined" ); | |
341 | var o = {"NAME": "NAME"}; | |
342 | t.is( repr(o), "NAME", "NAME protocol (obj)" ); | |
343 | o = function () { return "TACO" }; | |
344 | o.NAME = "NAME"; | |
345 | t.is( repr(o), "NAME", "NAME protocol (func)" ); | |
346 | ||
347 | t.is( repr(MochiKit.Base.nameFunctions), "MochiKit.Base.nameFunctions", "test nameFunctions" ); | |
348 | // Done! | |
349 | ||
350 | t.is( urlEncode("1+2=2").toUpperCase(), "1%2B2%3D2", "urlEncode" ); | |
351 | t.is( queryString(["a", "b"], [1, "two"]), "a=1&b=two", "queryString"); | |
352 | t.is( queryString({"a": 1}), "a=1", "one item alternate form queryString" ); | |
353 | var o = {"a": 1, "b": 2, "c": function() {}}; | |
354 | var res = queryString(o).split("&"); | |
355 | res.sort(); | |
356 | t.is( res.join("&"), "a=1&b=2", "two item alternate form queryString, function skip" ); | |
357 | var res = parseQueryString("1+1=2&b=3%3D2"); | |
358 | t.is( res["1 1"], "2", "parseQueryString pathological name" ); | |
359 | t.is( res.b, "3=2", "parseQueryString second name:value pair" ); | |
360 | var res = parseQueryString("foo=one&foo=two", true); | |
361 | t.is( res["foo"].join(" "), "one two", "parseQueryString useArrays" ); | |
362 | var res = parseQueryString("?foo=2&bar=1"); | |
363 | t.is( res["foo"], "2", "parseQueryString strip leading question mark"); | |
364 | ||
365 | t.is( serializeJSON("foo\n\r\b\f\t"), "\"foo\\n\\r\\b\\f\\t\"", "string JSON" ); | |
366 | t.is( serializeJSON(null), "null", "null JSON"); | |
367 | try { | |
368 | serializeJSON(undefined); | |
369 | t.ok(false, "undefined should not be serializable"); | |
370 | } catch (e) { | |
371 | t.ok(e instanceof TypeError, "undefined not serializable"); | |
372 | } | |
373 | t.is( serializeJSON(1), "1", "1 JSON"); | |
374 | t.is( serializeJSON(1.23), "1.23", "1.23 JSON"); | |
375 | t.is( serializeJSON(serializeJSON), null, "function JSON (null, not string)" ); | |
376 | t.is( serializeJSON([1, "2", 3.3]), "[1, \"2\", 3.3]", "array JSON" ); | |
377 | var res = evalJSON(serializeJSON({"a":1, "b":2})); | |
378 | t.is( res.a, 1, "evalJSON on an object (1)" ); | |
379 | t.is( res.b, 2, "evalJSON on an object (2)" ); | |
380 | var res = {"a": 1, "b": 2, "json": function () { return this; }}; | |
381 | var res = evalJSON(serializeJSON(res)); | |
382 | t.is( res.a, 1, "evalJSON on an object that jsons self (1)" ); | |
383 | t.is( res.b, 2, "evalJSON on an object that jsons self (2)" ); | |
384 | var strJSON = {"a": 1, "b": 2, "json": function () { return "json"; }}; | |
385 | t.is( serializeJSON(strJSON), "\"json\"", "json serialization calling" ); | |
386 | t.is( serializeJSON([strJSON]), "[\"json\"]", "json serialization calling in a structure" ); | |
387 | registerJSON("isDateLike", | |
388 | isDateLike, | |
389 | function (d) { | |
390 | return "this was a date"; | |
391 | } | |
392 | ); | |
393 | t.is( serializeJSON(new Date()), "\"this was a date\"", "json registry" ); | |
394 | MochiKit.Base.jsonRegistry.unregister("isDateLike"); | |
395 | ||
396 | var a = {"foo": {"bar": 12, "wibble": 13}}; | |
397 | var b = {"foo": {"baz": 4, "bar": 16}, "bar": 4}; | |
398 | updatetree(a, b); | |
399 | var expect = [["bar", 16], ["baz", 4], ["wibble", 13]]; | |
400 | var got = items(a.foo); | |
401 | got.sort(compare); | |
402 | t.is( repr(got), repr(expect), "updatetree merge" ); | |
403 | t.is( a.bar, 4, "updatetree insert" ); | |
404 | ||
405 | var c = counter(); | |
406 | t.is( c(), 1, "counter starts at 1" ); | |
407 | t.is( c(), 2, "counter increases" ); | |
408 | c = counter(2); | |
409 | t.is( c(), 2, "counter starts at 2" ); | |
410 | t.is( c(), 3, "counter increases" ); | |
411 | ||
412 | t.is( findValue([1, 2, 3], 4), -1, "findValue returns -1 on not found"); | |
413 | t.is( findValue([1, 2, 3], 1), 0, "findValue returns correct index"); | |
414 | t.is( findValue([1, 2, 3], 1, 1), -1, "findValue honors start"); | |
415 | t.is( findValue([1, 2, 3], 2, 0, 1), -1, "findValue honors end"); | |
416 | t.is( findIdentical([1, 2, 3], 4), -1, "findIdentical returns -1"); | |
417 | t.is( findIdentical([1, 2, 3], 1), 0, "findIdentical returns correct index"); | |
418 | t.is( findIdentical([1, 2, 3], 1, 1), -1, "findIdentical honors start"); | |
419 | t.is( findIdentical([1, 2, 3], 2, 0, 1), -1, "findIdentical honors end"); | |
420 | t.is( isNull(undefined), false, "isNull doesn't match undefined" ); | |
421 | ||
422 | var flat = flattenArguments(1, "2", 3, [4, [5, [6, 7], 8, [], 9]]); | |
423 | var expect = [1, "2", 3, 4, 5, 6, 7, 8, 9]; | |
424 | t.is( repr(flat), repr(expect), "flattenArguments" ); | |
425 | ||
426 | var fn = function () { | |
427 | return [this, concat(arguments)]; | |
428 | } | |
429 | t.is( methodcaller("toLowerCase")("FOO"), "foo", "methodcaller with a method name" ); | |
430 | t.is( repr(methodcaller(fn, 2, 3)(1)), "[1, [2, 3]]", "methodcaller with a function" ); | |
431 | ||
432 | var f1 = function (x) { return [1, x]; }; | |
433 | var f2 = function (x) { return [2, x]; }; | |
434 | var f3 = function (x) { return [3, x]; }; | |
435 | t.is( repr(f1(f2(f3(4)))), "[1, [2, [3, 4]]]", "test the compose test" ); | |
436 | t.is( repr(compose(f1,f2,f3)(4)), "[1, [2, [3, 4]]]", "three fn composition works" ); | |
437 | t.is( repr(compose(compose(f1,f2),f3)(4)), "[1, [2, [3, 4]]]", "associative left" ); | |
438 | t.is( repr(compose(f1,compose(f2,f3))(4)), "[1, [2, [3, 4]]]", "associative right" ); | |
439 | ||
440 | try { | |
441 | compose(f1, "foo"); | |
442 | t.ok( false, "wrong compose argument not raised!" ); | |
443 | } catch (e) { | |
444 | t.is( e.name, 'TypeError', "wrong compose argument raised correctly" ); | |
445 | } | |
446 | ||
447 | t.is(camelize('one'), 'one', 'one word'); | |
448 | t.is(camelize('one-two'), 'oneTwo', 'two words'); | |
449 | t.is(camelize('one-two-three'), 'oneTwoThree', 'three words'); | |
450 | t.is(camelize('1-one'), '1One', 'letter and word'); | |
451 | t.is(camelize('one-'), 'one', 'trailing hyphen'); | |
452 | t.is(camelize('-one'), 'One', 'starting hyphen'); | |
453 | t.is(camelize('o-two'), 'oTwo', 'one character and word'); | |
454 | ||
455 | var flat = flattenArray([1, "2", 3, [4, [5, [6, 7], 8, [], 9]]]); | |
456 | var expect = [1, "2", 3, 4, 5, 6, 7, 8, 9]; | |
457 | t.is( repr(flat), repr(expect), "flattenArray" ); | |
458 | ||
459 | /* mean */ | |
460 | try { | |
461 | mean(); | |
462 | t.ok( false, "no arguments didn't raise!" ); | |
463 | } catch (e) { | |
464 | t.is( e.name, 'TypeError', "no arguments raised correctly" ); | |
465 | } | |
466 | t.is( mean(1), 1, 'single argument (arg list)'); | |
467 | t.is( mean([1]), 1, 'single argument (array)'); | |
468 | t.is( mean(1,2,3), 2, 'three arguments (arg list)'); | |
469 | t.is( mean([1,2,3]), 2, 'three arguments (array)'); | |
470 | t.is( average(1), 1, 'test the average alias'); | |
471 | ||
472 | /* median */ | |
473 | try { | |
474 | median(); | |
475 | t.ok( false, "no arguments didn't raise!" ); | |
476 | } catch (e) { | |
477 | t.is( e.name, 'TypeError', "no arguments raised correctly" ); | |
478 | } | |
479 | t.is( median(1), 1, 'single argument (arg list)'); | |
480 | t.is( median([1]), 1, 'single argument (array)'); | |
481 | t.is( median(3,1,2), 2, 'three arguments (arg list)'); | |
482 | t.is( median([3,1,2]), 2, 'three arguments (array)'); | |
483 | t.is( median(3,1,2,4), 2.5, 'four arguments (arg list)'); | |
484 | t.is( median([3,1,2,4]), 2.5, 'four arguments (array)'); | |
485 | ||
486 | /* #185 */ | |
487 | t.is( serializeJSON(parseQueryString("")), "{}", "parseQueryString('')" ); | |
488 | t.is( serializeJSON(parseQueryString("", true)), "{}", "parseQueryString('', true)" ); | |
489 | ||
490 | /* #109 */ | |
491 | t.is( queryString({ids: [1,2,3]}), "ids=1&ids=2&ids=3", "queryString array value" ); | |
492 | t.is( queryString({ids: "123"}), "ids=123", "queryString string value" ); | |
493 | ||
494 | /* test values */ | |
495 | var o = {a: 1, b: 2, c: 4, d: -1}; | |
496 | var got = values(o); | |
497 | got.sort(); | |
498 | t.is( repr(got), repr([-1, 1, 2, 4]), "values()" ); | |
499 | ||
500 | t.is( queryString([["foo", "bar"], ["baz", "wibble"]]), "foo=baz&bar=wibble" ); | |
501 | o = parseQueryString("foo=1=1=1&bar=2&baz&wibble="); | |
502 | t.is( o.foo, "1=1=1", "parseQueryString multiple = first" ); | |
503 | t.is( o.bar, "2", "parseQueryString multiple = second" ); | |
504 | t.is( o.baz, "", "parseQueryString multiple = third" ); | |
505 | t.is( o.wibble, "", "parseQueryString multiple = fourth" ); | |
506 | ||
507 | }; |