Skip to content

Commit 723c8e2

Browse files
docs: basic cookbook docs and app (#1622)
* docs: basic cookbook docs and app * chore: add tests * chore: enable example apps * chore: fix typecheck * chore: add lint & fix issues * docs: tweaks * docs: tweaks * docs: tweaks * chore: tweaks
1 parent e418b6b commit 723c8e2

28 files changed

+11012
-1
lines changed

.github/workflows/example-apps.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ jobs:
1010
test-example:
1111
strategy:
1212
matrix:
13-
example: [basic]
13+
example: [basic, cookbook]
1414

1515
name: Test Example
1616
runs-on: ubuntu-latest

examples/cookbook/.eslintignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
test-utils.*

examples/cookbook/.eslintrc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"extends": "@callstack"
3+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"12bb71342c6255bbf50437ec8f4441c083f47cdb74bd89160c15e4f43e52a1cb": true,
3+
"40b842e832070c58deac6aa9e08fa459302ee3f9da492c7e77d93d2fbf4a56fd": true
4+
}

examples/cookbook/.gitignore

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# General Node.js
2+
node_modules/
3+
.expo/
4+
dist/
5+
npm-debug.*
6+
*.jks
7+
*.p8
8+
*.p12
9+
*.key
10+
*.mobileprovision
11+
*.orig.*
12+
web-build/
13+
14+
# Yarn 4.x
15+
.pnp.*
16+
.yarn/*
17+
!.yarn/patches
18+
!.yarn/plugins
19+
!.yarn/releases
20+
!.yarn/sdks
21+
!.yarn/versions
22+
23+
# macOS
24+
.DS_Store
25+

examples/cookbook/App.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import * as React from 'react';
2+
import { View } from 'react-native';
3+
4+
const App = () => {
5+
return <View />;
6+
};
7+
8+
export default App;

examples/cookbook/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# RNTL Cookbook
2+
3+
This example app gathers recipes from the [RNTL Cookbook](https://callstack.github.io/react-native-testing-library/cookbook).
4+
5+
Each recipe described in the Cookbook should have a corresponding code example in this repo.
6+
7+
Note:
8+
Since examples will showcase usage of different dependencies, the dependencies in `package.json` fill will grow much larger that in an normal React Native. This is fine 🐶☕️🔥.

examples/cookbook/app.json

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"expo": {
3+
"name": "RNTL Cookbook App",
4+
"slug": "rntl-cookbook",
5+
"version": "1.0.0",
6+
"orientation": "portrait",
7+
"icon": "./assets/icon.png",
8+
"userInterfaceStyle": "light",
9+
"splash": {
10+
"image": "./assets/splash.png",
11+
"resizeMode": "contain",
12+
"backgroundColor": "#ffffff"
13+
},
14+
"updates": {
15+
"fallbackToCacheTimeout": 0
16+
},
17+
"assetBundlePatterns": ["**/*"],
18+
"ios": {
19+
"supportsTablet": true
20+
},
21+
"android": {
22+
"adaptiveIcon": {
23+
"foregroundImage": "./assets/adaptive-icon.png",
24+
"backgroundColor": "#FFFFFF"
25+
}
26+
},
27+
"web": {
28+
"favicon": "./assets/favicon.png"
29+
}
30+
}
31+
}
17.1 KB
Loading

examples/cookbook/assets/favicon.png

1.43 KB
Loading

examples/cookbook/assets/icon.png

21.9 KB
Loading

examples/cookbook/assets/splash.png

46.2 KB
Loading

