Skip to content

Commit 10bda69

Browse files
vanGalileastevegalili
and
stevegalili
authored
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 <steve.galili@mywheels.nl>
1 parent d31c05a commit 10bda69

29 files changed

+1022
-217
lines changed

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/custom-render/WelcomeScreen.test.tsx renamed to examples/cookbook/__tests__/app/custom-render/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';
33
import { renderWithProviders } from './test-utils';
4-
import { WelcomeScreen } from './WelcomeScreen';
4+
import WelcomeScreen from "../../../app/custom-render";
55

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

examples/cookbook/custom-render/test-utils.tsx renamed to examples/cookbook/__tests__/app/custom-render/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;

examples/cookbook/jotai/TaskList.test.tsx renamed to examples/cookbook/__tests__/app/jotai/index.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 '../../../app/jotai';
34
import { renderWithAtoms } from './test-utils';
4-
import { TaskList } from './TaskList';
5-
import { addTask, getAllTasks, newTaskTitleAtom, store, tasksAtom } from './state';
6-
import { Task } from './types';
5+
import { Task } from '../../../app/jotai/types';
6+
import { addTask, getAllTasks, newTaskTitleAtom, store, tasksAtom } from '../../../app/jotai/state';
77

88
jest.useFakeTimers();
99

examples/cookbook/app.json

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,22 @@
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
1617
},
17-
"assetBundlePatterns": ["**/*"],
18+
"assetBundlePatterns": [
19+
"**/*"
20+
],
1821
"ios": {
1922
"supportsTablet": true
2023
},
@@ -26,6 +29,18 @@
2629
},
2730
"web": {
2831
"favicon": "./assets/favicon.png"
29-
}
32+
},
33+
"plugins": [
34+
"expo-router",
35+
[
36+
"expo-font",
37+
{
38+
"fonts": [
39+
"./assets/fonts/OpenSans-Regular.ttf",
40+
"./assets/fonts/OpenSans-Bold.ttf"
41+
]
42+
}
43+
]
44+
]
3045
}
3146
}

examples/cookbook/app/_layout.tsx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { Stack } from 'expo-router';
2+
import theme from '../theme';
3+
4+
export default function RootLayout() {
5+
return (
6+
<Stack
7+
screenOptions={{
8+
headerStyle: {
9+
backgroundColor: theme.colors.primary,
10+
},
11+
headerTintColor: '#fff',
12+
headerTitleStyle: {
13+
fontWeight: 'bold',
14+
},
15+
headerBackTitleVisible: false,
16+
}}
17+
>
18+
<Stack.Screen name="index" options={{ headerTitle: '' }} />
19+
</Stack>
20+
);
21+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { Slot } from 'expo-router';
2+
import { UserProvider } from './providers/user-provider';
3+
import { ThemeProvider } from './providers/theme-provider';
4+
5+
export default function CustomRenderLayout() {
6+
return (
7+
<UserProvider.Provider value={null}>
8+
<ThemeProvider.Provider value={'light'}>
9+
<Slot />
10+
</ThemeProvider.Provider>
11+
</UserProvider.Provider>
12+
);
13+
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import * as React from 'react';
2-
import { View, Text } from 'react-native';
2+
import { 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={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
1212
<Text>Hello {user ? user.name : 'Stranger'}</Text>
1313
<Text>Theme: {theme}</Text>
1414
</View>

examples/cookbook/app/index.tsx

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

examples/cookbook/jotai/TaskList.tsx renamed to examples/cookbook/app/jotai/index.tsx

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

7-
export function TaskList() {
8+
export default function TaskList() {
89
const [tasks, setTasks] = useAtom(tasksAtom);
910
const [newTaskTitle, setNewTaskTitle] = useAtom(newTaskTitleAtom);
1011

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

2223
return (
23-
<View>
24+
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
2425
{tasks.map((task) => (
2526
<Text key={task.id} testID="task-item">
2627
{task.title}
499 KB
Loading

examples/cookbook/assets/favicon.png

1.82 KB
Loading
Binary file not shown.
Binary file not shown.
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-font": "~11.10.3",
17+
"expo-linking": "~6.2.2",
18+
"expo-router": "~3.4.10",
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)