Skip to content

Commit 0294c93

Browse files
committed
Convert config/Basic.mjs Test from Siesta to Playwright #7274
1 parent 191c27f commit 0294c93

3 files changed

Lines changed: 163 additions & 2 deletions

File tree

.github/ISSUE/epic-enhance-workflow-with-mandatory-unit-testing.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ The primary goal is to prevent regressions, especially in the complex core modul
7575
- **Done:** ticket-convert-classsystem-test.md
7676
- **Done:** ticket-convert-collectionbase-test.md
7777
- **Done:** ticket-convert-config-aftersetconfig-test.md
78-
- **To Do:** ticket-convert-config-basic-test.md
78+
- **Done:** ticket-convert-config-basic-test.md
7979
- **To Do:** ticket-convert-config-circulardependencies-test.md
8080
- **To Do:** ticket-convert-config-customfunctions-test.md
8181
- **To Do:** ticket-convert-config-hierarchy-test.md

.github/ISSUE/ticket-convert-config-basic-test.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
GH ticket id: #7274
44

55
**Assignee:**
6-
**Status:** To Do
6+
**Status:** Done
77

88
**Parent Epic:** epic-enhance-workflow-with-mandatory-unit-testing.md
99

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
import { setup } from '../../setup.mjs';
2+
3+
setup();
4+
5+
import { test, expect } from '@playwright/test';
6+
7+
import Neo from '../../../../src/Neo.mjs';
8+
import Base from '../../../../src/core/Base.mjs';
9+
import {isDescriptor} from '../../../../src/core/ConfigSymbols.mjs';
10+
11+
class MyComponent extends Base {
12+
static config = {
13+
className : 'Neo.TestComponent',
14+
myConfig_ : 'initialValue',
15+
arrayConfig_ : {
16+
[isDescriptor]: true,
17+
value : [],
18+
merge : 'replace'
19+
},
20+
objectConfig_: {
21+
[isDescriptor]: true,
22+
value : {},
23+
merge : 'deep'
24+
}
25+
}
26+
27+
afterSetMyConfig(value, oldValue) {
28+
// This will be called by the framework
29+
}
30+
}
31+
32+
MyComponent = Neo.setupClass(MyComponent);
33+
34+
/**
35+
* @summary Tests for basic config reactivity in Neo.core.Base
36+
* This suite tests the fundamental reactivity of configs, including the observeConfig method
37+
* for subscriptions and the behavior of config descriptors for array and object merging.
38+
*/
39+
40+
test.describe('Neo.core.Base#configs-basic', () => {
41+
test('Basic reactivity with subscribe', () => {
42+
const instance = Neo.create(MyComponent);
43+
44+
let subscriberCalled = false;
45+
let receivedNewValue, receivedOldValue;
46+
47+
const cleanup = instance.observeConfig(instance, 'myConfig', (newValue, oldValue) => {
48+
subscriberCalled = true;
49+
receivedNewValue = newValue;
50+
receivedOldValue = oldValue;
51+
});
52+
53+
instance.myConfig = 'newValue';
54+
55+
expect(subscriberCalled).toBe(true);
56+
expect(receivedNewValue).toBe('newValue');
57+
expect(receivedOldValue).toBe('initialValue');
58+
59+
// Test cleanup
60+
subscriberCalled = false;
61+
cleanup();
62+
instance.myConfig = 'anotherValue';
63+
expect(subscriberCalled).toBe(false);
64+
});
65+
66+
test('Descriptor: arrayConfig_ with merge: replace', () => {
67+
const instance = Neo.create(MyComponent);
68+
69+
let subscriberCalled = 0;
70+
instance.observeConfig(instance, 'arrayConfig', (newValue, oldValue) => {
71+
subscriberCalled++;
72+
});
73+
74+
const arr1 = [1, 2, 3];
75+
instance.arrayConfig = arr1;
76+
expect(instance.arrayConfig).toEqual(arr1);
77+
expect(subscriberCalled).toBe(1);
78+
79+
const arr2 = [4, 5, 6];
80+
instance.arrayConfig = arr2;
81+
expect(instance.arrayConfig).toEqual(arr2);
82+
expect(subscriberCalled).toBe(2);
83+
84+
// Setting the same array should not trigger a change by default isEqual
85+
instance.arrayConfig = arr2;
86+
expect(subscriberCalled).toBe(2);
87+
});
88+
89+
test('Descriptor: objectConfig_ with merge: deep', () => {
90+
const instance = Neo.create(MyComponent);
91+
92+
let subscriberCalled = 0;
93+
instance.observeConfig(instance, 'objectConfig', (newValue, oldValue) => {
94+
subscriberCalled++;
95+
});
96+
97+
const obj1 = {a: 1, b: {c: 2}};
98+
instance.objectConfig = obj1;
99+
expect(instance.objectConfig).toEqual(obj1);
100+
expect(subscriberCalled).toBe(1);
101+
102+
// Deep merge should happen, but default isEqual will still compare references
103+
const obj2 = {a: 1, b: {c: 3}};
104+
instance.objectConfig = obj2;
105+
expect(instance.objectConfig.a).toBe(1);
106+
expect(instance.objectConfig.b.c).toBe(3);
107+
expect(subscriberCalled).toBe(2);
108+
109+
// Setting the same object reference should not trigger a change
110+
instance.objectConfig = obj2;
111+
expect(subscriberCalled).toBe(2);
112+
113+
// Modifying a nested property should trigger a change if isEqual is deep
114+
// NOTE: The current Config.mjs uses Neo.isEqual which is a deep comparison.
115+
// If the object reference changes, it will trigger. If the object reference stays the same,
116+
// but content changes, it will not trigger unless isEqual is customized.
117+
// For now, this test relies on the fact that setting a new object reference triggers the change.
118+
const obj3 = {a: 1, b: {c: 2}};
119+
instance.objectConfig = obj3;
120+
expect(subscriberCalled).toBe(3);
121+
});
122+
123+
test('Multiple subscriptions from same owner ID', () => {
124+
const instance = Neo.create(MyComponent);
125+
const publisher = instance; // Observing itself for simplicity
126+
const configName = 'myConfig';
127+
128+
let callback1Called = false;
129+
let callback2Called = false;
130+
131+
const cleanup1 = instance.observeConfig(publisher, configName, (newValue, oldValue) => {
132+
callback1Called = true;
133+
});
134+
135+
const cleanup2 = instance.observeConfig(publisher, configName, (newValue, oldValue) => {
136+
callback2Called = true;
137+
});
138+
139+
// Reset flags
140+
callback1Called = false;
141+
callback2Called = false;
142+
143+
// Change the config value
144+
instance.myConfig = 'changedValue';
145+
146+
expect(callback1Called).toBe(true);
147+
expect(callback2Called).toBe(true);
148+
149+
// Test cleanup
150+
cleanup1();
151+
cleanup2();
152+
153+
callback1Called = false;
154+
callback2Called = false;
155+
156+
instance.myConfig = 'anotherChange';
157+
158+
expect(callback1Called).toBe(false);
159+
expect(callback2Called).toBe(false);
160+
});
161+
});

0 commit comments

Comments
 (0)