Skip to content

Commit faa9707

Browse files
committed
testing
1 parent e7bc3c8 commit faa9707

File tree

13 files changed

+1697
-141
lines changed

13 files changed

+1697
-141
lines changed

.eslintrc.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// https://docs.expo.dev/guides/using-eslint/
2+
module.exports = {
3+
extends: 'expo',
4+
ignorePatterns: ['/dist/*'],
5+
};

.husky/pre-commit

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
pnpm tsc
1+
pnpm validate

.nvmrc

22 Bytes
Binary file not shown.

app.json

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,6 @@
1818
},
1919
"package": "com.emon5122.reactnativeapp"
2020
},
21-
"web": {
22-
"bundler": "metro",
23-
"output": "static",
24-
"favicon": "./assets/images/favicon.png"
25-
},
2621
"plugins": [
2722
"expo-router",
2823
[
@@ -36,9 +31,6 @@
3631
],
3732
"expo-font"
3833
],
39-
"experiments": {
40-
"typedRoutes": true
41-
},
4234
"extra": {
4335
"router": {
4436
"origin": false

app/_layout.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { Header } from "@/components/header";
33
import { Poppins_400Regular } from "@expo-google-fonts/poppins";
44
import { Rubik_400Regular, Rubik_700Bold } from "@expo-google-fonts/rubik";
55
import { useFonts } from "expo-font";
6-
import { Stack } from "expo-router";
6+
import { Stack, usePathname } from "expo-router";
77
import * as SplashScreen from "expo-splash-screen";
88
import { useEffect } from "react";
99
import { SafeAreaView } from "react-native";
@@ -13,6 +13,8 @@ import "../global.css";
1313
SplashScreen.preventAutoHideAsync();
1414

1515
export default function RootLayout() {
16+
const path = usePathname();
17+
1618
const [loaded] = useFonts({
1719
Rubik_400Regular,
1820
Rubik_700Bold,
@@ -31,14 +33,14 @@ export default function RootLayout() {
3133

3234
return (
3335
<SafeAreaView style={{ flex: 1 }}>
34-
<Header />
36+
<Header path={path} />
3537
<Stack>
3638
<Stack.Screen name="index" options={{ headerShown: false }} />
3739
<Stack.Screen name="news" options={{ headerShown: false }} />
3840
<Stack.Screen name="chat" options={{ headerShown: false }} />
3941
<Stack.Screen name="+not-found" />
4042
</Stack>
41-
<Footer />
43+
<Footer path={path} />
4244
</SafeAreaView>
4345
);
4446
}

components/__tests__/footer-test.tsx

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import renderer from "react-test-renderer";
2+
import { Footer } from "../footer";
3+
4+
describe("Footer", () => {
5+
it("renders when path is Game Board, News and not Chat", () => {
6+
const tree = renderer.create(<Footer path="/" />).toJSON();
7+
expect(tree).not.toBeNull();
8+
const tree2 = renderer.create(<Footer path="/news" />).toJSON();
9+
expect(tree2).not.toBeNull();
10+
const tree3 = renderer.create(<Footer path="/chat" />).toJSON();
11+
expect(tree3).toBeNull();
12+
});
13+
it("applies active state styling for the selected page", () => {
14+
const homeTree = renderer.create(<Footer path="/" />).toJSON();
15+
if (!homeTree || !("children" in homeTree)) {
16+
throw new Error("Game Board tree not rendered correctly");
17+
}
18+
const homeChildren = homeTree.children as unknown as {
19+
type: string;
20+
props: { className: string };
21+
children: { type: string; props: { className: string } }[];
22+
}[];
23+
const homeOpacities = homeChildren
24+
.map((child) => child.children?.[0]?.props?.className || "")
25+
.filter((className) => className.includes("opacity"));
26+
expect(homeOpacities[0]).toContain("opacity-100");
27+
expect(homeOpacities[1]).toContain("opacity-70");
28+
const newsTree = renderer.create(<Footer path="/news" />).toJSON();
29+
if (!newsTree || !("children" in newsTree)) {
30+
throw new Error("News tree not rendered correctly");
31+
}
32+
const newsChildren = newsTree.children as unknown as {
33+
type: string;
34+
props: { className: string };
35+
children: { type: string; props: { className: string } }[];
36+
}[];
37+
const newsOpacities = newsChildren
38+
.map((child) => child.children?.[0]?.props?.className || "")
39+
.filter((className) => className.includes("opacity"));
40+
expect(newsOpacities[0]).toContain("opacity-70");
41+
expect(newsOpacities[1]).toContain("opacity-100");
42+
});
43+
it("navigates to Game Board when the Game Board & News tabs are clicked", () => {
44+
const tree = renderer.create(<Footer path="/" />).toJSON();
45+
if (!tree || !("children" in tree)) {
46+
throw new Error("Tree not rendered correctly");
47+
}
48+
const treeChildren = tree.children as unknown as {
49+
type: string;
50+
props: { onClick: () => void };
51+
}[];
52+
treeChildren.forEach((child) => {
53+
if (child.props.onClick) {
54+
child.props.onClick();
55+
}
56+
});
57+
const newTree = renderer.create(<Footer path="/" />).toJSON();
58+
if (!newTree || !("children" in newTree)) {
59+
throw new Error("Tree not rendered correctly");
60+
}
61+
const newTreeChildren = newTree.children as unknown as {
62+
type: string;
63+
props: { className: string };
64+
children: { type: string; props: { className: string } }[];
65+
}[];
66+
const newTreeOpacities = newTreeChildren
67+
.map((child) => child.children?.[0]?.props?.className || "")
68+
.filter((className) => className.includes("opacity"));
69+
expect(newTreeOpacities[0]).toContain("opacity-100");
70+
expect(newTreeOpacities[1]).toContain("opacity-70");
71+
});
72+
});

components/__tests__/header-test.tsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import renderer from "react-test-renderer";
2+
import { Header } from "../header";
3+
4+
describe("Header", () => {
5+
it("renders header content correctly on Game Board & News", () => {
6+
const tree = renderer.create(<Header path="/" />).toJSON();
7+
expect(tree).not.toBeNull();
8+
const tree2 = renderer.create(<Header path="/news" />).toJSON();
9+
expect(tree2).not.toBeNull();
10+
});
11+
it("does not render when the path is /chat", () => {
12+
const tree = renderer.create(<Header path="/chat" />).toJSON();
13+
expect(tree).toBeNull();
14+
});
15+
});

components/footer.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Link, usePathname } from "expo-router";
1+
import { Link } from "expo-router";
22
import { Text, View } from "react-native";
33
import GameBoardIcon from "./icons/gameBoard";
44
import NewsIcon from "./icons/news";
@@ -29,11 +29,8 @@ const TABS: TabType[] = [
2929
{ icon: NewsIcon, label: "News", href: "/news" },
3030
];
3131

32-
export const Footer = () => {
33-
const path = usePathname();
34-
32+
export const Footer = ({ path }: { path: string }) => {
3533
if (path === "/chat") return null;
36-
3734
const TabItem = ({
3835
icon: Icon,
3936
label,

components/header.tsx

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,8 @@
11
import { loggedInUserData } from "@/constants/data/user";
2-
import { usePathname } from "expo-router";
32
import { Image, Text, View } from "react-native";
43

5-
export const Header = () => {
6-
const path = usePathname();
7-
8-
if (path === "/chat") {
9-
return null;
10-
}
11-
4+
export const Header = ({ path }: { path: string }) => {
5+
if (path === "/chat") return null;
126
return (
137
<View className="w-full h-[10%] bg-[#1F1B1B] p-4">
148
<View className="flex flex-row items-center mt-2.5">

package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,16 @@
22
"name": "react-native-app",
33
"main": "expo-router/entry",
44
"version": "1.0.0",
5+
"packageManager": "pnpm@9.15.4",
56
"scripts": {
67
"start": "expo start",
7-
"reset-project": "node ./scripts/reset-project.js",
88
"android": "expo start --android",
99
"ios": "expo start --ios",
1010
"web": "expo start --web",
1111
"test": "jest --watchAll",
1212
"lint": "expo lint",
1313
"tsc": "tsc --noEmit",
14+
"validate": "pnpm jest --passWithNoTests && pnpm lint && pnpm tsc",
1415
"prepare": "husky"
1516
},
1617
"jest": {
@@ -53,6 +54,8 @@
5354
"@types/react": "~18.3.18",
5455
"@types/react-test-renderer": "^18.3.1",
5556
"autoprefixer": "^10.4.20",
57+
"eslint": "^8.57.0",
58+
"eslint-config-expo": "~8.0.1",
5659
"husky": "^9.1.7",
5760
"jest": "^29.7.0",
5861
"jest-expo": "~52.0.3",

0 commit comments

Comments
 (0)