Skip to content

Commit 2f4568a

Browse files
vanGalileamdjastrzebski
authored andcommitted
chore: revamp the cookbook app (#1635)
* create a Jotai examples dir in cookbook with related utils, add state management recipes dir * add docs with examples * extract state from component to state, utils, simplify types and custom render func. * refactor: tweaks & cleanup * make cookbook app runnable * update yarn.lock file * fix TS issue and spelling * remove duplicate files and adjust testMatch in config to ensure no utils test run --------- Co-authored-by: stevegalili <[email protected]> refactor: tweak cookbook (#1636) * refactor: move files around * refactor: simplify * chore: remove custom fonts * chore: tweak eslint * chore: update yarn.lock
1 parent d31c05a commit 2f4568a

File tree

29 files changed

+1020
-217
lines changed

29 files changed

+1020
-217
lines changed

examples/cookbook/.eslintrc

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
11
{
2-
"extends": "@callstack"
2+
"extends": "@callstack",
3+
"rules": {
4+
"react-native-a11y/has-valid-accessibility-ignores-invert-colors": "off",
5+
"react-native/no-color-literals": "off",
6+
"react-native-a11y/has-valid-accessibility-descriptors": "off",
7+
}
38
}

examples/cookbook/App.tsx

Lines changed: 0 additions & 8 deletions
This file was deleted.

examples/cookbook/README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
# RNTL Cookbook
22

3-
This example app gathers recipes from the [RNTL Cookbook](https://callstack.github.io/react-native-testing-library/cookbook).
3+
This example app gathers recipes from
4+
the [RNTL Cookbook](https://callstack.github.io/react-native-testing-library/cookbook).
45

5-
Each recipe described in the Cookbook should have a corresponding code example in this repo.
6+
Each recipe described in the Cookbook should have a corresponding code example screen in this repo.
67

78
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 🐶☕️🔥.
9+
Since examples will showcase usage of different dependencies, the dependencies in `package.json`
10+
file will grow much larger that in a normal React Native. This is fine 🐶☕️🔥.

examples/cookbook/app.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22
"expo": {
33
"name": "RNTL Cookbook App",
44
"slug": "rntl-cookbook",
5+
"scheme": "rntlcookbook",
56
"version": "1.0.0",
67
"orientation": "portrait",
78
"icon": "./assets/icon.png",
89
"userInterfaceStyle": "light",
910
"splash": {
1011
"image": "./assets/splash.png",
11-
"resizeMode": "contain",
12-
"backgroundColor": "#ffffff"
12+
"resizeMode": "cover",
13+
"backgroundColor": "#FFFFFF"
1314
},
1415
"updates": {
1516
"fallbackToCacheTimeout": 0
@@ -26,6 +27,7 @@
2627
},
2728
"web": {
2829
"favicon": "./assets/favicon.png"
29-
}
30+
},
31+
"plugins": ["expo-router"]
3032
}
3133
}

examples/cookbook/app/_layout.tsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import * as React from 'react';
2+
import { Stack } from 'expo-router';
3+
import theme from '../theme';
4+
5+
export default function RootLayout() {
6+
return (
7+
<Stack
8+
screenOptions={{
9+
headerStyle: {
10+
backgroundColor: theme.colors.primary,
11+
},
12+
headerTintColor: '#fff',
13+
headerTitleStyle: {
14+
fontWeight: 'bold',
15+
},
16+
headerBackTitleVisible: false,
17+
}}
18+
>
19+
<Stack.Screen name="index" options={{ headerTitle: '' }} />
20+
</Stack>
21+
);
22+
}
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,24 @@
11
import * as React from 'react';
2-
import { View, Text } from 'react-native';
2+
import { StyleSheet, Text, View } from 'react-native';
33
import { useUser } from './providers/user-provider';
44
import { useTheme } from './providers/theme-provider';
55

6-
export function WelcomeScreen() {
6+
export default function WelcomeScreen() {
77
const theme = useTheme();
88
const user = useUser();
99

1010
return (
11-
<View>
11+
<View style={styles.container}>
1212
<Text>Hello {user ? user.name : 'Stranger'}</Text>
1313
<Text>Theme: {theme}</Text>
1414
</View>
1515
);
1616
}
17+
18+
const styles = StyleSheet.create({
19+
container: {
20+
flex: 1,
21+
justifyContent: 'center',
22+
alignItems: 'center',
23+
},
24+
});

examples/cookbook/custom-render/WelcomeScreen.test.tsx renamed to examples/cookbook/app/custom-render/__tests__/index.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as React from 'react';
22
import { screen } from '@testing-library/react-native';
3+
import WelcomeScreen from '../WelcomeScreen';
34
import { renderWithProviders } from './test-utils';
4-
import { WelcomeScreen } from './WelcomeScreen';
55

66
test('renders WelcomeScreen in light theme', () => {
77
renderWithProviders(<WelcomeScreen />, { theme: 'light' });

examples/cookbook/custom-render/test-utils.tsx renamed to examples/cookbook/app/custom-render/__tests__/test-utils.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as React from 'react';
22
import { render } from '@testing-library/react-native';
3-
import { User, UserProvider } from './providers/user-provider';
4-
import { Theme, ThemeProvider } from './providers/theme-provider';
3+
import { User, UserProvider } from '../../../app/custom-render/providers/user-provider';
4+
import { Theme, ThemeProvider } from '../../../app/custom-render/providers/theme-provider';
55

66
interface RenderWithProvidersProps {
77
user?: User | null;
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import * as React from 'react';
2+
import { UserProvider } from './providers/user-provider';
3+
import { ThemeProvider } from './providers/theme-provider';
4+
import WelcomeScreen from './WelcomeScreen';
5+
6+
export default function Example() {
7+
return (
8+
<UserProvider.Provider value={null}>
9+
<ThemeProvider.Provider value={'light'}>
10+
<WelcomeScreen />
11+
</ThemeProvider.Provider>
12+
</UserProvider.Provider>
13+
);
14+
}

examples/cookbook/app/index.tsx

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import React from 'react';
2+
import { FlatList, Image, Pressable, StyleSheet, Text, View } from 'react-native';
3+
import { useRouter } from 'expo-router';
4+
import theme from '../theme';
5+
6+
export default function Home() {
7+
const router = useRouter();
8+
9+
const renderItem = ({ item }: { item: Recipe }) => (
10+
<Pressable role="listitem" style={styles.pressable} onPress={() => router.push(item.path)}>
11+
<Text style={styles.pressableText}>{item.title}</Text>
12+
</Pressable>
13+
);
14+
15+
return (
16+
<View style={styles.container}>
17+
<View style={styles.bannerContainer}>
18+
<Image source={require('../assets/icon.png')} style={styles.logo} />
19+
<Image
20+
resizeMode={'contain'}
21+
source={require('../assets/gradientRNBanner.png')}
22+
style={styles.banner}
23+
/>
24+
<Text style={styles.title}>Testing Library</Text>
25+
<Text style={styles.subTitle}>Cookbook App</Text>
26+
</View>
27+
28+
<FlatList<Recipe>
29+
data={recipes}
30+
renderItem={renderItem}
31+
keyExtractor={(item) => item.id.toString()}
32+
/>
33+
</View>
34+
);
35+
}
36+
37+
const styles = StyleSheet.create({
38+
container: {
39+
flex: 1,
40+
justifyContent: 'center',
41+
alignItems: 'center',
42+
backgroundColor: '#F5F5F5',
43+
paddingVertical: 20,
44+
},
45+
bannerContainer: {
46+
alignItems: 'center',
47+
marginBottom: 20,
48+
},
49+
title: {
50+
fontSize: 20,
51+
color: theme.colors.black,
52+
},
53+
subTitle: {
54+
fontSize: 14,
55+
color: theme.colors.gray,
56+
},
57+
banner: {
58+
height: 40,
59+
},
60+
logo: {
61+
width: 80,
62+
height: 80,
63+
marginBottom: 20,
64+
},
65+
pressable: {
66+
backgroundColor: '#9b6dff',
67+
padding: 12,
68+
marginBottom: 8,
69+
borderRadius: 16,
70+
},
71+
pressableText: {
72+
color: '#fff',
73+
fontSize: 14,
74+
textAlign: 'center',
75+
},
76+
});
77+
78+
type Recipe = {
79+
id: number;
80+
title: string;
81+
path: string;
82+
};
83+
84+
const recipes: Recipe[] = [
85+
{ id: 2, title: 'Welcome Screen with Custom Render', path: 'custom-render/' },
86+
{ id: 1, title: 'Task List with Jotai', path: 'jotai/' },
87+
];

examples/cookbook/jotai/TaskList.tsx renamed to examples/cookbook/app/state-management/jotai/TaskList.tsx

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1+
import 'react-native-get-random-values';
2+
import { nanoid } from 'nanoid';
13
import * as React from 'react';
2-
import { Pressable, Text, TextInput, View } from 'react-native';
4+
import { Pressable, StyleSheet, Text, TextInput, View } from 'react-native';
35
import { useAtom } from 'jotai';
4-
import { nanoid } from 'nanoid';
56
import { newTaskTitleAtom, tasksAtom } from './state';
67

78
export function TaskList() {
@@ -20,7 +21,7 @@ export function TaskList() {
2021
};
2122

2223
return (
23-
<View>
24+
<View style={styles.container}>
2425
{tasks.map((task) => (
2526
<Text key={task.id} testID="task-item">
2627
{task.title}
@@ -42,3 +43,11 @@ export function TaskList() {
4243
</View>
4344
);
4445
}
46+
47+
const styles = StyleSheet.create({
48+
container: {
49+
flex: 1,
50+
justifyContent: 'center',
51+
alignItems: 'center',
52+
},
53+
});

examples/cookbook/jotai/TaskList.test.tsx renamed to examples/cookbook/app/state-management/jotai/__tests__/TaskList.test.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import * as React from 'react';
22
import { render, screen, userEvent } from '@testing-library/react-native';
3+
import { TaskList } from '../TaskList';
4+
import { Task } from '../types';
5+
import { addTask, getAllTasks, newTaskTitleAtom, store, tasksAtom } from '../state';
36
import { renderWithAtoms } from './test-utils';
4-
import { TaskList } from './TaskList';
5-
import { addTask, getAllTasks, newTaskTitleAtom, store, tasksAtom } from './state';
6-
import { Task } from './types';
77

88
jest.useFakeTimers();
99

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import * as React from 'react';
2+
import { TaskList } from './TaskList';
3+
4+
export default function Example() {
5+
return <TaskList />;
6+
}
499 KB
Loading

examples/cookbook/assets/favicon.png

1.82 KB
Loading
62.9 KB
Loading

examples/cookbook/assets/icon.png

494 KB
Loading

examples/cookbook/assets/splash.png

150 KB
Loading

examples/cookbook/jest.config.js

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

examples/cookbook/package.json

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"main": "node_modules/expo/AppEntry.js",
2+
"main": "expo-router/entry",
33
"scripts": {
44
"start": "expo start",
55
"android": "expo start --android",
@@ -12,20 +12,29 @@
1212
},
1313
"dependencies": {
1414
"expo": "^50.0.4",
15+
"expo-constants": "~15.4.6",
16+
"expo-linking": "~6.2.2",
17+
"expo-router": "~3.4.10",
18+
"expo-splash-screen": "~0.26.5",
1519
"expo-status-bar": "~1.11.1",
1620
"jotai": "^2.8.4",
1721
"nanoid": "^3.3.7",
1822
"react": "18.2.0",
1923
"react-dom": "18.2.0",
2024
"react-native": "0.73.2",
25+
"react-native-get-random-values": "~1.8.0",
26+
"react-native-safe-area-context": "4.8.2",
27+
"react-native-screens": "~3.29.0",
2128
"react-native-web": "~0.19.6"
2229
},
2330
"devDependencies": {
2431
"@babel/core": "^7.20.0",
32+
"@expo/metro-runtime": "~3.1.3",
2533
"@testing-library/react-native": "^12.4.0",
2634
"@types/eslint": "^8.56.10",
2735
"@types/jest": "^29.5.12",
2836
"@types/react": "~18.2.45",
37+
"@types/react-native-get-random-values": "^1",
2938
"eslint": "^8.57.0",
3039
"jest": "^29.7.0",
3140
"react-test-renderer": "18.2.0",

examples/cookbook/theme.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export default {
2+
colors: {
3+
primary: '#9b6dff',
4+
secondary: '#58baad',
5+
black: '#323232',
6+
gray: '#5b5a5b',
7+
},
8+
};

0 commit comments

Comments
 (0)