Skip to content

Commit 94c3a78

Browse files
committed
test: add os support
1 parent b9dba18 commit 94c3a78

File tree

4 files changed

+171
-2
lines changed

4 files changed

+171
-2
lines changed

app/components/UI/Bridge/Views/BridgeView/BridgeView.integration.test.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@ import { renderIntegrationScreenWithRoutes } from '../../../../../util/test/inte
99
import Routes from '../../../../../constants/navigation/Routes';
1010
import { initialStateBridge } from '../../../../../util/test/integration/presets/bridge';
1111
import BridgeView from './index';
12+
import { describeForPlatforms } from '../../../../../util/test/platform';
1213

13-
describe('BridgeView (integration)', () => {
14+
describeForPlatforms('BridgeView (integration)', () => {
1415
it('renders input areas and hides confirm button without tokens or amount', () => {
1516
const { getByTestId, queryByTestId } = renderBridgeView({
1617
overrides: {

app/util/test/integration/README.md

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Integration Test Framework
1+
# Component View Test Framework
22

33
This folder contains a lightweight integration testing framework with the following goals:
44

@@ -7,6 +7,33 @@ This folder contains a lightweight integration testing framework with the follow
77
- Provide view-specific presets and render helpers for concise, declarative tests
88
- Avoid mocking hooks or selectors – the UI should consume Redux state naturally
99

10+
## Platform Matrix (iOS / Android)
11+
12+
- By default, you can execute tests for both platforms using the platform helpers.
13+
- Import helpers and define tests parameterized by platform:
14+
15+
```ts
16+
import { itForPlatforms, describeForPlatforms } from '../../platform';
17+
import { renderBridgeView } from './renderers/bridge';
18+
19+
describeForPlatforms('BridgeView', ({ os }) => {
20+
itForPlatforms('renders BridgeView', () => {
21+
const { getByTestId } = renderBridgeView({ deterministicFiat: true });
22+
// Platform-specific assertions if needed
23+
// if (os === 'ios') { ... } else { ... }
24+
});
25+
});
26+
```
27+
28+
- To filter globally, use `TEST_OS`:
29+
- `TEST_OS=ios yarn jest <path>`
30+
- `TEST_OS=android yarn jest <path>`
31+
- Without `TEST_OS`, both `ios` and `android` run.
32+
33+
- To filter per test:
34+
- `itForPlatforms('name', fn, { only: 'ios' })`
35+
- `itForPlatforms('name', fn, { skip: ['android'] })`
36+
1037
## Principles
1138

1239
- Single Engine mock: `app/util/test/integration/mocks.ts`

app/util/test/integration/stateFixture.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,20 @@ export function createStateFixture(options?: {
275275
},
276276
},
277277
},
278+
bridgeConfigV2: {
279+
minimumVersion: '0.0.0',
280+
maxRefreshCount: 5,
281+
refreshRate: 30000,
282+
support: true,
283+
chains: {
284+
// enable mainnet as src/dest
285+
[`eip155:${parseInt(chainIdHex, 16)}`]: {
286+
isActiveSrc: true,
287+
isActiveDest: true,
288+
isGaslessSwapEnabled: false,
289+
},
290+
},
291+
},
278292
},
279293
},
280294
CurrencyRateController: {

app/util/test/platform.ts

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
import { Platform } from 'react-native';
2+
3+
export type RNPlatform = 'ios' | 'android';
4+
5+
type PlatformFilter =
6+
| RNPlatform
7+
| RNPlatform[]
8+
| { only?: RNPlatform | RNPlatform[]; skip?: RNPlatform[] };
9+
10+
const SCOPE_KEY = '__MM_TEST_PLATFORM_SCOPE__';
11+
12+
function normalizeArray<T>(value: T | T[] | undefined): T[] {
13+
if (!value) {
14+
return [];
15+
}
16+
return Array.isArray(value) ? value : [value];
17+
}
18+
19+
function getDefaultPlatforms(): RNPlatform[] {
20+
const scoped = (globalThis as Record<string, unknown>)[SCOPE_KEY] as
21+
| RNPlatform
22+
| undefined;
23+
if (scoped === 'ios' || scoped === 'android') {
24+
return [scoped];
25+
}
26+
const env = (process.env.TEST_OS ?? '').toLowerCase();
27+
if (env === 'ios' || env === 'android') {
28+
return [env as RNPlatform];
29+
}
30+
return ['ios', 'android'];
31+
}
32+
33+
function resolveTargetPlatforms(filter?: PlatformFilter): RNPlatform[] {
34+
const defaultTargets = getDefaultPlatforms();
35+
36+
if (!filter) {
37+
return defaultTargets;
38+
}
39+
40+
if (typeof filter === 'string' || Array.isArray(filter)) {
41+
const only = normalizeArray(filter) as RNPlatform[];
42+
return only.length ? only : defaultTargets;
43+
}
44+
45+
const only = normalizeArray(filter.only) as RNPlatform[];
46+
const skip = new Set(normalizeArray(filter.skip) as RNPlatform[]);
47+
48+
const base = (only.length ? only : defaultTargets) as RNPlatform[];
49+
return base.filter((p) => !skip.has(p));
50+
}
51+
52+
/**
53+
* Runs a test body for each targeted platform, defaulting to both iOS and Android.
54+
* Use TEST_OS=ios|android to globally filter, or the filter parameter to narrow per test.
55+
*/
56+
export function itForPlatforms(
57+
name: string,
58+
testFn: (ctx: { os: RNPlatform }) => void | Promise<void>,
59+
filter?: PlatformFilter,
60+
) {
61+
const targets = resolveTargetPlatforms(filter);
62+
for (const os of targets) {
63+
it(`${name} [${os}]`, async () => {
64+
const originalOS = Platform.OS;
65+
Platform.OS = os;
66+
try {
67+
await testFn({ os });
68+
} finally {
69+
Platform.OS = originalOS;
70+
}
71+
});
72+
}
73+
}
74+
75+
/**
76+
* Same as itForPlatforms but focused (runs only these tests).
77+
*/
78+
export function itOnlyForPlatforms(
79+
name: string,
80+
testFn: (ctx: { os: RNPlatform }) => void | Promise<void>,
81+
filter?: PlatformFilter,
82+
) {
83+
const targets = resolveTargetPlatforms(filter);
84+
for (const os of targets) {
85+
it.only(`${name} [${os}]`, async () => {
86+
const originalOS = Platform.OS;
87+
Platform.OS = os;
88+
try {
89+
await testFn({ os });
90+
} finally {
91+
Platform.OS = originalOS;
92+
}
93+
});
94+
}
95+
}
96+
97+
/**
98+
* Group tests under a describe for each targeted platform.
99+
*/
100+
export function describeForPlatforms(
101+
name: string,
102+
define: (ctx: { os: RNPlatform }) => void,
103+
filter?: PlatformFilter,
104+
) {
105+
const targets = resolveTargetPlatforms(filter);
106+
for (const os of targets) {
107+
describe(`${name} [${os}]`, () => {
108+
const originalOS = Platform.OS;
109+
beforeAll(() => {
110+
Platform.OS = os;
111+
(globalThis as Record<string, unknown>)[SCOPE_KEY] = os;
112+
});
113+
afterAll(() => {
114+
Platform.OS = originalOS;
115+
delete (globalThis as Record<string, unknown>)[SCOPE_KEY];
116+
});
117+
define({ os });
118+
});
119+
}
120+
}
121+
122+
/**
123+
* Utility to compute target platforms if you need custom loops.
124+
*/
125+
export function getTargetPlatforms(filter?: PlatformFilter): RNPlatform[] {
126+
return resolveTargetPlatforms(filter);
127+
}

0 commit comments

Comments
 (0)