@webqit/observer 1.7.6 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/.gitignore +3 -3
  2. package/LICENSE +20 -20
  3. package/README.md +202 -199
  4. package/dist/main.js +2 -2
  5. package/dist/main.js.map +7 -1
  6. package/package.json +68 -68
  7. package/src/actors.js +175 -0
  8. package/src/core/Descriptor.js +23 -0
  9. package/src/core/ListenerRegistration.js +54 -0
  10. package/src/core/ListenerRegistry.js +41 -0
  11. package/src/core/Registration.js +35 -0
  12. package/src/core/Registry.js +96 -0
  13. package/src/core/TrapsRegistration.js +35 -0
  14. package/src/core/TrapsRegistry.js +51 -0
  15. package/src/index.js +10 -74
  16. package/src/main.js +547 -0
  17. package/src/targets.browser.js +9 -0
  18. package/test/reactions.test.js +326 -337
  19. package/webpack.config.cjs +5 -5
  20. package/src/actions/_exec.js +0 -33
  21. package/src/actions/_setOrDefine.js +0 -136
  22. package/src/actions/apply.js +0 -19
  23. package/src/actions/construct.js +0 -19
  24. package/src/actions/defineProperty.js +0 -20
  25. package/src/actions/deleteProperty.js +0 -80
  26. package/src/actions/get.js +0 -53
  27. package/src/actions/getOwnPropertyDescriptor.js +0 -18
  28. package/src/actions/getPrototypeOf.js +0 -17
  29. package/src/actions/has.js +0 -18
  30. package/src/actions/isExtensible.js +0 -17
  31. package/src/actions/ownKeys.js +0 -17
  32. package/src/actions/preventExtensions.js +0 -17
  33. package/src/actions/set.js +0 -21
  34. package/src/actions/setPrototypeOf.js +0 -18
  35. package/src/actors/accessorize.js +0 -162
  36. package/src/actors/proxy.js +0 -59
  37. package/src/actors/unaccessorize.js +0 -26
  38. package/src/actors/unproxy.js +0 -17
  39. package/src/browser-entry.js +0 -11
  40. package/src/connectors/build.js +0 -64
  41. package/src/connectors/link.js +0 -76
  42. package/src/connectors/unlink.js +0 -35
  43. package/src/core/Action.js +0 -33
  44. package/src/core/Delta.js +0 -46
  45. package/src/core/Event.js +0 -141
  46. package/src/core/Fireable.js +0 -34
  47. package/src/core/Firebase.js +0 -136
  48. package/src/core/Interceptor.js +0 -33
  49. package/src/core/Interceptors.js +0 -61
  50. package/src/core/Mutation.js +0 -46
  51. package/src/core/Observer.js +0 -99
  52. package/src/core/Observers.js +0 -75
  53. package/src/core/utils.js +0 -51
  54. package/src/reactions/closure.js +0 -88
  55. package/src/reactions/intercept.js +0 -53
  56. package/src/reactions/observe.js +0 -45
  57. package/src/reactions/unintercept.js +0 -43
  58. package/src/reactions/unobserve.js +0 -36
