@blac/react 2.0.0-rc-14 → 2.0.0-rc.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.
- package/dist/.tsbuildinfo +1 -0
- package/dist/index.cjs +13 -0
- package/dist/index.d.ts +4 -58
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js.map +1 -0
- package/dist/useBloc.d.ts +20 -0
- package/dist/useBloc.d.ts.map +1 -0
- package/dist/useBloc.js +175 -0
- package/dist/useBloc.js.map +1 -0
- package/dist/useExternalBlocStore.d.ts +31 -0
- package/dist/useExternalBlocStore.d.ts.map +1 -0
- package/dist/useExternalBlocStore.js +93 -0
- package/dist/useExternalBlocStore.js.map +1 -0
- package/package.json +24 -14
- package/dist/index.cjs.js +0 -3
- package/dist/index.cjs.js.map +0 -1
- package/dist/index.es.js +0 -140
- package/dist/index.es.js.map +0 -1
- package/src/__tests__/rerenderLogging.test.tsx +0 -257
- package/src/__tests__/useBloc.disposal.test.tsx +0 -377
- package/src/__tests__/useBloc.instanceChange.test.tsx +0 -200
- package/src/__tests__/useBloc.props.test.tsx +0 -435
- package/src/__tests__/useBloc.proxyConfig.test.tsx +0 -228
- package/src/__tests__/useBloc.staticProps.test.tsx +0 -297
- package/src/__tests__/useBloc.tracking.test.tsx +0 -202
- package/src/index.ts +0 -3
- package/src/useBloc.ts +0 -227
- package/src/useExternalBlocStore.ts +0 -145
|
@@ -1,297 +0,0 @@
|
|
|
1
|
-
import { Blac, Cubit } from '@blac/core';
|
|
2
|
-
import { renderHook } from '@testing-library/react';
|
|
3
|
-
import { describe, expect, it, vi, beforeEach } from 'vitest';
|
|
4
|
-
import useBloc from '../useBloc';
|
|
5
|
-
|
|
6
|
-
// Test components
|
|
7
|
-
interface UserDetailsProps {
|
|
8
|
-
userId: string;
|
|
9
|
-
page: number;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
interface UserDetailsState {
|
|
13
|
-
user: { id: string; name: string } | null;
|
|
14
|
-
loading: boolean;
|
|
15
|
-
page: number;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
class UserDetailsCubit extends Cubit<UserDetailsState> {
|
|
19
|
-
props: ConstructorParameters<typeof UserDetailsCubit>[0];
|
|
20
|
-
|
|
21
|
-
constructor(props: UserDetailsProps) {
|
|
22
|
-
super({ user: null, loading: false, page: props.page });
|
|
23
|
-
this.props = props;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
loadUser = () => {
|
|
27
|
-
this.emit({ ...this.state, loading: true });
|
|
28
|
-
// Simulate API call
|
|
29
|
-
setTimeout(() => {
|
|
30
|
-
this.emit({
|
|
31
|
-
...this.state,
|
|
32
|
-
user: { id: this.props!.userId, name: `User ${this.props!.userId}` },
|
|
33
|
-
loading: false,
|
|
34
|
-
});
|
|
35
|
-
}, 10);
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
interface SearchProps {
|
|
40
|
-
query: string;
|
|
41
|
-
filters?: { category?: string; minPrice?: number; tags?: string[] };
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
interface SearchState {
|
|
45
|
-
results: string[];
|
|
46
|
-
loading: boolean;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
class SearchCubit extends Cubit<SearchState> {
|
|
50
|
-
constructor(props: SearchProps) {
|
|
51
|
-
super({ results: [], loading: false });
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
describe('useBloc staticProps integration', () => {
|
|
56
|
-
beforeEach(() => {
|
|
57
|
-
Blac.resetInstance();
|
|
58
|
-
vi.clearAllMocks();
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
describe('staticProps with instanceId', () => {
|
|
62
|
-
it('should use explicit instanceId when provided with staticProps', () => {
|
|
63
|
-
const { result: result1 } = renderHook(() =>
|
|
64
|
-
useBloc(UserDetailsCubit, {
|
|
65
|
-
staticProps: { userId: 'user123', page: 1 },
|
|
66
|
-
instanceId: 'user123',
|
|
67
|
-
}),
|
|
68
|
-
);
|
|
69
|
-
|
|
70
|
-
const { result: result2 } = renderHook(() =>
|
|
71
|
-
useBloc(UserDetailsCubit, {
|
|
72
|
-
staticProps: { userId: 'user123', page: 2 }, // Different page
|
|
73
|
-
instanceId: 'user123', // Same instanceId
|
|
74
|
-
}),
|
|
75
|
-
);
|
|
76
|
-
|
|
77
|
-
// Both should have the same instanceId
|
|
78
|
-
expect(result1.current[1]._id).toBe('user123');
|
|
79
|
-
expect(result2.current[1]._id).toBe('user123');
|
|
80
|
-
|
|
81
|
-
// Note: In React Testing Library, each renderHook creates a separate component tree,
|
|
82
|
-
// so they won't share the same instance. In a real app, they would.
|
|
83
|
-
expect(result1.current[1]._id).toBe(result2.current[1]._id);
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
it('should create different instances with different instanceIds', () => {
|
|
87
|
-
const { result: result1 } = renderHook(() =>
|
|
88
|
-
useBloc(UserDetailsCubit, {
|
|
89
|
-
staticProps: { userId: 'user123', page: 1 },
|
|
90
|
-
instanceId: 'user123',
|
|
91
|
-
}),
|
|
92
|
-
);
|
|
93
|
-
|
|
94
|
-
const { result: result2 } = renderHook(() =>
|
|
95
|
-
useBloc(UserDetailsCubit, {
|
|
96
|
-
staticProps: { userId: 'user456', page: 1 },
|
|
97
|
-
instanceId: 'user456',
|
|
98
|
-
}),
|
|
99
|
-
);
|
|
100
|
-
|
|
101
|
-
// Should have different IDs
|
|
102
|
-
expect(result1.current[1]._id).toBe('user123');
|
|
103
|
-
expect(result2.current[1]._id).toBe('user456');
|
|
104
|
-
expect(result1.current[1]._id).not.toBe(result2.current[1]._id);
|
|
105
|
-
});
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
describe('staticProps without instanceId (auto-generation)', () => {
|
|
109
|
-
it('should generate instanceId from primitive staticProps values', () => {
|
|
110
|
-
const { result: result1 } = renderHook(() =>
|
|
111
|
-
useBloc(SearchCubit, {
|
|
112
|
-
staticProps: { query: 'test', filters: { category: 'books' } },
|
|
113
|
-
}),
|
|
114
|
-
);
|
|
115
|
-
|
|
116
|
-
const { result: result2 } = renderHook(() =>
|
|
117
|
-
useBloc(SearchCubit, {
|
|
118
|
-
staticProps: { query: 'test', filters: { category: 'movies' } },
|
|
119
|
-
}),
|
|
120
|
-
);
|
|
121
|
-
|
|
122
|
-
// Should have generated ID from the query primitive
|
|
123
|
-
expect(result1.current[1]._id).toBe('query:test');
|
|
124
|
-
expect(result2.current[1]._id).toBe('query:test');
|
|
125
|
-
|
|
126
|
-
// They have the same generated ID
|
|
127
|
-
expect(result1.current[1]._id).toBe(result2.current[1]._id);
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
it('should create different instances for different primitive values', () => {
|
|
131
|
-
const { result: result1 } = renderHook(() =>
|
|
132
|
-
useBloc(SearchCubit, {
|
|
133
|
-
staticProps: { query: 'test1' },
|
|
134
|
-
}),
|
|
135
|
-
);
|
|
136
|
-
|
|
137
|
-
const { result: result2 } = renderHook(() =>
|
|
138
|
-
useBloc(SearchCubit, {
|
|
139
|
-
staticProps: { query: 'test2' },
|
|
140
|
-
}),
|
|
141
|
-
);
|
|
142
|
-
|
|
143
|
-
// Should have different generated IDs
|
|
144
|
-
expect(result1.current[1]._id).toBe('query:test1');
|
|
145
|
-
expect(result2.current[1]._id).toBe('query:test2');
|
|
146
|
-
expect(result1.current[1]._id).not.toBe(result2.current[1]._id);
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
it('should ignore non-primitive values when generating instanceId', () => {
|
|
150
|
-
const filters = { category: 'books', tags: ['fiction', 'bestseller'] };
|
|
151
|
-
|
|
152
|
-
const { result: result1 } = renderHook(() =>
|
|
153
|
-
useBloc(SearchCubit, {
|
|
154
|
-
staticProps: { query: 'test', filters }, // filters has an array
|
|
155
|
-
}),
|
|
156
|
-
);
|
|
157
|
-
|
|
158
|
-
const { result: result2 } = renderHook(() =>
|
|
159
|
-
useBloc(SearchCubit, {
|
|
160
|
-
staticProps: {
|
|
161
|
-
query: 'test',
|
|
162
|
-
filters: { ...filters, tags: ['different'] },
|
|
163
|
-
},
|
|
164
|
-
}),
|
|
165
|
-
);
|
|
166
|
-
|
|
167
|
-
// Both should generate the same ID (only 'query' is used)
|
|
168
|
-
expect(result1.current[1]._id).toBe('query:test');
|
|
169
|
-
expect(result2.current[1]._id).toBe('query:test');
|
|
170
|
-
});
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
describe('InstanceId usage', () => {
|
|
174
|
-
it('should use instanceId option', () => {
|
|
175
|
-
const { result } = renderHook(() =>
|
|
176
|
-
useBloc(UserDetailsCubit, {
|
|
177
|
-
staticProps: { userId: 'user123', page: 1 },
|
|
178
|
-
instanceId: 'custom-id',
|
|
179
|
-
}),
|
|
180
|
-
);
|
|
181
|
-
|
|
182
|
-
expect(result.current[1]._id).toBe('custom-id');
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
it('should use instanceId option with static props', () => {
|
|
186
|
-
const { result } = renderHook(() =>
|
|
187
|
-
useBloc(UserDetailsCubit, {
|
|
188
|
-
staticProps: { userId: 'user123', page: 1 },
|
|
189
|
-
instanceId: 'user123',
|
|
190
|
-
}),
|
|
191
|
-
);
|
|
192
|
-
|
|
193
|
-
const [state, bloc] = result.current;
|
|
194
|
-
expect(state.page).toBe(1);
|
|
195
|
-
expect(bloc).toBeDefined();
|
|
196
|
-
expect(bloc._id).toBe('user123');
|
|
197
|
-
});
|
|
198
|
-
|
|
199
|
-
it('should use explicit instanceId when provided', () => {
|
|
200
|
-
const { result } = renderHook(() =>
|
|
201
|
-
useBloc(UserDetailsCubit, {
|
|
202
|
-
staticProps: { userId: 'new', page: 2 },
|
|
203
|
-
instanceId: 'new-id',
|
|
204
|
-
}),
|
|
205
|
-
);
|
|
206
|
-
|
|
207
|
-
// Should use the instanceId
|
|
208
|
-
expect(result.current[1]._id).toBe('new-id');
|
|
209
|
-
|
|
210
|
-
// Should use staticProps
|
|
211
|
-
expect(result.current[1].props).toEqual({ userId: 'new', page: 2 });
|
|
212
|
-
});
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
describe('Complex scenarios', () => {
|
|
216
|
-
it('should handle mixed primitive types in staticProps', () => {
|
|
217
|
-
interface ConfigProps {
|
|
218
|
-
enabled: boolean;
|
|
219
|
-
maxRetries: number;
|
|
220
|
-
apiKey: string;
|
|
221
|
-
debugInfo?: { level: string };
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
class ConfigCubit extends Cubit<{ config: ConfigProps | null }> {
|
|
225
|
-
constructor(props: ConfigProps) {
|
|
226
|
-
super({ config: props });
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
const { result: result1 } = renderHook(() =>
|
|
231
|
-
useBloc(ConfigCubit, {
|
|
232
|
-
staticProps: {
|
|
233
|
-
enabled: true,
|
|
234
|
-
maxRetries: 3,
|
|
235
|
-
apiKey: 'abc123',
|
|
236
|
-
debugInfo: { level: 'verbose' }, // This should be ignored
|
|
237
|
-
},
|
|
238
|
-
}),
|
|
239
|
-
);
|
|
240
|
-
|
|
241
|
-
const { result: result2 } = renderHook(() =>
|
|
242
|
-
useBloc(ConfigCubit, {
|
|
243
|
-
staticProps: {
|
|
244
|
-
enabled: true,
|
|
245
|
-
maxRetries: 3,
|
|
246
|
-
apiKey: 'abc123',
|
|
247
|
-
debugInfo: { level: 'quiet' }, // Different object, but should still match
|
|
248
|
-
},
|
|
249
|
-
}),
|
|
250
|
-
);
|
|
251
|
-
|
|
252
|
-
// Should generate the same ID from primitives
|
|
253
|
-
const expectedId = 'apiKey:abc123|enabled:true|maxRetries:3';
|
|
254
|
-
expect(result1.current[1]._id).toBe(expectedId);
|
|
255
|
-
expect(result2.current[1]._id).toBe(expectedId);
|
|
256
|
-
});
|
|
257
|
-
|
|
258
|
-
it('should handle null and undefined in staticProps', () => {
|
|
259
|
-
interface OptionalProps {
|
|
260
|
-
required: string;
|
|
261
|
-
optional?: string;
|
|
262
|
-
nullable: string | null;
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
class OptionalCubit extends Cubit<{ data: any }> {
|
|
266
|
-
constructor(props: OptionalProps) {
|
|
267
|
-
super({ data: props });
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
const { result: result1 } = renderHook(() =>
|
|
272
|
-
useBloc(OptionalCubit, {
|
|
273
|
-
staticProps: {
|
|
274
|
-
required: 'test',
|
|
275
|
-
optional: undefined,
|
|
276
|
-
nullable: null,
|
|
277
|
-
},
|
|
278
|
-
}),
|
|
279
|
-
);
|
|
280
|
-
|
|
281
|
-
const { result: result2 } = renderHook(() =>
|
|
282
|
-
useBloc(OptionalCubit, {
|
|
283
|
-
staticProps: {
|
|
284
|
-
required: 'test',
|
|
285
|
-
optional: undefined,
|
|
286
|
-
nullable: null,
|
|
287
|
-
},
|
|
288
|
-
}),
|
|
289
|
-
);
|
|
290
|
-
|
|
291
|
-
// Should generate the same ID including null/undefined
|
|
292
|
-
const expectedId = 'nullable:null|optional:undefined|required:test';
|
|
293
|
-
expect(result1.current[1]._id).toBe(expectedId);
|
|
294
|
-
expect(result2.current[1]._id).toBe(expectedId);
|
|
295
|
-
});
|
|
296
|
-
});
|
|
297
|
-
});
|
|
@@ -1,202 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi } from 'vitest';
|
|
2
|
-
import { renderHook, act } from '@testing-library/react';
|
|
3
|
-
import { Cubit, Blac } from '@blac/core';
|
|
4
|
-
import useBloc from '../useBloc';
|
|
5
|
-
|
|
6
|
-
interface TestState {
|
|
7
|
-
count: number;
|
|
8
|
-
name: string;
|
|
9
|
-
unused: string;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
class TestCubit extends Cubit<TestState> {
|
|
13
|
-
static isolated = true; // Make it isolated to avoid test interference
|
|
14
|
-
|
|
15
|
-
constructor() {
|
|
16
|
-
super({ count: 0, name: 'Alice', unused: 'not-used' });
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
increment = () => {
|
|
20
|
-
this.emit({ ...this.state, count: this.state.count + 1 });
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
changeName = (name: string) => {
|
|
24
|
-
this.emit({ ...this.state, name });
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
changeUnused = (value: string) => {
|
|
28
|
-
this.emit({ ...this.state, unused: value });
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
describe('useBloc dependency tracking', () => {
|
|
33
|
-
it('should only track properties accessed during current render', () => {
|
|
34
|
-
let renderCount = 0;
|
|
35
|
-
let accessedProperties: string[] = [];
|
|
36
|
-
|
|
37
|
-
const { result, rerender } = renderHook(() => {
|
|
38
|
-
const [state, cubit] = useBloc(TestCubit);
|
|
39
|
-
renderCount++;
|
|
40
|
-
|
|
41
|
-
// Reset tracked properties for this render
|
|
42
|
-
accessedProperties = [];
|
|
43
|
-
|
|
44
|
-
// First few renders: access both count and name
|
|
45
|
-
if (renderCount <= 2) {
|
|
46
|
-
// Access count and name
|
|
47
|
-
void state.count;
|
|
48
|
-
void state.name;
|
|
49
|
-
accessedProperties = ['count', 'name'];
|
|
50
|
-
} else {
|
|
51
|
-
// Later renders: only access count
|
|
52
|
-
void state.count;
|
|
53
|
-
accessedProperties = ['count'];
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
return { state, cubit, accessedProperties };
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
// Initial render - accessing count and name
|
|
60
|
-
expect(renderCount).toBe(1);
|
|
61
|
-
expect(result.current.accessedProperties).toEqual(['count', 'name']);
|
|
62
|
-
|
|
63
|
-
// Change name - should trigger re-render since we're tracking it
|
|
64
|
-
act(() => {
|
|
65
|
-
result.current.cubit.changeName('Bob');
|
|
66
|
-
});
|
|
67
|
-
expect(renderCount).toBe(2);
|
|
68
|
-
expect(result.current.state.name).toBe('Bob');
|
|
69
|
-
|
|
70
|
-
// Force a re-render (this will be render #3, where we stop accessing name)
|
|
71
|
-
rerender();
|
|
72
|
-
expect(renderCount).toBe(3);
|
|
73
|
-
expect(result.current.accessedProperties).toEqual(['count']); // Only accessing count now
|
|
74
|
-
|
|
75
|
-
// Change name again - should NOT trigger re-render since we're no longer tracking it
|
|
76
|
-
const prevRenderCount = renderCount;
|
|
77
|
-
act(() => {
|
|
78
|
-
result.current.cubit.changeName('Charlie');
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
// Render count should not increase
|
|
82
|
-
expect(renderCount).toBe(prevRenderCount);
|
|
83
|
-
// But state should still be updated if we check it
|
|
84
|
-
expect(result.current.cubit.state.name).toBe('Charlie');
|
|
85
|
-
|
|
86
|
-
// Change count - should trigger re-render since we're still tracking it
|
|
87
|
-
act(() => {
|
|
88
|
-
result.current.cubit.increment();
|
|
89
|
-
});
|
|
90
|
-
expect(renderCount).toBe(prevRenderCount + 1);
|
|
91
|
-
expect(result.current.state.count).toBe(1);
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
it('should not re-render when non-accessed properties change', () => {
|
|
95
|
-
let renderCount = 0;
|
|
96
|
-
|
|
97
|
-
const { result } = renderHook(() => {
|
|
98
|
-
const [state, cubit] = useBloc(TestCubit);
|
|
99
|
-
renderCount++;
|
|
100
|
-
|
|
101
|
-
// Only access count, never access unused
|
|
102
|
-
void state.count;
|
|
103
|
-
|
|
104
|
-
return { state, cubit };
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
expect(renderCount).toBe(1);
|
|
108
|
-
|
|
109
|
-
// Change unused property - should NOT trigger re-render
|
|
110
|
-
act(() => {
|
|
111
|
-
result.current.cubit.changeUnused('changed');
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
// Should not re-render
|
|
115
|
-
expect(renderCount).toBe(1);
|
|
116
|
-
|
|
117
|
-
// The component shouldn't re-render, so we can't check the state through result.current
|
|
118
|
-
// This is the expected behavior - component doesn't see changes to untracked properties
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
it('should track nested property access correctly', () => {
|
|
122
|
-
interface NestedState {
|
|
123
|
-
user: {
|
|
124
|
-
profile: {
|
|
125
|
-
name: string;
|
|
126
|
-
age: number;
|
|
127
|
-
};
|
|
128
|
-
};
|
|
129
|
-
settings: {
|
|
130
|
-
theme: string;
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
class NestedCubit extends Cubit<NestedState> {
|
|
135
|
-
static isolated = true;
|
|
136
|
-
|
|
137
|
-
constructor() {
|
|
138
|
-
super({
|
|
139
|
-
user: {
|
|
140
|
-
profile: {
|
|
141
|
-
name: 'Alice',
|
|
142
|
-
age: 25,
|
|
143
|
-
},
|
|
144
|
-
},
|
|
145
|
-
settings: {
|
|
146
|
-
theme: 'light',
|
|
147
|
-
},
|
|
148
|
-
});
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
updateName = (name: string) => {
|
|
152
|
-
this.emit({
|
|
153
|
-
...this.state,
|
|
154
|
-
user: {
|
|
155
|
-
...this.state.user,
|
|
156
|
-
profile: {
|
|
157
|
-
...this.state.user.profile,
|
|
158
|
-
name,
|
|
159
|
-
},
|
|
160
|
-
},
|
|
161
|
-
});
|
|
162
|
-
};
|
|
163
|
-
|
|
164
|
-
updateTheme = (theme: string) => {
|
|
165
|
-
this.emit({
|
|
166
|
-
...this.state,
|
|
167
|
-
settings: {
|
|
168
|
-
...this.state.settings,
|
|
169
|
-
theme,
|
|
170
|
-
},
|
|
171
|
-
});
|
|
172
|
-
};
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
let renderCount = 0;
|
|
176
|
-
|
|
177
|
-
const { result } = renderHook(() => {
|
|
178
|
-
const [state, cubit] = useBloc(NestedCubit);
|
|
179
|
-
renderCount++;
|
|
180
|
-
|
|
181
|
-
// Only access user.profile.name
|
|
182
|
-
void state.user.profile.name;
|
|
183
|
-
|
|
184
|
-
return { state, cubit };
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
expect(renderCount).toBe(1);
|
|
188
|
-
|
|
189
|
-
// Change theme - should NOT trigger re-render
|
|
190
|
-
act(() => {
|
|
191
|
-
result.current.cubit.updateTheme('dark');
|
|
192
|
-
});
|
|
193
|
-
expect(renderCount).toBe(1);
|
|
194
|
-
|
|
195
|
-
// Change name - should trigger re-render
|
|
196
|
-
act(() => {
|
|
197
|
-
result.current.cubit.updateName('Bob');
|
|
198
|
-
});
|
|
199
|
-
expect(renderCount).toBe(2);
|
|
200
|
-
expect(result.current.state.user.profile.name).toBe('Bob');
|
|
201
|
-
});
|
|
202
|
-
});
|
package/src/index.ts
DELETED