UNPKG

8.88 kBJavaScriptView Raw
1if(module.parent === null) {
2 console.log('Run this test file with nodeunit:');
3 console.log('$ nodeunit test.js');
4}
5
6if (typeof(global) === 'object') global.TESTING = true;
7
8var clone = require('./');
9var _ = require('underscore');
10
11function inspect(obj) {
12 seen = [];
13 return JSON.stringify(obj, function(key, val) {
14 if (val != null && typeof val == "object") {
15 if (seen.indexOf(val) >= 0) return '[cyclic]'
16 seen.push(val)
17 }
18 return val
19 });
20}
21
22// Creates a new VM in node, or a iframe in a browser to run the script.
23function apartContext(context, script, callback) {
24 var vm = require('vm');
25 if (vm) {
26 var ctx = vm.createContext({ctx: context});
27 callback(vm.runInContext(script, ctx));
28 }
29 else if (document && document.createElement) {
30 var iframe = document.createElement('iframe');
31 iframe.style.display = 'none';
32 document.body.appendChild(iframe);
33 var myCtxId = 'tmpCtx' + Math.random();
34 window[myCtxId] = context;
35 iframe.src = 'test-apart-ctx.html?'+myCtxId+'&'+encodeURIComponent(script);
36 iframe.onload = function(){
37 try { callback(iframe.contentWindow.results) }
38 catch(e) {
39 alert('Apart Context iFrame data collection fail.\n'+e); throw e
40 }
41 };
42 } else {
43 console.log('WARNING: cant create an apart context (vm.createContext or iframe).');
44 }
45}
46
47exports["clone string"] = function(test) {
48 test.expect(2); // how many tests?
49
50 var a = "foo";
51 test.strictEqual(clone(a), a);
52 a = "";
53 test.strictEqual(clone(a), a);
54
55 test.done();
56};
57
58exports["clone number"] = function(test) {
59 test.expect(5); // how many tests?
60
61 var a = 0;
62 test.strictEqual(clone(a), a);
63 a = 1;
64 test.strictEqual(clone(a), a);
65 a = -1000;
66 test.strictEqual(clone(a), a);
67 a = 3.1415927;
68 test.strictEqual(clone(a), a);
69 a = -3.1415927;
70 test.strictEqual(clone(a), a);
71
72 test.done();
73};
74
75exports["clone date"] = function(test) {
76 test.expect(3); // how many tests?
77
78 var a = new Date;
79 var c = clone(a);
80 test.ok(!!a.getUTCDate && !!a.toUTCString);
81 test.ok(!!c.getUTCDate && !!c.toUTCString);
82 test.equal(a.getTime(), c.getTime());
83
84 test.done();
85};
86
87exports["clone object"] = function(test) {
88 test.expect(2); // how many tests?
89
90 var a = { foo: { bar: "baz" } };
91 var b = clone(a);
92
93 test.ok(_(a).isEqual(b), "underscore equal");
94 test.deepEqual(b, a);
95
96 test.done();
97};
98
99exports["clone array"] = function(test) {
100 test.expect(3); // how many tests?
101
102 var a = [
103 { foo: "bar" },
104 "baz"
105 ];
106 var b = clone(a);
107
108 test.ok(_(a).isEqual(b), "underscore equal");
109 test.ok(b instanceof Array);
110 test.deepEqual(b, a);
111
112 test.done();
113};
114
115exports["clone buffer"] = function(test) {
116 if (typeof Buffer == 'undefined') return test.done();
117
118 test.expect(1);
119
120 var a = new Buffer("this is a test buffer");
121 var b = clone(a);
122
123 // no underscore equal since it has no concept of Buffers
124 test.deepEqual(b, a);
125 test.done();
126};
127
128exports["clone regexp"] = function(test) {
129 test.expect(5);
130
131 var a = /abc123/gi;
132 var b = clone(a);
133
134 test.deepEqual(b, a);
135
136 var c = /a/g;
137 test.ok(c.lastIndex === 0);
138
139 c.exec('123a456a');
140 test.ok(c.lastIndex === 4);
141
142 var d = clone(c);
143 test.ok(d.global);
144 test.ok(d.lastIndex === 4);
145
146 test.done();
147};
148
149exports["clone object containing array"] = function(test) {
150 test.expect(2); // how many tests?
151
152 var a = {
153 arr1: [ { a: '1234', b: '2345' } ],
154 arr2: [ { c: '345', d: '456' } ]
155 };
156 var b = clone(a);
157
158 test.ok(_(a).isEqual(b), "underscore equal");
159 test.deepEqual(b, a);
160
161 test.done();
162};
163
164exports["clone object with circular reference"] = function(test) {
165 test.expect(8); // how many tests?
166
167 var c = [1, "foo", {'hello': 'bar'}, function() {}, false, [2]];
168 var b = [c, 2, 3, 4];
169 var a = {'b': b, 'c': c};
170 a.loop = a;
171 a.loop2 = a;
172 c.loop = c;
173 c.aloop = a;
174 var aCopy = clone(a);
175 test.ok(a != aCopy);
176 test.ok(a.c != aCopy.c);
177 test.ok(aCopy.c == aCopy.b[0]);
178 test.ok(aCopy.c.loop.loop.aloop == aCopy);
179 test.ok(aCopy.c[0] == a.c[0]);
180
181 //console.log(util.inspect(aCopy, true, null) );
182 //console.log("------------------------------------------------------------");
183 //console.log(util.inspect(a, true, null) );
184 test.ok(eq(a, aCopy));
185 aCopy.c[0] = 2;
186 test.ok(!eq(a, aCopy));
187 aCopy.c = "2";
188 test.ok(!eq(a, aCopy));
189 //console.log("------------------------------------------------------------");
190 //console.log(util.inspect(aCopy, true, null) );
191
192 function eq(x, y) {
193 return inspect(x) === inspect(y);
194 }
195
196 test.done();
197};
198
199exports['clone prototype'] = function(test) {
200 test.expect(3); // how many tests?
201
202 var a = {
203 a: "aaa",
204 x: 123,
205 y: 45.65
206 };
207 var b = clone.clonePrototype(a);
208
209 test.strictEqual(b.a, a.a);
210 test.strictEqual(b.x, a.x);
211 test.strictEqual(b.y, a.y);
212
213 test.done();
214};
215
216exports['clone within an apart context'] = function(test) {
217 var results = apartContext(
218 {clone: clone},
219 "results = ctx.clone({ a: [1, 2, 3], d: new Date(), r: /^foo$/ig })",
220 function(results) {
221 test.ok(results.a.constructor.toString() === Array.toString());
222 test.ok(results.d.constructor.toString() === Date.toString());
223 test.ok(results.r.constructor.toString() === RegExp.toString());
224 test.done();
225 }
226 );
227};
228
229exports['clone object with no constructor'] = function(test) {
230 test.expect(3);
231 var n = null;
232 var a = { foo: 'bar' };
233 a.__proto__ = n;
234 test.ok(typeof a === 'object');
235 test.ok(typeof a !== null);
236 var b = clone(a);
237 test.ok(a.foo, b.foo);
238 test.done();
239};
240
241exports['clone object with depth argument'] = function (test) {
242 test.expect(6);
243 var a = {
244 foo: {
245 bar : {
246 baz : 'qux'
247 }
248 }
249 };
250 var b = clone(a, false, 1);
251 test.deepEqual(b, a);
252 test.notEqual(b, a);
253 test.strictEqual(b.foo, a.foo);
254
255 b = clone(a, true, 2);
256 test.deepEqual(b, a);
257 test.notEqual(b.foo, a.foo);
258 test.strictEqual(b.foo.bar, a.foo.bar);
259 test.done();
260};
261
262exports['maintain prototype chain in clones'] = function (test) {
263 test.expect(1);
264 function Constructor() {}
265 var a = new Constructor();
266 var b = clone(a);
267 test.strictEqual(Object.getPrototypeOf(a), Object.getPrototypeOf(b));
268 test.done();
269};
270
271exports['parent prototype is overriden with prototype provided'] = function (test) {
272 test.expect(1);
273 function Constructor() {}
274 var a = new Constructor();
275 var b = clone(a, true, Infinity, null);
276 test.strictEqual(b.__defineSetter__, undefined);
277 test.done();
278};
279
280exports['clone object with null children'] = function(test) {
281 test.expect(1);
282 var a = {
283 foo: {
284 bar: null,
285 baz: {
286 qux: false
287 }
288 }
289 };
290 var b = clone(a);
291 test.deepEqual(b, a);
292 test.done();
293};
294
295exports['clone instance with getter'] = function(test) {
296 test.expect(1);
297 function Ctor() {};
298 Object.defineProperty(Ctor.prototype, 'prop', {
299 configurable: true,
300 enumerable: true,
301 get: function() {
302 return 'value';
303 }
304 });
305
306 var a = new Ctor();
307 var b = clone(a);
308
309 test.strictEqual(b.prop, 'value');
310 test.done();
311};
312
313exports['get RegExp flags'] = function(test) {
314 test.strictEqual(clone.getRegExpFlags(/a/), '' );
315 test.strictEqual(clone.getRegExpFlags(/a/i), 'i' );
316 test.strictEqual(clone.getRegExpFlags(/a/g), 'g' );
317 test.strictEqual(clone.getRegExpFlags(/a/gi), 'gi');
318 test.strictEqual(clone.getRegExpFlags(/a/m), 'm' );
319 test.done();
320};
321
322exports["recognize Array object"] = function(test) {
323 var results = apartContext(
324 null, "results = [1, 2, 3]",
325 function(alien) {
326 var local = [4, 5, 6];
327 test.ok(clone.isArray(alien)); // recognize in other context.
328 test.ok(clone.isArray(local)); // recognize in local context.
329 test.ok(!clone.isDate(alien));
330 test.ok(!clone.isDate(local));
331 test.ok(!clone.isRegExp(alien));
332 test.ok(!clone.isRegExp(local));
333 test.done();
334 }
335 );
336};
337
338exports["recognize Date object"] = function(test) {
339 var results = apartContext(
340 null, "results = new Date()",
341 function(alien) {
342 var local = new Date();
343 test.ok(clone.isDate(alien)); // recognize in other context.
344 test.ok(clone.isDate(local)); // recognize in local context.
345 test.ok(!clone.isArray(alien));
346 test.ok(!clone.isArray(local));
347 test.ok(!clone.isRegExp(alien));
348 test.ok(!clone.isRegExp(local));
349 test.done();
350 }
351 );
352};
353
354exports["recognize RegExp object"] = function(test) {
355 var results = apartContext(
356 null, "results = /foo/",
357 function(alien) {
358 var local = /bar/;
359 test.ok(clone.isRegExp(alien)); // recognize in other context.
360 test.ok(clone.isRegExp(local)); // recognize in local context.
361 test.ok(!clone.isArray(alien));
362 test.ok(!clone.isArray(local));
363 test.ok(!clone.isDate(alien));
364 test.ok(!clone.isDate(local));
365 test.done();
366 }
367 );
368};