|
| 1 | +import Neo from '../../../../src/Neo.mjs'; |
| 2 | +import * as core from '../../../../src/core/_export.mjs'; |
| 3 | +import {isDescriptor} from '../../../../src/core/ConfigSymbols.mjs'; |
| 4 | + |
| 5 | +class TestComponent extends core.Base { |
| 6 | + static config = { |
| 7 | + className : 'Neo.Test.CustomFunctionsComponent', |
| 8 | + arrayConfig_ : { |
| 9 | + [isDescriptor]: true, |
| 10 | + value : [1, 2], |
| 11 | + // NOTE: The custom merge function is called during two distinct phases: |
| 12 | + // 1. During Neo.setupClass(): To merge the static config down the inheritance chain. |
| 13 | + // At this stage, `defaultValue` will be `undefined` if the config is defined for the |
| 14 | + // first time in this class. The function must handle this case. |
| 15 | + // 2. During Neo.create(): To merge an instance-specific value into the class's final |
| 16 | + // static default value. |
| 17 | + merge : (defaultValue, instanceValue) => { |
| 18 | + // Custom merge: concatenate arrays. Handle the initial undefined case. |
| 19 | + return (defaultValue || []).concat(instanceValue); |
| 20 | + } |
| 21 | + }, |
| 22 | + objectConfig_: { |
| 23 | + [isDescriptor]: true, |
| 24 | + value : {id: 1, data: 'initial'}, |
| 25 | + isEqual : (a, b) => { |
| 26 | + // Custom isEqual: compare by id property |
| 27 | + return a?.id === b?.id; |
| 28 | + } |
| 29 | + } |
| 30 | + } |
| 31 | +} |
| 32 | +Neo.setupClass(TestComponent); |
| 33 | + |
| 34 | +StartTest(t => { |
| 35 | + t.it('Custom "merge" function for array concatenation', t => { |
| 36 | + const instance = Neo.create(TestComponent, { |
| 37 | + arrayConfig: [3, 4] |
| 38 | + }); |
| 39 | + |
| 40 | + // The custom merge function should concatenate the static default value [1, 2] |
| 41 | + // with the instance value [3, 4] |
| 42 | + t.isDeeplyStrict(instance.arrayConfig, [1, 2, 3, 4], 'Custom merge function should concatenate arrays'); |
| 43 | + }); |
| 44 | + |
| 45 | + t.it('Custom "isEqual" function for object comparison by id', t => { |
| 46 | + const instance = Neo.create(TestComponent); |
| 47 | + const configController = instance.getConfig('objectConfig'); |
| 48 | + |
| 49 | + let subscriberCalled = 0; |
| 50 | + configController.subscribe(() => { |
| 51 | + subscriberCalled++; |
| 52 | + }); |
| 53 | + |
| 54 | + t.is(instance.objectConfig.data, 'initial', 'Initial object data is correct'); |
| 55 | + |
| 56 | + // Set a new object with the SAME id. The custom isEqual should return true. |
| 57 | + instance.objectConfig = {id: 1, data: 'updated'}; |
| 58 | + |
| 59 | + t.is(subscriberCalled, 0, 'Subscriber should NOT be called when id is the same'); |
| 60 | + // The value should NOT have been updated because isEqual returned true |
| 61 | + t.is(instance.objectConfig.data, 'initial', 'Object data should not change when id is the same'); |
| 62 | + |
| 63 | + |
| 64 | + // Set a new object with a DIFFERENT id. The custom isEqual should return false. |
| 65 | + instance.objectConfig = {id: 2, data: 'new object'}; |
| 66 | + |
| 67 | + t.is(subscriberCalled, 1, 'Subscriber should be called when id is different'); |
| 68 | + t.is(instance.objectConfig.data, 'new object', 'Object data should update when id is different'); |
| 69 | + }); |
| 70 | +}); |
0 commit comments