@@ -1,337 +1,326 @@
1
-
2
- /**
3
- * @imports
4
- */
5
- import { expect } from 'chai';
6
- import Observers from '../src/core/Observers.js';
7
- import Interceptors from '../src/core/Interceptors.js';
8
- import observe from '../src/reactions/observe.js';
9
- import intercept from '../src/reactions/intercept.js';
10
- import set from '../src/actions/set.js';
11
- import get from '../src/actions/get.js';
12
- import accessorize from '../src/actors/accessorize.js';
13
- import unaccessorize from '../src/actors/unaccessorize.js';
14
- import proxy from '../src/actors/proxy.js';
15
- import unproxy from '../src/actors/unproxy.js';
16
-
17
- describe(`Test: .observe() + .set()`, function() {
18
-
19
- describe(`Observe all changes.`, function() {
20
-
21
- it(`Should recieve an event of one change on setting one prop.`, function() {
22
- var obj = {}, _changes;
23
- // -----
24
- observe(obj, changes => {
25
- _changes = changes;
26
- });
27
- // -----
28
- set(obj, {
29
- key1: 'value1',
30
- });
31
- // -----
32
- expect(_changes).to.be.an('array').with.length(1);
33
- });
34
-
35
- it(`Should recieve an event of two changes on batch-setting two props.`, function() {
36
- var obj = {}, _changes;
37
- // -----
38
- observe(obj, changes => {
39
- _changes = changes;
40
- });
41
- // -----
42
- set(obj, {
43
- key1: 'value1',
44
- key2: 'value2',
45
- });
46
- // -----
47
- expect(_changes).to.be.an('array').with.length(2);
48
- });
49
-
50
- });
51
-
52
- describe(`Observe with namespaces.`, function() {
53
-
54
- var obj = {},
55
- ObserversCustomAddMethodCalled = false,
56
- InterceptorsCustomAddMethodCalled = false,
57
- _changesRecieved = [];
58
- class Observers2 extends Observers {
59
- // Catch when fireables added.
60
- add(...args) {
61
- ObserversCustomAddMethodCalled = true;
62
- return super.add(...args);
63
- }
64
- }
65
- class Interceptors2 extends Interceptors {
66
- // Catch when fireables added.
67
- add(...args) {
68
- InterceptorsCustomAddMethodCalled = true;
69
- return super.add(...args);
70
- }
71
- }
72
- Observers.namespace('ns1', Observers2);
73
- Interceptors.namespace('ns1', Interceptors2);
74
-
75
- it(`Should assert that methods of an Observers namespace class are called.`, function() {
76
- observe(obj, changes => {
77
- _changesRecieved.push(changes);
78
- }, {
79
- namespace: 'ns1',
80
- });
81
- expect(ObserversCustomAddMethodCalled).to.be.true;
82
- });
83
-
84
- it(`Should that "events" off the namespace dont't leak.`, function() {
85
- _changesRecieved = [];
86
- ObserversCustomAddMethodCalled = false;
87
- InterceptorsCustomAddMethodCalled = false;
88
- observe(obj, () => {});
89
- set(obj, {
90
- key1: 'value1',
91
- key2: 'value2',
92
- });
93
- expect(_changesRecieved).to.be.an('array').with.lengthOf(0);
94
- expect(ObserversCustomAddMethodCalled).to.be.false;
95
- expect(InterceptorsCustomAddMethodCalled).to.be.false;
96
- });
97
-
98
- it(`Should assert that methods of an Interceptors namespace class are called.`, function() {
99
- InterceptorsCustomAddMethodCalled = false;
100
- intercept(obj, 'set', (e, recieved, next) => {
101
- return next();
102
- }, {
103
- namespace: 'ns1',
104
- });
105
- expect(InterceptorsCustomAddMethodCalled).to.be.true;
106
- });
107
-
108
- it(`Should assert that interceptor was called.`, function() {
109
- var handlerWasCalled;
110
- intercept(obj, {
111
- set: (e, recieved, next) => {
112
- handlerWasCalled = e.value;
113
- return next('new val');
114
- },
115
- });
116
- set(obj, 'someProp', 'some val');
117
- expect(handlerWasCalled).to.be.eq('some val');
118
- expect(obj.someProp).to.be.eq('new val');
119
- });
120
-
121
- it(`Should assert that "custom events" in the namespace fire.`, function() {
122
- _changesRecieved = [];
123
- Observers2.getFirebase(obj).fire([{
124
- name: 'costum-name', // required
125
- type: 'costum-type', // required
126
- }]);
127
- expect(_changesRecieved[0][0]).to.be.an('object').that.includes({ name: 'costum-name', type: 'costum-type', });
128
- });
129
-
130
- it(`Should that "set" operations in the namespace are recieved.`, function() {
131
- _changesRecieved = [];
132
- set(obj, {
133
- key1: 'value1',
134
- key2: 'value2',
135
- }, {
136
- namespace: 'ns1',
137
- });
138
- expect(_changesRecieved[0]).to.be.an('array').with.length(2);
139
- });
140
-
141
- });
142
-
143
- describe(`Observe paths.`, function() {
144
-
145
- it(`Observe a one-level path of an object.`, function() {
146
- var obj = {}, _change;
147
- // -----
148
- observe(obj, 'key1', change => {
149
- _change = change;
150
- });
151
- // -----
152
- set(obj, {
153
- key1: 'value1',
154
- });
155
- // -----
156
- expect(_change).to.be.an('object').that.includes({ name: 'key1', type: 'set', });
157
- });
158
-
159
- it(`Observe a two-level path of an object.`, function() {
160
- var obj = {}, _changes = [];
161
- // -----
162
- observe(obj, ['key1', 'sub.key1'], change => {
163
- _changes.push(change);
164
- });
165
- // -----
166
- set(obj, {
167
- key1: {},
168
- key2: {},
169
- });
170
- set(obj.key1, {
171
- 'sub.key1': {},
172
- subkey1: {},
173
- });
174
- // -----
175
- expect(_changes).to.have.lengthOf(1);
176
- expect(_changes[0]).to.be.an('object').that.deep.includes({ name: 'key1', path: [ 'key1', 'sub.key1' ], type: 'set', });
177
- });
178
-
179
- it(`Observe path 0 of an array.`, function() {
180
- var arr = [], _changes = [];
181
- // -----
182
- observe(arr, 0, change => {
183
- _changes.push(change);
184
- });
185
- // -----
186
- set(arr, 0, {});
187
- // -----
188
- expect(_changes).to.have.lengthOf(1);
189
- expect(_changes[0]).to.be.an('object').that.deep.includes({ name: 0, path: [ 0 ], type: 'set', });
190
- });
191
-
192
- it(`Observe path [0, 'key1'] of an array.`, function() {
193
- var arr = [], _changes = [];
194
- // -----
195
- observe(arr, [0, 'key1'], change => {
196
- _changes.push(change);
197
- });
198
- // -----
199
- set(arr, 0, {});
200
- set(arr[0], 'key1', {});
201
- // -----
202
- expect(_changes).to.have.lengthOf(1);
203
- expect(_changes[0]).to.be.an('object').that.deep.includes({ name: 0, path: [ 0, 'key1' ], type: 'set', });
204
- });
205
-
206
- it(`Observe wildcard paths.`, function() {
207
- var obj = {}, _changes = [];
208
- // -----
209
- observe(obj, ['key1', ,], change => {
210
- _changes.push(change);
211
- });
212
- // -----
213
- set(obj, {
214
- key1: {},
215
- key2: {},
216
- });
217
- set(obj.key1, {
218
- 'sub.key1': {},
219
- subkey1: {},
220
- });
221
- // -----
222
- expect(_changes).to.have.lengthOf(2);
223
- expect(_changes[0]).to.be.an('object').that.deep.includes({ name: 'key1', path: [ 'key1', 'sub.key1' ], type: 'set', });
224
- });
225
-
226
- it(`Observe path [0] and subtree of an array.`, function() {
227
- var arr = [], _changes = [];
228
- // -----
229
- observe(arr, 0, change => {
230
- _changes.push(change);
231
- }, {subtree: true});
232
- // -----
233
- set(arr, 0, {});
234
- set(arr[0], 'key1', {});
235
- // -----
236
- expect(_changes).to.have.lengthOf(2);
237
- expect(_changes[1][0]).to.be.an('object').that.deep.includes({ name: 0, path: [ 0, 'key1' ], type: 'set', });
238
- });
239
-
240
- });
241
-
242
- describe(`Accessorize/unaccessorize.`, function() {
243
-
244
- it(`Should report a change on setting an accessorized prop. Should report nothing after unaccessorizing the prop.`, function() {
245
- var obj = {}, _changes = [];
246
- // -----
247
- observe(obj, changes => {
248
- _changes.push(changes);
249
- });
250
- // -----
251
- var accessorizeFlag = accessorize(obj, 'key1');
252
- obj.key1 = 'value1'; // Should fire event
253
- // -----
254
- var unaccessorizeFlag = unaccessorize(obj, 'key1');
255
- obj.key1 = 'value1-b'; // Should not fire event
256
- // -----
257
- expect(accessorizeFlag).to.be.true;
258
- expect(unaccessorizeFlag).to.be.true;
259
- expect(_changes).to.be.an('array').with.length(1);
260
- });
261
-
262
- it(`Should report a change on setting an immutable accessorized prop. Should be unable to unaccessorize the immutable prop. Should report additional changes`, function() {
263
- var obj = {}, _changes = [];
264
- // -----
265
- observe(obj, changes => {
266
- _changes.push(changes);
267
- });
268
- // -----
269
- var accessorizeFlag = accessorize(obj, 'key1', { configurable: false });
270
- obj.key1 = 'value1'; // Should fire event
271
- // -----
272
- var unaccessorizeFlag = unaccessorize(obj, 'key1');
273
- obj.key1 = 'value1-b'; // Should still fire event
274
- // -----
275
- expect(accessorizeFlag).to.be.true;
276
- expect(unaccessorizeFlag).to.be.false;
277
- expect(_changes).to.be.an('array').with.length(2);
278
- });
279
-
280
- });
281
-
282
- describe(`Proxy/unproxy.`, function() {
283
-
284
- it(`Should report a change on setting a prop on a proxied instance.`, function() {
285
- var obj = {}, _changes = [];
286
- // -----
287
- observe(obj, changes => {
288
- _changes.push(changes);
289
- });
290
- // -----
291
- var _obj = proxy(obj);
292
- _obj.key1 = 'value1'; // Should fire event
293
- _obj.key2 = 'value2'; // Should fire event
294
- // -----
295
- expect(_obj === obj).to.be.false;
296
- expect(unproxy(_obj) === obj).to.be.true;
297
- expect(_changes).to.be.an('array').with.length(2);
298
- });
299
-
300
- });
301
-
302
- describe(`Accessorize/unaccessorize.`, function() {
303
-
304
- it(`Should report just a change on PROGRAMMATICALLY setting an already ACCESSORIZED prop.`, function() {
305
- var obj = {}, _changes = [];
306
- // -----
307
- observe(obj, changes => {
308
- _changes.push(changes);
309
- });
310
- // -----
311
- accessorize(obj, 'key1');
312
- set(obj, 'key1', 'value1'); // Should fire just one event
313
- // -----
314
- obj.key1 = 'value1-b'; // Should fire event
315
- // -----
316
- expect(_changes).to.be.an('array').with.length(2);
317
- });
318
-
319
- it(`Should report just a change on PROGRAMMATICALLY setting an already ACCESSORIZED prop of a PROXIED instance.`, function() {
320
- var obj = {}, _changes = [];
321
- // -----
322
- observe(obj, changes => {
323
- _changes.push(changes);
324
- });
325
- // -----
326
- accessorize(obj, 'key1');
327
- var _obj = proxy(obj);
328
- set(_obj, 'key1', 'value1'); // Should fire just one event
329
- // -----
330
- obj.key1 = 'value1-b'; // Should fire event
331
- // -----
332
- expect(_changes).to.be.an('array').with.length(2);
333
- });
334
-
335
- });
336
-
337
- });
1
+
2
+ /**
3
+ * @imports
4
+ */
5
+ import { expect } from 'chai';
6
+ import Observer from '../src/index.js';
7
+ import TrapsRegistry from '../src/core/TrapsRegistry.js';
8
+ import ListenerRegistry from '../src/core/ListenerRegistry.js';
9
+
10
+
11
+ describe( `Test: .observe() + .set()`, function() {
12
+
13
+ describe( `Observe all changes.`, function() {
14
+
15
+ it( `Should recieve an event of one change on setting one prop.`, function() {
16
+ let obj = {}, _changes;
17
+ // -----
18
+ Observer.observe( obj, changes => {
19
+ _changes = changes;
20
+ } );
21
+ // -----
22
+ Observer.set( obj, {
23
+ key1: 'value1',
24
+ } );
25
+ // -----
26
+ expect( _changes ).to.be.an( 'array' ).with.length( 1 );
27
+ } );
28
+
29
+ it( `Should recieve an event of two changes on batch-setting two props.`, function() {
30
+ let obj = {}, _changes;
31
+ // -----
32
+ Observer.observe( obj, changes => {
33
+ _changes = changes;
34
+ } );
35
+ // -----
36
+ Observer.set( obj, {
37
+ key1: 'value1',
38
+ key2: 'value2',
39
+ } );
40
+ // -----
41
+ expect( _changes ).to.be.an( 'array' ).with.length( 2 );
42
+ } );
43
+
44
+ } );
45
+
46
+ describe( `Observe with namespaces.`, function() {
47
+
48
+ let obj = {},
49
+ ListenerRegistryCustomAddMethodCalled = false,
50
+ TrapsRegistryCustomAddMethodCalled = false,
51
+ _changesRecieved = [];
52
+ class ListenerRegistry2 extends ListenerRegistry {
53
+ // Catch when fireables added.
54
+ addRegistration( ...args ) {
55
+ ListenerRegistryCustomAddMethodCalled = true;
56
+ return super.addRegistration( ...args );
57
+ }
58
+ }
59
+ class TrapsRegistry2 extends TrapsRegistry {
60
+ // Catch when fireables added.
61
+ addRegistration( ...args ) {
62
+ TrapsRegistryCustomAddMethodCalled = true;
63
+ return super.addRegistration( ...args );
64
+ }
65
+ }
66
+ ListenerRegistry.namespace( 'ns1', ListenerRegistry2 );
67
+ TrapsRegistry.namespace( 'ns1', TrapsRegistry2 );
68
+
69
+ it( `Should assert that methods of an Observers namespace class are called.`, function() {
70
+ Observer.observe( obj, changes => {
71
+ _changesRecieved.push( changes );
72
+ }, {
73
+ namespace: 'ns1',
74
+ } );
75
+ expect( ListenerRegistryCustomAddMethodCalled ).to.be.true;
76
+ } );
77
+
78
+ it( `Should that "events" off the namespace dont't leak.`, function() {
79
+ _changesRecieved = [];
80
+ ListenerRegistryCustomAddMethodCalled = false;
81
+ TrapsRegistryCustomAddMethodCalled = false;
82
+ Observer.observe( obj, () => {} );
83
+ Observer.set( obj, {
84
+ key1: 'value1',
85
+ key2: 'value2',
86
+ } );
87
+ expect( _changesRecieved ).to.be.an( 'array' ).with.lengthOf( 0 );
88
+ expect( ListenerRegistryCustomAddMethodCalled ).to.be.false;
89
+ expect( TrapsRegistryCustomAddMethodCalled ).to.be.false;
90
+ } );
91
+
92
+ it( `Should assert that methods of an Interceptors namespace class are called.`, function() {
93
+ TrapsRegistryCustomAddMethodCalled = false;
94
+ Observer.intercept( obj, 'set', ( e, recieved, next ) => {
95
+ return next();
96
+ }, {
97
+ namespace: 'ns1',
98
+ } );
99
+ expect( TrapsRegistryCustomAddMethodCalled ).to.be.true;
100
+ } );
101
+
102
+ it( `Should assert that interceptor was called.`, function() {
103
+ let handlerWasCalled;
104
+ Observer.intercept( obj, {
105
+ set: ( e, recieved, next ) => {
106
+ handlerWasCalled = e.value;
107
+ e.value = 'new val';
108
+ return next();
109
+ },
110
+ } );
111
+ Observer.set( obj, 'someProp', 'some val' );
112
+ expect( handlerWasCalled ).to.be.eq( 'some val' );
113
+ expect( obj.someProp ).to.be.eq( 'new val' );
114
+ } );
115
+
116
+ it( `Should assert that "custom events" in the namespace fire.`, function() {
117
+ _changesRecieved = [];
118
+ ListenerRegistry2.getInstance( obj ).emit( [ {
119
+ key: 'costum-name', // required
120
+ type: 'costum-type', // required
121
+ } ] );
122
+ expect( _changesRecieved[ 0 ][ 0 ] ).to.be.an( 'object' ).that.includes( { key: 'costum-name', type: 'costum-type', } );
123
+ } );
124
+
125
+ it( `Should that "set" events in the namespace are recieved.`, function() {
126
+ _changesRecieved = [];
127
+ Observer.set( obj, {
128
+ key1: 'value1',
129
+ key2: 'value2',
130
+ }, {
131
+ namespace: 'ns1',
132
+ } );
133
+ expect( _changesRecieved[ 0 ] ).to.be.an( 'array' ).with.length( 2 );
134
+ } );
135
+
136
+ } );
137
+
138
+ describe( `Observe paths.`, function() {
139
+
140
+ it( `Observe a one-level path of an object.`, function() {
141
+ let obj = {}, _change;
142
+ // -----
143
+ Observer.observe( obj, 'key1', change => {
144
+ _change = change;
145
+ } );
146
+ // -----
147
+ Observer.set( obj, {
148
+ key1: 'value1',
149
+ } );
150
+ // -----
151
+ expect( _change ).to.be.an( 'object' ).that.includes( { key: 'key1', type: 'set', } );
152
+ } );
153
+
154
+ it( `Observe a two-level path of an object. (Using Observer.observe() with preflight option.)`, function() {
155
+ let obj = {}, _changes = [];
156
+ // -----
157
+ Observer.deep( obj, [ 'key1', 'sub.key1' ], Observer.observe, change => {
158
+ _changes.push( change );
159
+ }, { preflight: true } );
160
+ // -----
161
+ Observer.set( obj, {
162
+ key1: {},
163
+ key2: {},
164
+ } );
165
+ Observer.set( obj.key1, {
166
+ 'sub.key1': {},
167
+ subkey1: {},
168
+ } );
169
+ // -----
170
+ expect( _changes ).to.have.lengthOf( 2 );
171
+ expect( _changes[ 0 ] ).to.be.an( 'object' ).that.deep.includes( { key: 'sub.key1', path: [ 'key1', 'sub.key1' ], type: 'get', value: undefined, } );
172
+ expect( _changes[ 1 ] ).to.be.an( 'object' ).that.deep.includes( { key: 'sub.key1', path: [ 'key1', 'sub.key1' ], type: 'set', value: {}, } );
173
+ } );
174
+
175
+ it( `Observe a two-level path of an object. (Using Observer.get() with "live" option.)`, function() {
176
+ let obj = {}, _changes = [];
177
+ // -----
178
+ Observer.deep( obj, [ 'key1', 'sub.key1' ], Observer.get, change => {
179
+ _changes.push( change );
180
+ }, { live: true } );
181
+ // -----
182
+ Observer.set( obj, {
183
+ key1: {},
184
+ key2: {},
185
+ } );
186
+ Observer.set( obj.key1, {
187
+ 'sub.key1': {},
188
+ subkey1: {},
189
+ } );
190
+ // -----
191
+ expect( _changes ).to.have.lengthOf( 2 );
192
+ expect( _changes[ 0 ] ).to.be.an( 'object' ).that.deep.includes( { key: 'sub.key1', path: [ 'key1', 'sub.key1' ], type: 'get', value: undefined, } );
193
+ expect( _changes[ 1 ] ).to.be.an( 'object' ).that.deep.includes( { key: 'sub.key1', path: [ 'key1', 'sub.key1' ], type: 'set', value: {}, } );
194
+ } );
195
+
196
+ it( `Observe path 0 of an array.`, function() {
197
+ let arr = [], _changes = [];
198
+ // -----
199
+ Observer.observe( arr, 0, change => {
200
+ _changes.push( change );
201
+ }, { preflight: true } );
202
+ // -----
203
+ Observer.set( arr, 0, {} );
204
+ // -----
205
+ expect( _changes ).to.have.lengthOf( 2 );
206
+ expect( _changes[ 0 ] ).to.be.an( 'object' ).that.deep.includes( { key: 0, type: 'get', } );
207
+ expect( _changes[ 1 ] ).to.be.an( 'object' ).that.deep.includes( { key: 0, type: 'set', } );
208
+ } );
209
+
210
+ it( `Observe path [ 0, 'key1' ] of an array.`, function() {
211
+ let arr = [], _changes = [];
212
+ // -----
213
+ Observer.deep( arr, [ 0, 'key1' ], Observer.observe, change => {
214
+ _changes.push( change );
215
+ }, { preflight: true } );
216
+ // -----
217
+ Observer.set( arr, 0, {} );
218
+ Observer.set( arr[ 0 ], 'key1', {} );
219
+ // -----
220
+ expect( _changes ).to.have.lengthOf( 2 );
221
+ expect( _changes[ 0 ] ).to.be.an( 'object' ).that.deep.includes( { key: 'key1', path: [ 0, 'key1' ], type: 'get', } );
222
+ expect( _changes[ 1 ] ).to.be.an( 'object' ).that.deep.includes( { key: 'key1', path: [ 0, 'key1' ], type: 'set', } );
223
+ } );
224
+
225
+ it( `Observe wildcard paths.`, function() {
226
+ let obj = {}, _changes = [];
227
+ // -----
228
+ Observer.deep( obj, [ 'key1', Infinity ], Observer.observe, change => {
229
+ _changes.push( change );
230
+ }, { preflight: true } );
231
+ // -----
232
+ Observer.set( obj, {
233
+ key1: {},
234
+ key2: {},
235
+ } );
236
+ Observer.set( obj.key1, {
237
+ 'sub.key1': {},
238
+ subkey1: {},
239
+ } );
240
+ // -----
241
+ expect( _changes ).to.have.lengthOf( 2 );
242
+ expect( _changes[ 0 ] ).to.be.an( 'array' ).lengthOf( 0 );
243
+ expect( _changes[ 1 ] ).to.be.an( 'array' ).lengthOf( 2 );
244
+ expect( _changes[ 1 ][ 0 ] ).to.be.an( 'object' ).that.deep.includes( { key: 'sub.key1', path: [ 'key1', 'sub.key1' ], type: 'set', } );
245
+ } );
246
+
247
+ } );
248
+
249
+ describe( `Accessorize/unaccessorize.`, function() {
250
+
251
+ it( `Should report a change on setting an accessorized prop. Should report nothing after unaccessorizing the prop.`, function() {
252
+ let obj = {}, _changes = [];
253
+ // -----
254
+ Observer.observe( obj, changes => {
255
+ _changes.push( changes );
256
+ } );
257
+ // -----
258
+ let accessorizeFlag = Observer.accessorize( obj, 'key11111' );
259
+ obj.key11111 = 'value1'; // Should fire event
260
+ // -----
261
+ let unaccessorizeFlag = Observer.unaccessorize( obj, 'key11111' );
262
+ obj.key11111 = 'value1-b'; // Should not fire event
263
+ // -----
264
+ expect( accessorizeFlag ).to.be.true;
265
+ expect( unaccessorizeFlag ).to.be.true;
266
+ expect( _changes ).to.be.an( 'array' ).with.length( 1 );
267
+ } );
268
+
269
+ } );
270
+
271
+ describe( `Proxy/unproxy.`, function() {
272
+
273
+ it( `Should report a change on setting a prop on a proxied instance.`, function() {
274
+ let obj = {}, _changes = [];
275
+ // -----
276
+ Observer.observe( obj, changes => {
277
+ _changes.push( changes );
278
+ } );
279
+ // -----
280
+ let _obj = Observer.proxy( obj );
281
+ _obj.key1 = 'value1'; // Should fire event
282
+ _obj.key2 = 'value2'; // Should fire event
283
+ // -----
284
+ expect( _changes ).to.be.an( 'array' ).with.length( 2 );
285
+ expect( _obj === obj ).to.be.false;
286
+ expect( Observer.unproxy( _obj ) === obj ).to.be.true;
287
+ } );
288
+
289
+ } );
290
+
291
+ describe( `Accessorize/unaccessorize.`, function() {
292
+
293
+ it( `Should report just a change on PROGRAMMATICALLY setting an already ACCESSORIZED prop.`, function() {
294
+ let obj = {}, _changes = [];
295
+ // -----
296
+ Observer.observe( obj, changes => {
297
+ _changes.push( changes );
298
+ } );
299
+ // -----
300
+ Observer.accessorize( obj, 'key1' );
301
+ Observer.set( obj, 'key1', 'value1' ); // Should fire just one event
302
+ // -----
303
+ obj.key1 = 'value1-b'; // Should fire event
304
+ // -----
305
+ expect( _changes ).to.be.an( 'array' ).with.length( 2 );
306
+ } );
307
+
308
+ it( `Should report just a change on PROGRAMMATICALLY setting an already ACCESSORIZED prop of a PROXIED instance.`, function() {
309
+ let obj = {}, _changes = [];
310
+ // -----
311
+ Observer.observe( obj, changes => {
312
+ _changes.push( changes );
313
+ } );
314
+ // -----
315
+ Observer.accessorize( obj, 'key1' );
316
+ let _obj = Observer.proxy( obj );
317
+ Observer.set( _obj, 'key1', 'value1' ); // Should fire just one event
318
+ // -----
319
+ obj.key1 = 'value1-b'; // Should fire event
320
+ // -----
321
+ expect( _changes ).to.be.an( 'array' ).with.length( 2 );
322
+ } );
323
+
324
+ } );
325
+
326
+ } );