examples/cookbook/babel.config.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
module.exports = function (api) {
2+
api.cache(true);
3+
return {
4+
presets: ['babel-preset-expo'],
5+
};
6+
};
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import * as React from 'react';
2+
import { screen } from '@testing-library/react-native';
3+
import { renderWithProviders } from './test-utils';
4+
import { WelcomeScreen } from './WelcomeScreen';
5+
6+
test('renders WelcomeScreen in light theme', () => {
7+
renderWithProviders(<WelcomeScreen />, { theme: 'light' });
8+
expect(screen.getByText('Theme: light')).toBeOnTheScreen();
9+
});
10+
11+
test('renders WelcomeScreen in dark theme', () => {
12+
renderWithProviders(<WelcomeScreen />, { theme: 'dark' });
13+
expect(screen.getByText('Theme: dark')).toBeOnTheScreen();
14+
});
15+
16+
test('renders WelcomeScreen with user', () => {
17+
renderWithProviders(<WelcomeScreen />, { user: { name: 'Jar-Jar' } });
18+
expect(screen.getByText(/hello Jar-Jar/i)).toBeOnTheScreen();
19+
});
20+
21+
test('renders WelcomeScreen without user', () => {
22+
renderWithProviders(<WelcomeScreen />, { user: null });
23+
expect(screen.getByText(/hello stranger/i)).toBeOnTheScreen();
24+
});
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import * as React from 'react';
2+
import { View, Text } from 'react-native';
3+
import { useUser } from './providers/user-provider';
4+
import { useTheme } from './providers/theme-provider';
5+
6+
export function WelcomeScreen() {
7+
const theme = useTheme();
8+
const user = useUser();
9+
10+
return (
11+
<View>
12+
<Text>Hello {user ? user.name : 'Stranger'}</Text>
13+
<Text>Theme: {theme}</Text>
14+
</View>
15+
);
16+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import * as React from 'react';
2+
3+
export type Theme = 'light' | 'dark';
4+
export const ThemeProvider = React.createContext<Theme | undefined>(undefined);
5+
6+
export function useTheme() {
7+
const theme = React.useContext(ThemeProvider);
8+
if (theme === undefined) {
9+
throw new Error('useTheme must be used within a ThemeProvider');
10+
}
11+
12+
return theme;
13+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import * as React from 'react';
2+
3+
export type User = { name: string };
4+
export const UserProvider = React.createContext<User | null>(null);
5+
6+
export function useUser() {
7+
return React.useContext(UserProvider);
8+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import * as React from 'react';
2+
import { render } from '@testing-library/react-native';
3+
import { User, UserProvider } from './providers/user-provider';
4+
import { Theme, ThemeProvider } from './providers/theme-provider';
5+
6+
interface RenderWithProvidersProps {
7+
user?: User | null;
8+
theme?: Theme;
9+
}
10+
11+
export function renderWithProviders<T>(
12+
ui: React.ReactElement<T>,
13+
options?: RenderWithProvidersProps,
14+
) {
15+
return render(
16+
<UserProvider.Provider value={options?.user ?? null}>
17+
<ThemeProvider.Provider value={options?.theme ?? 'light'}>{ui}</ThemeProvider.Provider>
18+
</UserProvider.Provider>,
19+
);
20+
}

examples/cookbook/jest-setup.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/* eslint-disable no-undef, import/no-extraneous-dependencies */
2+
3+
// Import built-in Jest matchers
4+
import '@testing-library/react-native/extend-expect';
5+
6+
// Silence the warning: Animated: `useNativeDriver` is not supported because the native animated module is missing
7+
jest.mock('react-native/Libraries/Animated/NativeAnimatedHelper');

examples/cookbook/jest.config.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module.exports = {
2+
preset: '@testing-library/react-native',
3+
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json'],
4+
setupFilesAfterEnv: ['./jest-setup.ts'],
5+
};

examples/cookbook/package.json

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{
2+
"main": "node_modules/expo/AppEntry.js",
3+
"scripts": {
4+
"start": "expo start",
5+
"android": "expo start --android",
6+
"ios": "expo start --ios",
7+
"web": "expo start --web",
8+
"eject": "expo eject",
9+
"test": "jest",
10+
"lint": "eslint .",
11+
"typecheck": "tsc --noEmit"
12+
},
13+
"dependencies": {
14+
"expo": "^50.0.4",
15+
"expo-status-bar": "~1.11.1",
16+
"react": "18.2.0",
17+
"react-dom": "18.2.0",
18+
"react-native": "0.73.2",
19+
"react-native-web": "~0.19.6"
20+
},
21+
"devDependencies": {
22+
"@babel/core": "^7.20.0",
23+
"@testing-library/react-native": "^12.4.0",
24+
"@types/eslint": "^8.56.10",
25+
"@types/jest": "^29.5.12",
26+
"@types/react": "~18.2.45",
27+
"eslint": "^8.57.0",
28+
"jest": "^29.7.0",
29+
"react-test-renderer": "18.2.0",
30+
"typescript": "^5.3.0"
31+
},
32+
"private": true,
33+
"packageManager": "[email protected]"
34+
}

examples/cookbook/tsconfig.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"extends": "expo/tsconfig.base",
3+
"compilerOptions": {
4+
"strict": true,
5+
"allowJs": false
6+
}
7+
}

0 commit comments

Comments
 (0)