Skip to content

Commit e7a3456

Browse files
authored
Merge pull request #3984 from aryaemami59/rn-example-ci
Add React Native demo app to CI workflow
2 parents 6e66f4f + 480ba72 commit e7a3456

File tree

81 files changed

+13889
-1
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

81 files changed

+13889
-1
lines changed

.github/workflows/tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ jobs:
149149
fail-fast: false
150150
matrix:
151151
node: ['18.x']
152-
example: ['cra4', 'cra5', 'next', 'vite', 'node-standard', 'node-esm', 'expo']
152+
example: ['cra4', 'cra5', 'next', 'vite', 'node-standard', 'node-esm', 'react-native', 'expo']
153153
defaults:
154154
run:
155155
working-directory: ./examples/publish-ci/${{ matrix.example }}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
BUNDLE_PATH: "vendor/bundle"
2+
BUNDLE_FORCE_RUBY_PLATFORM: 1
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{
2+
"extends": [
3+
"eslint:recommended",
4+
"@react-native",
5+
"plugin:react/jsx-runtime",
6+
"prettier"
7+
],
8+
"parser": "@typescript-eslint/parser",
9+
"parserOptions": { "project": true, "tsconfigRootDir": "./" },
10+
"plugins": ["@typescript-eslint"],
11+
"root": true,
12+
"rules": {
13+
"@typescript-eslint/consistent-type-imports": [
14+
2,
15+
{ "fixStyle": "separate-type-imports" }
16+
],
17+
"@typescript-eslint/no-restricted-imports": [
18+
2,
19+
{
20+
"paths": [
21+
{
22+
"name": "react-redux",
23+
"importNames": ["useSelector", "useStore", "useDispatch"],
24+
"message": "Please use pre-typed versions from `src/app/hooks.ts` instead."
25+
}
26+
]
27+
}
28+
]
29+
},
30+
"overrides": [
31+
{ "files": ["*.{c,m,}{t,j}s", "*.{t,j}sx"] },
32+
{ "files": ["*{test,spec}.{t,j}s?(x)"], "env": { "jest": true } }
33+
]
34+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# OSX
2+
#
3+
.DS_Store
4+
5+
# Xcode
6+
#
7+
build/
8+
*.pbxuser
9+
!default.pbxuser
10+
*.mode1v3
11+
!default.mode1v3
12+
*.mode2v3
13+
!default.mode2v3
14+
*.perspectivev3
15+
!default.perspectivev3
16+
xcuserdata
17+
*.xccheckout
18+
*.moved-aside
19+
DerivedData
20+
*.hmap
21+
*.ipa
22+
*.xcuserstate
23+
ios/.xcode.env.local
24+
25+
# Android/IntelliJ
26+
#
27+
build/
28+
.idea
29+
.gradle
30+
local.properties
31+
*.iml
32+
*.hprof
33+
.cxx/
34+
*.keystore
35+
!debug.keystore
36+
37+
# node.js
38+
#
39+
node_modules/
40+
npm-debug.log
41+
yarn-error.log
42+
.yarn/
43+
44+
# fastlane
45+
#
46+
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
47+
# screenshots whenever they are needed.
48+
# For more information about the recommended setup visit:
49+
# https://docs.fastlane.tools/best-practices/source-control/
50+
51+
**/fastlane/report.xml
52+
**/fastlane/Preview.html
53+
**/fastlane/screenshots
54+
**/fastlane/test_output
55+
56+
# Bundle artifact
57+
*.jsbundle
58+
59+
# Ruby / CocoaPods
60+
/ios/Pods/
61+
/vendor/bundle/
62+
63+
# Temporary files created by Metro to check the health of the file watcher
64+
.metro-health-check*
65+
66+
# testing
67+
/coverage
68+
69+
#IDE
70+
.vscode
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"arrowParens": "avoid",
3+
"semi": false
4+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
import { screen, waitFor } from "@testing-library/react-native"
2+
import { App } from "./App"
3+
import { renderWithProviders } from "./src/utils/test-utils"
4+
5+
test("App should have correct initial render", () => {
6+
renderWithProviders(<App />)
7+
8+
// The app should be rendered correctly
9+
expect(screen.getByText(/learn more redux/i)).toBeOnTheScreen()
10+
11+
// Initial state: count should be 0, incrementValue should be 2
12+
expect(screen.getByLabelText("Count")).toHaveTextContent("0")
13+
expect(screen.getByLabelText("Set increment amount")).toHaveDisplayValue("2")
14+
})
15+
16+
test("Increment value and Decrement value should work as expected", async () => {
17+
const { user } = renderWithProviders(<App />)
18+
19+
// Click on "+" => Count should be 1
20+
await user.press(screen.getByLabelText("Increment value"))
21+
expect(screen.getByLabelText("Count")).toHaveTextContent("1")
22+
23+
// Click on "-" => Count should be 0
24+
await user.press(screen.getByLabelText("Decrement value"))
25+
expect(screen.getByLabelText("Count")).toHaveTextContent("0")
26+
})
27+
28+
test("Add Amount should work as expected", async () => {
29+
const { user } = renderWithProviders(<App />)
30+
31+
// "Add Amount" button is clicked => Count should be 2
32+
await user.press(screen.getByText("Add Amount"))
33+
expect(screen.getByLabelText("Count")).toHaveTextContent("2")
34+
35+
const incrementValueInput = screen.getByLabelText("Set increment amount")
36+
// incrementValue is 2, click on "Add Amount" => Count should be 4
37+
await user.clear(incrementValueInput)
38+
await user.type(incrementValueInput, "2")
39+
await user.press(screen.getByText("Add Amount"))
40+
expect(screen.getByLabelText("Count")).toHaveTextContent("4")
41+
42+
// [Negative number] incrementValue is -1, click on "Add Amount" => Count should be 3
43+
await user.clear(incrementValueInput)
44+
await user.type(incrementValueInput, "-1")
45+
await user.press(screen.getByText("Add Amount"))
46+
expect(screen.getByLabelText("Count")).toHaveTextContent("3")
47+
})
48+
49+
it("Add Async should work as expected", async () => {
50+
const { user } = renderWithProviders(<App />)
51+
52+
// "Add Async" button is clicked => Count should be 2
53+
await user.press(screen.getByText("Add Async"))
54+
55+
await waitFor(() => {
56+
expect(screen.getByLabelText("Count")).toHaveTextContent("2")
57+
})
58+
59+
const incrementValueInput = screen.getByLabelText("Set increment amount")
60+
// incrementValue is 2, click on "Add Async" => Count should be 4
61+
await user.clear(incrementValueInput)
62+
await user.type(incrementValueInput, "2")
63+
64+
await user.press(screen.getByText("Add Async"))
65+
await waitFor(() => {
66+
expect(screen.getByLabelText("Count")).toHaveTextContent("4")
67+
})
68+
69+
// [Negative number] incrementValue is -1, click on "Add Async" => Count should be 3
70+
await user.clear(incrementValueInput)
71+
await user.type(incrementValueInput, "-1")
72+
await user.press(screen.getByText("Add Async"))
73+
await waitFor(() => {
74+
expect(screen.getByLabelText("Count")).toHaveTextContent("3")
75+
})
76+
})
77+
78+
test("Add If Odd should work as expected", async () => {
79+
const { user } = renderWithProviders(<App />)
80+
81+
// "Add If Odd" button is clicked => Count should stay 0
82+
await user.press(screen.getByText("Add If Odd"))
83+
expect(screen.getByLabelText("Count")).toHaveTextContent("0")
84+
85+
// Click on "+" => Count should be updated to 1
86+
await user.press(screen.getByLabelText("Increment value"))
87+
expect(screen.getByLabelText("Count")).toHaveTextContent("1")
88+
89+
// "Add If Odd" button is clicked => Count should be updated to 3
90+
await user.press(screen.getByText("Add If Odd"))
91+
expect(screen.getByLabelText("Count")).toHaveTextContent("3")
92+
93+
const incrementValueInput = screen.getByLabelText("Set increment amount")
94+
// incrementValue is 1, click on "Add If Odd" => Count should be updated to 4
95+
await user.clear(incrementValueInput)
96+
await user.type(incrementValueInput, "1")
97+
await user.press(screen.getByText("Add If Odd"))
98+
expect(screen.getByLabelText("Count")).toHaveTextContent("4")
99+
100+
// click on "Add If Odd" => Count should stay 4
101+
await user.clear(incrementValueInput)
102+
await user.type(incrementValueInput, "-1")
103+
await user.press(screen.getByText("Add If Odd"))
104+
expect(screen.getByLabelText("Count")).toHaveTextContent("4")
105+
})
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import {
2+
SafeAreaView,
3+
ScrollView,
4+
StatusBar,
5+
StyleSheet,
6+
Text,
7+
View,
8+
useColorScheme,
9+
} from "react-native"
10+
import { Counter } from "./src/features/counter/Counter"
11+
12+
import {
13+
DebugInstructions,
14+
HermesBadge,
15+
LearnMoreLinks,
16+
ReloadInstructions,
17+
} from "react-native/Libraries/NewAppScreen"
18+
import { Header } from "./src/components/Header"
19+
import { LearnReduxLinks } from "./src/components/LearnReduxLinks"
20+
import { Section } from "./src/components/Section"
21+
import { TypedColors } from "./src/constants/TypedColors"
22+
import { Quotes } from "./src/features/quotes/Quotes"
23+
24+
export const App = () => {
25+
const isDarkMode = useColorScheme() === "dark"
26+
27+
const backgroundStyle = {
28+
backgroundColor: isDarkMode ? TypedColors.darker : TypedColors.lighter,
29+
}
30+
31+
return (
32+
<SafeAreaView style={backgroundStyle}>
33+
<StatusBar
34+
barStyle={isDarkMode ? "light-content" : "dark-content"}
35+
backgroundColor={backgroundStyle.backgroundColor}
36+
/>
37+
<ScrollView
38+
contentInsetAdjustmentBehavior="automatic"
39+
style={backgroundStyle}
40+
>
41+
<Header />
42+
<HermesBadge />
43+
<View
44+
style={{
45+
backgroundColor: isDarkMode ? TypedColors.black : TypedColors.white,
46+
}}
47+
>
48+
<Counter />
49+
<Quotes />
50+
<Section title="Step One">
51+
Edit <Text style={styles.highlight}>App.tsx</Text> to change this
52+
screen and then come back to see your edits.
53+
</Section>
54+
<Section title="See Your Changes">
55+
<ReloadInstructions />
56+
</Section>
57+
<Section title="Debug">
58+
<DebugInstructions />
59+
</Section>
60+
<Section title="Learn More Redux">
61+
Discover what to do next with Redux:
62+
</Section>
63+
<LearnReduxLinks />
64+
<Section title="Learn More React Native">
65+
Read the docs to discover what to do next:
66+
</Section>
67+
<LearnMoreLinks />
68+
</View>
69+
</ScrollView>
70+
</SafeAreaView>
71+
)
72+
}
73+
74+
const styles = StyleSheet.create({
75+
highlight: {
76+
fontWeight: "700",
77+
},
78+
})
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
source 'https://rubygems.org'
2+
3+
# You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
4+
ruby ">= 2.6.10"
5+
6+
gem 'cocoapods', '~> 1.13'
7+
gem 'activesupport', '>= 6.1.7.3', '< 7.1.0'

0 commit comments

Comments
 (0)