UNPKG

10.6 kBJavaScriptView Raw
1// test object utils
2var assert = require('assert'),
3 approx = require('../../tools/approx'),
4 object = require('../../lib/utils/object');
5
6describe ('object', function () {
7
8 describe('clone', function() {
9
10 it('should clone undefined', function () {
11 assert.strictEqual(object.clone(undefined), undefined);
12 });
13
14 it('should clone null', function () {
15 assert.strictEqual(object.clone(null), null);
16 });
17
18 it('should clone booleans', function () {
19 assert.strictEqual(object.clone(true), true);
20 assert.strictEqual(object.clone(false), false);
21 assert.ok(object.clone(new Boolean(true)) instanceof Boolean);
22 assert.equal(object.clone(new Boolean(true)), true);
23 assert.equal(object.clone(new Boolean(false)), false);
24 });
25
26 it('should clone numbers', function () {
27 assert.strictEqual(object.clone(2.3), 2.3);
28 assert.ok(object.clone(new Number(2.3)) instanceof Number);
29 assert.equal(object.clone(new Number(2.3)), 2.3);
30 });
31
32 it('should clone strings', function () {
33 assert.strictEqual(object.clone('hello'), 'hello');
34 assert.ok(object.clone(new String('hello')) instanceof String);
35 assert.equal(object.clone(new String('hello')), 'hello');
36 });
37
38 it('should (deep) clone objects', function () {
39 var obj = {a: {b: 'c', d: new Date(2014,0,1)}};
40 var clone = object.clone(obj);
41
42 assert.deepEqual(obj, clone);
43
44 // check whether the clone remains unchanged when changing the original object
45 obj.a.b = 'cc';
46
47 assert.equal(clone.a.b, 'c');
48
49 obj.a.d.setMonth(2);
50 assert.equal(clone.a.d.valueOf(), new Date(2014,0,1).valueOf());
51 });
52
53 it('should clone dates', function () {
54 var d1 = new Date(2014,1,1);
55 var d2 = object.clone(d1);
56 assert.equal(d1.valueOf(), d2.valueOf());
57 d1.setMonth(2);
58 assert.notEqual(d1, d2);
59 });
60
61 it('should (deep) clone arrays', function () {
62 var d = new Date(2014,0,1);
63 var arr = [1, 2, d, {a: 3}]
64 var clone = object.clone(arr);
65
66 assert.deepEqual(arr, clone);
67 assert.notStrictEqual(arr, clone);
68 assert.notStrictEqual(arr[2], clone[2]);
69 assert.notStrictEqual(arr[3], clone[3]);
70
71 // check whether the clone remains unchanged when changing the original object
72 arr[2] = null;
73 arr[3].a = 1;
74 d.setMonth(2);
75 assert.equal(clone[2].valueOf(), new Date(2014,0,1).valueOf());
76 assert.equal(clone[3].a, 3);
77 });
78
79 it('should throw an error in case of an unsupported type', function () {
80 assert.throws(function () {object.clone(/a regexp/)}, /Cannot clone/);
81 });
82 });
83
84 describe('extend', function() {
85 it ('should extend an object with all properties of an other object', function () {
86 var e = {};
87 var o1 = {a: 2, b: 3};
88 var o2 = {a: 4, b: null, c: undefined, d: 5, e: e};
89 var o3 = object.extend(o1, o2);
90
91 assert.strictEqual(o1, o3);
92 assert.strictEqual(o1.e, o3.e);
93 assert.deepEqual(o3, {a: 4, b: null, c: undefined, d: 5, e: e});
94 assert.deepEqual(o2, {a: 4, b: null, c: undefined, d: 5, e: e}); // should be unchanged
95 });
96
97 it('should ignore inherited properties when extending an object', function () {
98 Object.prototype.foo = 'bar';
99 var o1 = {a: 2, b: 3};
100 var o2 = object.extend({}, o1);
101
102 assert.equal(o2['foo'], 'bar');
103 assert.equal(o2.hasOwnProperty('foo'), false);
104
105 delete Object.prototype.foo;
106 });
107 });
108
109 describe('deepExtend', function() {
110 it ('should deep extend an object with all properties of an other object', function () {
111 var e = {f: {g: 3}};
112 var o1 = {a: 2, b: 3};
113 var o2 = {a: 4, b: null, c: undefined, d: 5, e: e};
114 var o3 = object.deepExtend(o1, o2);
115
116 assert.strictEqual(o1, o3);
117 assert.notStrictEqual(o3.e, o2.e);
118 assert.deepEqual(o3, {a: 4, b: null, c: undefined, d: 5, e: {f: {g: 3}}});
119 assert.deepEqual(o2, {a: 4, b: null, c: undefined, d: 5, e: {f: {g: 3}}}); // should be unchanged
120
121 e.f.g = 4;
122 assert.deepEqual(o3, {a: 4, b: null, c: undefined, d: 5, e: {f: {g: 3}}}); // should be unchanged
123 assert.deepEqual(o2, {a: 4, b: null, c: undefined, d: 5, e: {f: {g: 4}}}); // should be changed
124 });
125
126 it ('should throw an error when deep extending an array (is not yet supported)', function () {
127 assert.throws(function () {object.deepExtend({}, [])}, /Arrays are not supported by deepExtend/);
128 assert.throws(function () {object.deepExtend({}, {a: []})}, /Arrays are not supported by deepExtend/);
129 assert.throws(function () {object.deepExtend({}, {a: {b: []}})}, /Arrays are not supported by deepExtend/);
130 });
131
132 it('should ignore inherited properties when deep extending an object', function () {
133 Object.prototype.foo = 'bar';
134 var o1 = {a: 2, b: 3};
135 var o2 = object.deepExtend({}, o1);
136
137 assert.equal(o2['foo'], 'bar');
138 assert.equal(o2.hasOwnProperty('foo'), false);
139
140 delete Object.prototype.foo;
141 });
142 });
143
144 describe('deepEqual', function() {
145
146 it('should deep compare two objects', function () {
147 assert.equal(object.deepEqual({}, {}), true);
148
149 assert.equal(object.deepEqual({a: 2, b: 3}, {a: 2, b: 3}), true);
150 assert.equal(object.deepEqual({a: 2, b: 3}, {a: 2, b: 4}), false);
151 assert.equal(object.deepEqual({a: 2, b: 3}, {a: 2}), false);
152 assert.equal(object.deepEqual({a: 2}, {a: 2, b: 3}), false);
153 assert.equal(object.deepEqual({a: 2, b: 3}, {a: 2, b: {}}), false);
154 assert.equal(object.deepEqual({a: 2, b: {}}, {a: 2, b: {}}), true);
155
156 assert.equal(object.deepEqual({a: 2, b: {c: 4}}, {a: 2, b: {c: 4}}), true);
157 assert.equal(object.deepEqual({a: 2, b: {c: 4}}, {a: 2, b: {c : 5}}), false);
158 assert.equal(object.deepEqual({a: 2, b: {c: 4}}, {a: 2, b: {}}), false);
159 assert.equal(object.deepEqual({a: 2, b: {}}, {a: 2, b: {c: 4}}), false);
160 });
161
162 it('should deep compare two arrays', function () {
163 assert.equal(object.deepEqual([], []), true);
164 assert.equal(object.deepEqual([1, 2], [1, 2]), true);
165 assert.equal(object.deepEqual([1, 2], [1, 2, 3]), false);
166 assert.equal(object.deepEqual([1, 0, 3], [1, 2, 3]), false);
167
168 assert.equal(object.deepEqual([1, 2, [3, 4]], [1, 2, [3, 4]]), true);
169 assert.equal(object.deepEqual([1, 2, [3]], [1, 2, [3, 4]]), false);
170 assert.equal(object.deepEqual([1, 2, [3, 4]], [1, 2, [3]]), false);
171 assert.equal(object.deepEqual([1, 2, null], [1, 2, [3]]), false);
172 assert.equal(object.deepEqual([1, 2, [3]], [1, 2, null]), false);
173 assert.equal(object.deepEqual([1, 2, 3], [1, 2, [3]]), false);
174 assert.equal(object.deepEqual([1, 2, [3]], [1, 2, 3]), false);
175 });
176
177 it('should deep compare mixed objects an arrays', function () {
178 assert.equal(object.deepEqual({}, []), false);
179 assert.equal(object.deepEqual({a: {}}, {a: []}), false);
180
181 assert.equal(object.deepEqual({a: [1,2,3]}, {a:[1,2,3]}), true);
182 assert.equal(object.deepEqual({a: [1,2,{}]}, {a:[1,2,{}]}), true);
183 assert.equal(object.deepEqual({a: [1,2,{b: 4}]}, {a:[1,2,{b: 4}]}), true);
184 assert.equal(object.deepEqual({a: [1,2,{b: 4}]}, {a:[1,2,{b: 5}]}), false);
185 assert.equal(object.deepEqual({a: [1,2,{b: 4}]}, {a:[1,2,{}]}), false);
186
187 assert.equal(object.deepEqual([1, 2, {}], [1, 2, {}]), true);
188 assert.equal(object.deepEqual([1, 2, {a: 3}], [1, 2, {a : 3}]), true);
189 assert.equal(object.deepEqual([1, 2, {a: 3}], [1, 2, {a : 4}]), false);
190 assert.equal(object.deepEqual([1, 2, {a: 3}], [1, 2, 3]), false);
191 assert.equal(object.deepEqual([1, 2, 3], [1, 2, {a: 3}]), false);
192 assert.equal(object.deepEqual([1, 2, {a: [3, 4]}], [1, 2, {a: [3, 4]}]), true);
193 assert.equal(object.deepEqual([1, 2, {a: [3, 4]}], [1, 2, {a: [3, 4, 5]}]), false);
194 });
195
196 it('should not ignore inherited properties during comparison', function () {
197 Object.prototype.foo = 'bar';
198
199 assert.equal(object.deepEqual({}, {}), true);
200 assert.equal(object.deepEqual({foo: 'bar'}, {}), true);
201
202 delete Object.prototype.foo;
203 });
204 });
205
206 describe('canDefineProperty', function() {
207
208 it('should test whether defineProperty is available', function () {
209 assert.equal(object.canDefineProperty(), true);
210 });
211 });
212
213
214 describe('lazy', function() {
215
216 it('should get a lazy property', function () {
217 var obj = {};
218 var count = 0;
219 object.lazy(obj, 'x', function () {
220 count++;
221 return 2;
222 });
223
224 var x = obj.x;
225 assert.equal(x, 2);
226 assert.equal(count, 1);
227
228 var x2 = obj.x;
229 assert.equal(x2, 2);
230 assert.equal(count, 1);
231 });
232
233 it('should set a lazy property', function () {
234 var obj = {};
235 object.lazy(obj, 'x', function () {
236 return 2;
237 });
238
239 obj.x = 3;
240 var x = obj.x;
241 assert.equal(x, 3);
242 });
243
244 });
245
246 describe('traverse', function() {
247
248 it('should traverse an existing path into an object', function () {
249 var a = {};
250 var b = {a: a};
251 var c = {b: b};
252
253 assert.strictEqual(object.traverse(c), c);
254 assert.strictEqual(object.traverse(c, ''), c);
255 assert.strictEqual(object.traverse(c, 'b'), b);
256 assert.strictEqual(object.traverse(c, 'b.a'), a);
257 });
258
259 it('should append missing piece of a path', function () {
260 var a = {};
261 var b = {a: a};
262 var c = {b: b};
263
264 assert.strictEqual(object.traverse(c), c);
265 assert.strictEqual(object.traverse(c, ''), c);
266 assert.strictEqual(object.traverse(c, 'b'), b);
267 assert.strictEqual(object.traverse(c, 'b.a'), a);
268 assert.strictEqual(object.traverse(c, 'b.d'), b.d);
269 assert.strictEqual(object.traverse(c, 'b.e.f'), b.e.f);
270 });
271
272 });
273
274 describe ('isFactory', function () {
275
276 it('should test whether an object is a factory', function () {
277 assert.equal(object.isFactory({}), false);
278 assert.equal(object.isFactory({foo: true}), false);
279 assert.equal(object.isFactory({name: 'foo'}), false);
280 assert.equal(object.isFactory({name: 'foo', factory: 'bar'}), false);
281 assert.equal(object.isFactory({name: 2, factory: function () {}}), true);
282 assert.equal(object.isFactory({factory: function () {}}), true);
283
284 assert.equal(object.isFactory({name: 'foo', factory: function () {}}), true);
285 assert.equal(object.isFactory({name: 'foo', factory: function () {}, foo: 'bar'}), true);
286 });
287
288 })
289});
\No newline at end of file