@momo-kits/foundation 0.169.4-beta.8 → 0.169.4
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/Application/BottomSheet.tsx +5 -11
- package/Application/ModalScreen.tsx +1 -7
- package/Application/NavigationContainer.tsx +0 -2
- package/Application/StackScreen.tsx +1 -4
- package/Application/__tests__/modalLayout.test.ts +3 -3
- package/Application/modalLayout.ts +2 -2
- package/Popup/PopupNotify.tsx +5 -9
- package/package.json +1 -1
- package/Application/KitAdoption/AdoptionBadge.tsx +0 -119
- package/Application/KitAdoption/AdoptionProbe.tsx +0 -145
- package/Application/KitAdoption/AdoptionStore.ts +0 -80
- package/Application/KitAdoption/constants.ts +0 -104
- package/Application/KitAdoption/index.ts +0 -5
- package/Application/KitAdoption/styles.ts +0 -55
- package/Application/KitAdoption/types.ts +0 -48
- package/Application/KitAdoption/utils.ts +0 -393
- package/Application/__tests__/KitAdoption.integration.test.tsx +0 -235
- package/Application/__tests__/KitAdoption.test.ts +0 -260
- package/Application/__tests__/KitAdoptionStore.test.ts +0 -110
|
@@ -1,260 +0,0 @@
|
|
|
1
|
-
import { createElement, Fragment } from 'react';
|
|
2
|
-
|
|
3
|
-
import { FIBER_TAG, REACT_MEMO_TYPE } from '../KitAdoption/constants';
|
|
4
|
-
import type { FiberLike } from '../KitAdoption/types';
|
|
5
|
-
import {
|
|
6
|
-
createRegistries,
|
|
7
|
-
getCurrentFiber,
|
|
8
|
-
walkScreen,
|
|
9
|
-
} from '../KitAdoption/utils';
|
|
10
|
-
|
|
11
|
-
const STACK = 'dev-stack';
|
|
12
|
-
|
|
13
|
-
const Button = () => null;
|
|
14
|
-
const Card = () => null;
|
|
15
|
-
const Chip = () => null;
|
|
16
|
-
const MyButton = () => null;
|
|
17
|
-
const Plain = () => null;
|
|
18
|
-
const RNView = () => null;
|
|
19
|
-
const Text = () => null;
|
|
20
|
-
const TouchableOpacity = () => null;
|
|
21
|
-
|
|
22
|
-
const makeFiber = (overrides: Partial<FiberLike> = {}): FiberLike => ({
|
|
23
|
-
tag: FIBER_TAG.FunctionComponent,
|
|
24
|
-
type: undefined,
|
|
25
|
-
child: null,
|
|
26
|
-
sibling: null,
|
|
27
|
-
return: null,
|
|
28
|
-
alternate: null,
|
|
29
|
-
memoizedProps: {},
|
|
30
|
-
...overrides,
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
/** Sets children of parent (child, sibling, return links) and returns parent. */
|
|
34
|
-
const link = (parent: FiberLike, children: FiberLike[]): FiberLike => {
|
|
35
|
-
children.forEach((child, index) => {
|
|
36
|
-
child.return = parent;
|
|
37
|
-
child.sibling = children[index + 1] ?? null;
|
|
38
|
-
});
|
|
39
|
-
parent.child = children[0] ?? null;
|
|
40
|
-
return parent;
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
/** Linear chain of plain app fibers, returned from the top. */
|
|
44
|
-
const buildChain = (length: number): FiberLike => {
|
|
45
|
-
let head = makeFiber({ type: Plain });
|
|
46
|
-
for (let i = 1; i < length; i += 1) {
|
|
47
|
-
head = link(makeFiber({ type: Plain }), [head]);
|
|
48
|
-
}
|
|
49
|
-
return head;
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
describe('KitAdoption walkScreen', () => {
|
|
53
|
-
it('counts a kit component once and skips its host-internal fibers', () => {
|
|
54
|
-
const internalView = makeFiber({
|
|
55
|
-
tag: FIBER_TAG.HostComponent,
|
|
56
|
-
type: 'RCTView',
|
|
57
|
-
_debugStack: STACK,
|
|
58
|
-
});
|
|
59
|
-
const button = link(makeFiber({ type: Button }), [internalView]);
|
|
60
|
-
const myButton = link(makeFiber({ type: MyButton }), [button]);
|
|
61
|
-
|
|
62
|
-
const result = walkScreen(
|
|
63
|
-
myButton,
|
|
64
|
-
createRegistries([{ Button }], { View: RNView }),
|
|
65
|
-
);
|
|
66
|
-
|
|
67
|
-
expect(result.counts.K).toBe(1);
|
|
68
|
-
expect(result.counts.R).toBe(0);
|
|
69
|
-
expect(result.kit.Button).toBe(1);
|
|
70
|
-
expect(result.top_transparent).toEqual([{ name: 'MyButton', count: 1 }]);
|
|
71
|
-
expect(result.status).toBe('ok');
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
it('counts a raw RN View written by the app as R', () => {
|
|
75
|
-
const result = walkScreen(
|
|
76
|
-
makeFiber({ type: RNView }),
|
|
77
|
-
createRegistries([{ Button }], { View: RNView }),
|
|
78
|
-
);
|
|
79
|
-
|
|
80
|
-
expect(result.counts.R).toBe(1);
|
|
81
|
-
expect(result.counts.K).toBe(0);
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
it('counts an app Text inside a kit Card as K and ignores the Card host view', () => {
|
|
85
|
-
const cardInternalView = makeFiber({
|
|
86
|
-
tag: FIBER_TAG.HostComponent,
|
|
87
|
-
type: 'RCTView',
|
|
88
|
-
_debugStack: STACK,
|
|
89
|
-
});
|
|
90
|
-
const appText = makeFiber({ type: Text });
|
|
91
|
-
const card = link(makeFiber({ type: Card }), [cardInternalView, appText]);
|
|
92
|
-
|
|
93
|
-
const result = walkScreen(
|
|
94
|
-
card,
|
|
95
|
-
createRegistries([{ Card, Text: Text }], { Text: Text }),
|
|
96
|
-
);
|
|
97
|
-
|
|
98
|
-
expect(result.counts.K).toBe(2);
|
|
99
|
-
expect(result.counts.R).toBe(0);
|
|
100
|
-
expect(result.kit.Card).toBe(1);
|
|
101
|
-
expect(result.kit.Text).toBe(1);
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
it('counts a lib unit once and only the slot children the app passed in', () => {
|
|
105
|
-
const slotElement = createElement(Button, { label: 'slot' });
|
|
106
|
-
const internalButton = makeFiber({ type: Button, memoizedProps: {} });
|
|
107
|
-
const slotFiber = makeFiber({
|
|
108
|
-
type: Button,
|
|
109
|
-
memoizedProps: slotElement.props,
|
|
110
|
-
});
|
|
111
|
-
const chip = link(
|
|
112
|
-
makeFiber({ type: Chip, memoizedProps: { children: slotElement } }),
|
|
113
|
-
[internalButton, slotFiber],
|
|
114
|
-
);
|
|
115
|
-
|
|
116
|
-
const result = walkScreen(chip, createRegistries([{ Button }], {}));
|
|
117
|
-
|
|
118
|
-
expect(result.counts.K).toBe(2);
|
|
119
|
-
expect(result.kit.Chip).toBe(1);
|
|
120
|
-
expect(result.kit.Button).toBe(1);
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
it('treats the children of a Fragment passed into a lib unit as slots', () => {
|
|
124
|
-
const first = createElement(Button, { label: 'first' });
|
|
125
|
-
const second = createElement(Button, { label: 'second' });
|
|
126
|
-
const fragment = createElement(Fragment, null, first, second);
|
|
127
|
-
const chip = link(
|
|
128
|
-
makeFiber({ type: Chip, memoizedProps: { children: fragment } }),
|
|
129
|
-
[
|
|
130
|
-
makeFiber({ type: Button, memoizedProps: {} }),
|
|
131
|
-
makeFiber({ type: Button, memoizedProps: first.props }),
|
|
132
|
-
makeFiber({ type: Button, memoizedProps: second.props }),
|
|
133
|
-
],
|
|
134
|
-
);
|
|
135
|
-
|
|
136
|
-
const result = walkScreen(chip, createRegistries([{ Button }], {}));
|
|
137
|
-
|
|
138
|
-
expect(result.kit.Button).toBe(2);
|
|
139
|
-
expect(result.counts.K).toBe(3);
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
it('does not count the TouchableOpacity re-export as kit', () => {
|
|
143
|
-
const registries = createRegistries([{ TouchableOpacity }], {
|
|
144
|
-
TouchableOpacity,
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
const result = walkScreen(
|
|
148
|
-
makeFiber({ type: TouchableOpacity }),
|
|
149
|
-
registries,
|
|
150
|
-
);
|
|
151
|
-
|
|
152
|
-
expect(result.counts.K).toBe(0);
|
|
153
|
-
expect(result.counts.R).toBe(1);
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
it('reports truncated when the walk exceeds the fiber limit', () => {
|
|
157
|
-
const result = walkScreen(
|
|
158
|
-
buildChain(10),
|
|
159
|
-
createRegistries([], {}),
|
|
160
|
-
undefined,
|
|
161
|
-
5,
|
|
162
|
-
);
|
|
163
|
-
|
|
164
|
-
expect(result.truncated).toBe(true);
|
|
165
|
-
expect(result.status).toBe('truncated');
|
|
166
|
-
expect(result.fibers).toBe(5);
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
it('reports dev_bundle when every fiber carries a dev stack', () => {
|
|
170
|
-
const child = makeFiber({
|
|
171
|
-
tag: FIBER_TAG.HostComponent,
|
|
172
|
-
type: 'RCTView',
|
|
173
|
-
_debugStack: STACK,
|
|
174
|
-
});
|
|
175
|
-
const root = link(
|
|
176
|
-
makeFiber({
|
|
177
|
-
tag: FIBER_TAG.HostComponent,
|
|
178
|
-
type: 'RCTView',
|
|
179
|
-
_debugStack: STACK,
|
|
180
|
-
}),
|
|
181
|
-
[child],
|
|
182
|
-
);
|
|
183
|
-
|
|
184
|
-
const result = walkScreen(root, createRegistries([{ Button }], {}));
|
|
185
|
-
|
|
186
|
-
expect(result.status).toBe('dev_bundle');
|
|
187
|
-
expect(result.counts).toEqual({ K: 0, R: 0, O: 0 });
|
|
188
|
-
expect(result.fibers).toBe(2);
|
|
189
|
-
});
|
|
190
|
-
|
|
191
|
-
it('does not count the inner fiber of a host-created memo as app code', () => {
|
|
192
|
-
const innerView = makeFiber({ type: RNView });
|
|
193
|
-
const hostMemo = link(
|
|
194
|
-
makeFiber({
|
|
195
|
-
tag: FIBER_TAG.MemoComponent,
|
|
196
|
-
type: { $$typeof: REACT_MEMO_TYPE, type: RNView },
|
|
197
|
-
_debugStack: STACK,
|
|
198
|
-
}),
|
|
199
|
-
[innerView],
|
|
200
|
-
);
|
|
201
|
-
const hostKit = link(
|
|
202
|
-
makeFiber({ type: Button, _debugStack: STACK }),
|
|
203
|
-
[hostMemo],
|
|
204
|
-
);
|
|
205
|
-
|
|
206
|
-
const result = walkScreen(
|
|
207
|
-
hostKit,
|
|
208
|
-
createRegistries([{ Button }], { View: RNView }),
|
|
209
|
-
);
|
|
210
|
-
|
|
211
|
-
expect(result.counts.R).toBe(0);
|
|
212
|
-
expect(result.counts.K).toBe(0);
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
it('counts an app-authored memo wrapping a kit component exactly once', () => {
|
|
216
|
-
const innerButton = makeFiber({ type: Button });
|
|
217
|
-
const appMemo = link(
|
|
218
|
-
makeFiber({
|
|
219
|
-
tag: FIBER_TAG.MemoComponent,
|
|
220
|
-
type: { $$typeof: REACT_MEMO_TYPE, type: Button },
|
|
221
|
-
}),
|
|
222
|
-
[innerButton],
|
|
223
|
-
);
|
|
224
|
-
|
|
225
|
-
const result = walkScreen(
|
|
226
|
-
appMemo,
|
|
227
|
-
createRegistries([{ Button }], {}),
|
|
228
|
-
);
|
|
229
|
-
|
|
230
|
-
expect(result.counts.K).toBe(1);
|
|
231
|
-
expect(result.kit.Button).toBe(1);
|
|
232
|
-
});
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
describe('KitAdoption getCurrentFiber', () => {
|
|
236
|
-
it('returns the alternate when the fiber hangs off a stale HostRoot', () => {
|
|
237
|
-
const alternate = makeFiber({ type: Plain });
|
|
238
|
-
const fiber = makeFiber({ type: Plain, alternate });
|
|
239
|
-
const committedRoot = makeFiber({ tag: FIBER_TAG.HostRoot });
|
|
240
|
-
link(
|
|
241
|
-
makeFiber({
|
|
242
|
-
tag: FIBER_TAG.HostRoot,
|
|
243
|
-
stateNode: { current: committedRoot },
|
|
244
|
-
}),
|
|
245
|
-
[fiber],
|
|
246
|
-
);
|
|
247
|
-
|
|
248
|
-
expect(getCurrentFiber(fiber)).toBe(alternate);
|
|
249
|
-
});
|
|
250
|
-
|
|
251
|
-
it('returns the fiber itself when its HostRoot is the committed one', () => {
|
|
252
|
-
const alternate = makeFiber({ type: Plain });
|
|
253
|
-
const fiber = makeFiber({ type: Plain, alternate });
|
|
254
|
-
const hostRoot = makeFiber({ tag: FIBER_TAG.HostRoot });
|
|
255
|
-
link(hostRoot, [fiber]);
|
|
256
|
-
hostRoot.stateNode = { current: hostRoot };
|
|
257
|
-
|
|
258
|
-
expect(getCurrentFiber(fiber)).toBe(fiber);
|
|
259
|
-
});
|
|
260
|
-
});
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import { AdoptionStore } from '../KitAdoption/AdoptionStore';
|
|
2
|
-
import type { ScreenSnapshot } from '../KitAdoption/types';
|
|
3
|
-
|
|
4
|
-
/** Snapshot with the given K/R/O counts for one app and screen. */
|
|
5
|
-
const makeSnapshot = (
|
|
6
|
-
screen: string,
|
|
7
|
-
counts: { K: number; R: number; O: number },
|
|
8
|
-
appId = 'app-1',
|
|
9
|
-
): ScreenSnapshot => ({
|
|
10
|
-
counts,
|
|
11
|
-
kit: {},
|
|
12
|
-
rn: {},
|
|
13
|
-
other: {},
|
|
14
|
-
top_transparent: [],
|
|
15
|
-
fibers: 0,
|
|
16
|
-
truncated: false,
|
|
17
|
-
status: 'ok',
|
|
18
|
-
app_id: appId,
|
|
19
|
-
screen_name: screen,
|
|
20
|
-
platform: 'ios',
|
|
21
|
-
ts: 0,
|
|
22
|
-
walk_ms: 0,
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
describe('AdoptionStore save', () => {
|
|
26
|
-
it('keeps the existing snapshot when it has more nodes', () => {
|
|
27
|
-
const store = new AdoptionStore();
|
|
28
|
-
store.save(makeSnapshot('Home', { K: 3, R: 0, O: 0 }));
|
|
29
|
-
store.save(makeSnapshot('Home', { K: 1, R: 0, O: 0 }));
|
|
30
|
-
|
|
31
|
-
expect(store.getAll()).toHaveLength(1);
|
|
32
|
-
expect(store.getAll()[0].counts.K).toBe(3);
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
it('replaces the existing snapshot when the new one has more nodes', () => {
|
|
36
|
-
const store = new AdoptionStore();
|
|
37
|
-
store.save(makeSnapshot('Home', { K: 1, R: 0, O: 0 }));
|
|
38
|
-
store.save(makeSnapshot('Home', { K: 2, R: 2, O: 1 }));
|
|
39
|
-
|
|
40
|
-
expect(store.getAll()[0].counts).toEqual({ K: 2, R: 2, O: 1 });
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
it('keys snapshots by app and screen', () => {
|
|
44
|
-
const store = new AdoptionStore();
|
|
45
|
-
store.save(makeSnapshot('Home', { K: 1, R: 0, O: 0 }, 'app-1'));
|
|
46
|
-
store.save(makeSnapshot('Home', { K: 1, R: 0, O: 0 }, 'app-2'));
|
|
47
|
-
|
|
48
|
-
expect(store.getAll()).toHaveLength(2);
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
it('getLatest returns the most recently saved screen', () => {
|
|
52
|
-
const store = new AdoptionStore();
|
|
53
|
-
store.save(makeSnapshot('Home', { K: 1, R: 0, O: 0 }));
|
|
54
|
-
store.save(makeSnapshot('Detail', { K: 1, R: 0, O: 0 }));
|
|
55
|
-
|
|
56
|
-
expect(store.getLatest()?.screen_name).toBe('Detail');
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
it('clear empties the store and getLatest', () => {
|
|
60
|
-
const store = new AdoptionStore();
|
|
61
|
-
store.save(makeSnapshot('Home', { K: 1, R: 0, O: 0 }));
|
|
62
|
-
store.clear();
|
|
63
|
-
|
|
64
|
-
expect(store.getAll()).toEqual([]);
|
|
65
|
-
expect(store.getLatest()).toBeUndefined();
|
|
66
|
-
});
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
describe('AdoptionStore subscribe', () => {
|
|
70
|
-
it('notifies listeners on save and stops after unsubscribe', () => {
|
|
71
|
-
const store = new AdoptionStore();
|
|
72
|
-
const listener = jest.fn();
|
|
73
|
-
const unsubscribe = store.subscribe(listener);
|
|
74
|
-
|
|
75
|
-
store.save(makeSnapshot('Home', { K: 1, R: 0, O: 0 }));
|
|
76
|
-
expect(listener).toHaveBeenCalledTimes(1);
|
|
77
|
-
|
|
78
|
-
unsubscribe();
|
|
79
|
-
store.save(makeSnapshot('Detail', { K: 1, R: 0, O: 0 }));
|
|
80
|
-
expect(listener).toHaveBeenCalledTimes(1);
|
|
81
|
-
});
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
describe('AdoptionStore active measurer', () => {
|
|
85
|
-
it('remeasureActive calls the active measurer', () => {
|
|
86
|
-
const store = new AdoptionStore();
|
|
87
|
-
const measure = jest.fn();
|
|
88
|
-
store.setActive(measure);
|
|
89
|
-
|
|
90
|
-
store.remeasureActive();
|
|
91
|
-
|
|
92
|
-
expect(measure).toHaveBeenCalledTimes(1);
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
it('clearActive only clears the measurer that is still active', () => {
|
|
96
|
-
const store = new AdoptionStore();
|
|
97
|
-
const first = jest.fn();
|
|
98
|
-
const second = jest.fn();
|
|
99
|
-
store.setActive(first);
|
|
100
|
-
store.setActive(second);
|
|
101
|
-
|
|
102
|
-
store.clearActive(first);
|
|
103
|
-
store.remeasureActive();
|
|
104
|
-
expect(second).toHaveBeenCalledTimes(1);
|
|
105
|
-
|
|
106
|
-
store.clearActive(second);
|
|
107
|
-
store.remeasureActive();
|
|
108
|
-
expect(second).toHaveBeenCalledTimes(1);
|
|
109
|
-
});
|
|
110
|
-
});
|