UNPKG

13.1 kBJavaScriptView Raw
1'use strict';
2var ObjectManage = require('../lib/ObjectManage')
3 , expect = require('chai').expect
4describe('ObjectManage',function(){
5 var data1 = {test1: 'val1', test2: 'val2'}
6 , data2 = {test3: 'val3', test4: 'val4'}
7 , data3 = {test5: {test6: 'val6'}}
8
9 describe('Construction',function(){
10 it('should accept data to the constructor',function(){
11 var obj = new ObjectManage(data1)
12 expect(obj.data.test1).to.equal('val1')
13 expect(obj.data.test2).to.equal('val2')
14 })
15 it('should be able to merge in data after constructing',function(){
16 var obj = new ObjectManage([data1,data2])
17 expect(obj.data.test3).to.equal('val3')
18 expect(obj.data.test4).to.equal('val4')
19 })
20 })
21
22 describe('Setters and Getters',function(){
23 it('should be able to get a nested key',function(){
24 var obj = new ObjectManage([data1,data3])
25 expect(obj.get('test5.test6')).to.equal('val6')
26 })
27 it('should be able to set a nested key',function(){
28 var obj = new ObjectManage([data1,data3])
29 obj.set('test5.test7','val7')
30 expect(obj.data.test5.test7).to.equal('val7')
31 })
32 it('should overwrite a key to object if nested below',function(){
33 var obj = new ObjectManage([data1,data2,data3])
34 obj.set('test5.test6.new','val8')
35 expect(obj.data.test5.test6.new).to.equal('val8')
36 })
37 it('should returned undefined on a missing key',function(){
38 var obj = new ObjectManage(data1)
39 expect(obj.get('test5.test6')).to.equal(undefined)
40 })
41 })
42
43 describe('Removal and Existence',function(){
44 it('should return true if the property exists',function(){
45 var obj = new ObjectManage(data1)
46 expect(obj.exists('test1')).to.equal(true)
47 })
48 it('should return false if the property does not exist',function(){
49 var obj = new ObjectManage()
50 expect(obj.exists('test1')).to.equal(false)
51 })
52 it('should remove a property and all its children',function(){
53 var obj = new ObjectManage([data1,data2,data3])
54 obj.remove('test5')
55 expect(obj.data.hasOwnProperty('test5')).to.equal(false)
56 })
57 })
58
59 describe('Merging',function(){
60 it('should always have an object at .data',function(){
61 var obj = new ObjectManage()
62 obj.load(undefined)
63 expect(obj.data).to.be.an('object')
64 })
65 it('should return the whole object if no argument if passed to get',function(){
66 var obj = new ObjectManage([data1,data2,data3])
67 expect(Object.keys(obj.get()).length).to.equal(5)
68 })
69 it('should merge recursively',function(){
70 var obj = new ObjectManage(data3)
71 obj.load({test5: {test7: 'val7'}})
72 expect(obj.get('test5.test6')).to.equal('val6')
73 expect(obj.get('test5.test7')).to.equal('val7')
74 })
75 })
76
77 describe('Events',function(){
78 it('should be able to watch the data object',function(done){
79 var obj = new ObjectManage()
80 obj.once('load',function(data){
81 expect(data.test5.test6).to.equal('val6')
82 done()
83 })
84 obj.load(data3)
85 })
86 it('should emit a set event',function(done){
87 var obj = new ObjectManage()
88 obj.once('set',function(path,value){
89 expect(path).to.equal('foo')
90 expect(value).to.equal('baz')
91 done()
92 })
93 obj.set('foo','baz')
94 })
95 it('should emit a get event',function(done){
96 var obj = new ObjectManage(data1)
97 obj.once('get',function(path,value){
98 expect(path).to.equal('test1')
99 expect(value).to.equal('val1')
100 done()
101 })
102 obj.get('test1')
103 })
104 it('should emit an exists event',function(done){
105 var obj = new ObjectManage(data1)
106 obj.once('exists',function(path,exists){
107 expect(path).to.equal('foo')
108 expect(exists).to.equal(false)
109 done()
110 })
111 obj.exists('foo')
112 })
113 it('should emit a remove event',function(done){
114 var obj = new ObjectManage(data1)
115 obj.once('remove',function(path,removed){
116 expect(path).to.equal('test1')
117 expect(removed).to.equal(true)
118 done()
119 })
120 obj.remove('test1')
121 })
122 it('should emit a load event',function(done){
123 var obj = new ObjectManage()
124 obj.once('load',function(data){
125 expect(data.test1).to.equal('val1')
126 done()
127 })
128 obj.load(data1)
129 })
130 })
131
132 describe('Set with Validation',function(){
133 it('should validate using drop',function(done){
134 var obj = new ObjectManage()
135 obj.validateSet = function(path){
136 expect(path).to.equal('test1')
137 this.drop(path + ' must be set to val2')
138 }
139 obj.once('drop',function(verb,message,path,value){
140 expect(verb).to.equal('set')
141 expect(message).to.equal('test1 must be set to val2')
142 expect(path).to.equal('test1')
143 expect(value).to.equal('val3')
144 done()
145 })
146 obj.set('test1','val3')
147 })
148 it('should validate using reject',function(done){
149 var obj = new ObjectManage()
150 obj.validateSet = function(path){
151 expect(path).to.equal('test1')
152 this.reject(path + ' must be set to val2')
153 }
154 obj.once('reject',function(verb,message,path,value){
155 expect(verb).to.equal('set')
156 expect(message).to.equal('test1 must be set to val2')
157 expect(path).to.equal('test1')
158 expect(value).to.equal('val3')
159 done()
160 })
161 obj.set('test1','val3')
162 })
163 it('should validate using warn',function(done){
164 var obj = new ObjectManage()
165 obj.validateSet = function(path,value){
166 expect(path).to.equal('test1')
167 this.warn(path + ' must be set to val2',value)
168 }
169 obj.once('warn',function(verb,message,path,value){
170 expect(verb).to.equal('set')
171 expect(message).to.equal('test1 must be set to val2')
172 expect(path).to.equal('test1')
173 expect(value).to.equal('val3')
174 expect(obj.get('test1')).to.equal('val3')
175 done()
176 })
177 obj.set('test1','val3')
178 })
179 it('should validate using error',function(done){
180 var obj = new ObjectManage()
181 obj.validateSet = function(path){
182 expect(path).to.equal('test1')
183 this.error(path + ' must be set to val2')
184 }
185 obj.once('error',function(verb,message,path,value){
186 expect(verb).to.equal('set')
187 expect(message).to.equal('test1 must be set to val2')
188 expect(path).to.equal('test1')
189 expect(value).to.equal('val3')
190 done()
191 })
192 expect(function(){obj.set('test1','val3')}).to.throw('test1 must be set to val2')
193 })
194 it('should validate using ok',function(done){
195 var obj = new ObjectManage()
196 obj.validateSet = function(path,value){
197 expect(path).to.equal('test1')
198 this.ok(value)
199 }
200 obj.once('set',function(path,value){
201 expect(path).to.equal('test1')
202 expect(value).to.equal('val3')
203 expect(obj.get('test1')).to.equal('val3')
204 done()
205 })
206 obj.set('test1','val3')
207 })
208 it('should validate using return',function(done){
209 var obj = new ObjectManage()
210 obj.validateSet = function(path,value){
211 expect(path).to.equal('test1')
212 return value
213 }
214 obj.once('set',function(path,value){
215 expect(path).to.equal('test1')
216 expect(value).to.equal('val3')
217 expect(obj.get('test1')).to.equal('val3')
218 done()
219 })
220 obj.set('test1','val3')
221 })
222 })
223
224 describe('Get with Validation',function(){
225 it('should validate using drop',function(done){
226 var obj = new ObjectManage()
227 obj.validateGet = function(path){
228 expect(path).to.equal('test1')
229 this.drop(path + ' must be set to val2')
230 }
231 obj.once('drop',function(verb,message,path,value){
232 expect(verb).to.equal('get')
233 expect(message).to.equal('test1 must be set to val2')
234 expect(path).to.equal('test1')
235 expect(value).to.equal('val3')
236 done()
237 })
238 obj.set('test1','val3')
239 obj.get('test1')
240 })
241 it('should validate using reject',function(done){
242 var obj = new ObjectManage()
243 obj.validateGet = function(path){
244 expect(path).to.equal('test1')
245 this.reject(path + ' must be set to val2')
246 }
247 obj.once('reject',function(verb,message,path,value){
248 expect(verb).to.equal('get')
249 expect(message).to.equal('test1 must be set to val2')
250 expect(path).to.equal('test1')
251 expect(value).to.equal('val3')
252 done()
253 })
254 obj.set('test1','val3')
255 obj.get('test1')
256 })
257 it('should validate using warn',function(done){
258 var obj = new ObjectManage()
259 obj.validateGet = function(path,value){
260 expect(path).to.equal('test1')
261 this.warn(path + ' must be set to val2',value)
262 }
263 obj.once('warn',function(verb,message,path,value){
264 expect(verb).to.equal('get')
265 expect(message).to.equal('test1 must be set to val2')
266 expect(path).to.equal('test1')
267 expect(value).to.equal('val3')
268 done()
269 })
270 obj.set('test1','val3')
271 obj.get('test1')
272 })
273 it('should validate using error',function(done){
274 var obj = new ObjectManage()
275 obj.validateGet = function(path){
276 expect(path).to.equal('test1')
277 this.error(path + ' must be set to val2')
278 }
279 obj.once('error',function(verb,message,path,value){
280 expect(verb).to.equal('get')
281 expect(message).to.equal('test1 must be set to val2')
282 expect(path).to.equal('test1')
283 expect(value).to.equal('val3')
284 done()
285 })
286 obj.set('test1','val3')
287 expect(function(){obj.get('test1')}).to.throw('test1 must be set to val2')
288 })
289 it('should validate using ok',function(done){
290 var obj = new ObjectManage()
291 obj.validateGet = function(path){
292 expect(path).to.equal('test1')
293 this.ok('val4')
294 }
295 obj.once('get',function(path,value){
296 expect(path).to.equal('test1')
297 expect(value).to.equal('val4')
298 done()
299 })
300 obj.set('test1','val3')
301 obj.get('test1')
302 })
303 it('should validate using return',function(done){
304 var obj = new ObjectManage()
305 obj.validateGet = function(path){
306 expect(path).to.equal('test1')
307 return 'val4'
308 }
309 obj.once('get',function(path,value){
310 expect(path).to.equal('test1')
311 expect(value).to.equal('val4')
312 done()
313 })
314 obj.set('test1','val3')
315 obj.get('test1')
316 })
317 })
318
319 describe('Circular Reference Handling',function(){
320 it('should fail on circular referenced objects',function(){
321 var x = {
322 'a' : function () {return null}
323 }
324 x.b = x.a
325 var obj = new ObjectManage()
326 function load(){
327 obj.load(x)
328 }
329 expect(load).to.throw(Error)
330 })
331 it('should work using merge-recursive',function(){
332 var obj = new ObjectManage()
333 obj.merge = ObjectManage.prototype.mergeRecursive
334 obj.load(data1)
335 obj.load(data3)
336 expect(obj.get('test5.test6')).to.equal('val6')
337 })
338 it('should count object depth accurately',function(){
339 var testObject = {foo: {foo: {foo: 'baz'}}}
340 , obj = new ObjectManage()
341 expect(obj.countDepth(testObject)).to.equal(3)
342 })
343 it('should warn on objects more than 50 levels deep',function(){
344 //setup console mocking
345 var oldLog = console.log
346 , oldTrace = console.trace
347 , log = []
348 , traced = false
349 console.log = function(msg){
350 log.push(msg)
351 }
352 console.trace = function(){
353 traced = true
354 }
355 var buildObject = function(object,depth,count){
356 if(undefined === object) object = {}
357 if(undefined === count) count = 1
358 if(undefined === depth) depth = 100
359 if(count > depth) return object
360 object[count] = buildObject(object[count],depth,(count + 1))
361 return object
362 }
363 //var obj = new ObjectManage()
364 var badObject = buildObject()
365 , obj = new ObjectManage()
366 //verify the limiter on depth is working
367 expect(obj.countDepth(badObject)).to.equal(obj.maxDepth)
368 //verify that we can adjust the maxDepth
369 var oldMaxDepth = obj.maxDepth
370 obj.maxDepth = 20
371 expect(obj.countDepth(badObject)).to.equal(20)
372 //restore original
373 obj.maxDepth = oldMaxDepth
374 //load the bad object which should puke
375 obj.load(badObject)
376 //verify the warning was thrown
377 expect(log[0]).to.equal('WARN [object-manage]: Object being merged is too deep (50)')
378 expect(traced).to.equal(true)
379 //cleanup
380 log = []
381 traced = false
382 //set the max depth to a lower value and try again
383 obj.maxDepth = 10
384 //load the bad object which should puke
385 obj.load(badObject)
386 expect(log[0]).to.equal('WARN [object-manage]: Object being merged is too deep (10)')
387 expect(traced).to.equal(true)
388 //restore native console functions
389 console.log = oldLog
390 console.trace = oldTrace
391 })
392 })
393
394})
\No newline at end of file