diff --git a/package.json b/package.json
index 6727bb8..771c330 100644
--- a/package.json
+++ b/package.json
@@ -50,22 +50,31 @@
"typescript": "^5.1.3"
},
"jest": {
- "preset": "jest-expo",
+ "projects": [
+ {
+ "preset": "jest-expo/ios",
+ "setupFilesAfterEnv": [
+ "./spec/specHelpers/jest/setupFilesAfterEnv/useReactNativeSpecificJestMatchers.ts",
+ "./spec/specHelpers/jest/setupFilesAfterEnv/jestCustomMatchers.ts",
+ "./spec/specHelpers/jest/setupFilesAfterEnv/mockExpoLibraries.ts"
+ ]
+ },
+ {
+ "preset": "jest-expo/android",
+ "setupFilesAfterEnv": [
+ "./spec/specHelpers/jest/setupFilesAfterEnv/useReactNativeSpecificJestMatchers.ts",
+ "./spec/specHelpers/jest/setupFilesAfterEnv/jestCustomMatchers.ts",
+ "./spec/specHelpers/jest/setupFilesAfterEnv/mockExpoLibraries.ts"
+ ]
+ }
+ ],
"transformIgnorePatterns": [
"node_modules/(?!((jest-)?react-native|@react-native(-community)?)|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|native-base|react-native-svg)"
],
- "setupFilesAfterEnv": [
- "./spec/specHelpers/jest/setupFilesAfterEnv/useReactNativeSpecificJestMatchers.ts",
- "./spec/specHelpers/jest/setupFilesAfterEnv/jestCustomMatchers.ts",
- "./spec/specHelpers/jest/setupFilesAfterEnv/mockExpoLibraries.ts"
- ],
"verbose": true,
"passWithNoTests": true,
"coverageProvider": "v8",
- "collectCoverageFrom": [
- "./src/**",
- "!src/Config.ts"
- ],
+ "collectCoverageFrom": ["./src/**", "!src/Config.ts", "!src/types/**"],
"coverageThreshold": {
"global": {
"lines": 100,
@@ -73,10 +82,7 @@
"branches": 100,
"statements": 100
}
- },
- "coveragePathIgnorePatterns": [
- "./src/types"
- ]
+ }
},
"private": true
}
diff --git a/spec/app/games.test.tsx b/spec/app/games.test.tsx
index 6203aea..7e7edcb 100644
--- a/spec/app/games.test.tsx
+++ b/spec/app/games.test.tsx
@@ -1,4 +1,5 @@
import * as ERTL from "expo-router/testing-library"
+import * as ReactNative from "react-native"
import * as DateFNS from "date-fns"
import type { Game } from "types/Game"
import gameFactory from "../specHelpers/factories/game"
@@ -28,7 +29,7 @@ describe("viewing the games tab", () => {
ERTL.renderRouter("src/app", { initialUrl: "/games" })
await ERTL.waitFor(() => {
- expect(ERTL.screen).toShowTestID("Loading Spinner")
+ expect(ERTL.screen).toShowTestId("Loading Spinner")
})
},
})
@@ -69,7 +70,7 @@ describe("viewing the games tab", () => {
ERTL.renderRouter("src/app", { initialUrl: "/games" })
await ERTL.waitFor(() => {
- expect(ERTL.screen).not.toShowTestID("Loading Spinner")
+ expect(ERTL.screen).not.toShowTestId("Loading Spinner")
})
const gameListItems = ERTL.screen.getAllByTestId("Game List Item")
@@ -94,7 +95,7 @@ describe("viewing the games tab", () => {
ERTL.renderRouter("src/app", { initialUrl: "/games" })
await ERTL.waitFor(() => {
- expect(ERTL.screen).not.toShowTestID("Loading Spinner")
+ expect(ERTL.screen).not.toShowTestId("Loading Spinner")
})
const gameListItems = ERTL.screen.getAllByTestId("Game List Item")
@@ -126,7 +127,7 @@ describe("viewing the games tab", () => {
ERTL.renderRouter("src/app", { initialUrl: "/games" })
await ERTL.waitFor(() => {
- expect(ERTL.screen).not.toShowTestID("Loading Spinner")
+ expect(ERTL.screen).not.toShowTestId("Loading Spinner")
})
const gameListItems = ERTL.screen.getAllByTestId("Game List Item")
@@ -168,7 +169,7 @@ describe("viewing the games tab", () => {
ERTL.renderRouter("src/app", { initialUrl: "/games" })
await ERTL.waitFor(() => {
- expect(ERTL.screen).not.toShowTestID("Loading Spinner")
+ expect(ERTL.screen).not.toShowTestId("Loading Spinner")
})
const gameListItems = ERTL.screen.getAllByTestId("Game List Item")
@@ -177,18 +178,26 @@ describe("viewing the games tab", () => {
expect(ERTL.within(gameListItems[0])).toShowText("2 - 1 W")
expect(ERTL.within(gameListItems[1])).toShowText("0 - 3 L")
expect(ERTL.within(gameListItems[2])).toShowText("0 - 0 T")
- expect(
- ERTL.within(gameListItems[0]).getByText("2 - 1 W").props.style
- .color,
- ).toEqual("green")
- expect(
- ERTL.within(gameListItems[1]).getByText("0 - 3 L").props.style
- .color,
- ).toEqual("red")
- expect(
- ERTL.within(gameListItems[2]).getByText("0 - 0 T").props.style
- .color,
- ).toEqual("gray")
+
+ const winLabelColor = ERTL.within(gameListItems[0]).getByText(
+ "2 - 1 W",
+ ).props.style.color
+ const lossLabelColor = ERTL.within(gameListItems[1]).getByText(
+ "0 - 3 L",
+ ).props.style.color
+ const tieLabelColor = ERTL.within(gameListItems[2]).getByText(
+ "0 - 0 T",
+ ).props.style.color
+
+ if (ReactNative.Platform.OS === "ios") {
+ expect(winLabelColor).toEqual({ semantic: ["systemGreen"] })
+ expect(lossLabelColor).toEqual({ semantic: ["systemRed"] })
+ expect(tieLabelColor).toEqual({ semantic: ["systemGray"] })
+ } else {
+ expect(winLabelColor).toEqual("green")
+ expect(lossLabelColor).toEqual("red")
+ expect(tieLabelColor).toEqual("gray")
+ }
})
},
})
@@ -209,7 +218,7 @@ describe("viewing the games tab", () => {
ERTL.renderRouter("src/app", { initialUrl: "/games" })
await ERTL.waitFor(() => {
- expect(ERTL.screen).not.toShowTestID("Loading Spinner")
+ expect(ERTL.screen).not.toShowTestId("Loading Spinner")
})
await ERTL.waitFor(() => {
@@ -231,7 +240,7 @@ describe("viewing the games tab", () => {
ERTL.renderRouter("src/app", { initialUrl: "/games" })
await ERTL.waitFor(() => {
- expect(ERTL.screen).not.toShowTestID("Loading Spinner")
+ expect(ERTL.screen).not.toShowTestId("Loading Spinner")
})
const gameListItems = ERTL.screen.getAllByTestId("Game List Item")
@@ -255,7 +264,7 @@ describe("viewing the games tab", () => {
ERTL.renderRouter("src/app", { initialUrl: "/games" })
await ERTL.waitFor(() => {
- expect(ERTL.screen).not.toShowTestID("Loading Spinner")
+ expect(ERTL.screen).not.toShowTestId("Loading Spinner")
})
},
})
@@ -270,7 +279,7 @@ describe("viewing the games tab", () => {
ERTL.renderRouter("src/app", { initialUrl: "/games" })
await ERTL.waitFor(() => {
- expect(ERTL.screen).not.toShowTestID("Loading Spinner")
+ expect(ERTL.screen).not.toShowTestId("Loading Spinner")
})
},
})
@@ -324,7 +333,9 @@ describe("viewing the games tab", () => {
test: async () => {
ERTL.renderRouter("src/app", { initialUrl: "/games" })
- await ERTL.waitFor(() => expect(ERTL.screen).toShowText("Reload"))
+ await ERTL.waitFor(() =>
+ expect(ERTL.screen).toShowTestId("Reload Button"),
+ )
},
})
})
@@ -336,14 +347,16 @@ describe("viewing the games tab", () => {
test: async () => {
ERTL.renderRouter("src/app", { initialUrl: "/games" })
- await ERTL.waitFor(() => expect(ERTL.screen).toShowText("Reload"))
+ await ERTL.waitFor(() =>
+ expect(ERTL.screen).toShowTestId("Reload Button"),
+ )
},
})
await mockGamesFromApi({
response: "Network Error",
test: async () => {
- ERTL.fireEvent.press(ERTL.screen.getByText("Reload"))
+ ERTL.fireEvent.press(ERTL.screen.getByTestId("Reload Button"))
await ERTL.waitFor(() =>
expect(ERTL.screen).not.toShowText(
@@ -360,17 +373,19 @@ describe("viewing the games tab", () => {
test: async () => {
ERTL.renderRouter("src/app", { initialUrl: "/games" })
- await ERTL.waitFor(() => expect(ERTL.screen).toShowText("Reload"))
+ await ERTL.waitFor(() =>
+ expect(ERTL.screen).toShowTestId("Reload Button"),
+ )
},
})
await mockGamesFromApi({
response: "Network Error",
test: async () => {
- ERTL.fireEvent.press(ERTL.screen.getByText("Reload"))
+ ERTL.fireEvent.press(ERTL.screen.getByTestId("Reload Button"))
await ERTL.waitFor(() =>
- expect(ERTL.screen).not.toShowText("Reload"),
+ expect(ERTL.screen).not.toShowTestId("Reload Button"),
)
},
})
@@ -382,17 +397,19 @@ describe("viewing the games tab", () => {
test: async () => {
ERTL.renderRouter("src/app", { initialUrl: "/games" })
- await ERTL.waitFor(() => expect(ERTL.screen).toShowText("Reload"))
+ await ERTL.waitFor(() =>
+ expect(ERTL.screen).toShowTestId("Reload Button"),
+ )
},
})
await mockGamesFromApi({
response: "Network Error",
test: async () => {
- ERTL.fireEvent.press(ERTL.screen.getByText("Reload"))
+ ERTL.fireEvent.press(ERTL.screen.getByTestId("Reload Button"))
await ERTL.waitFor(() =>
- expect(ERTL.screen).toShowTestID("Loading Spinner"),
+ expect(ERTL.screen).toShowTestId("Loading Spinner"),
)
},
})
@@ -405,7 +422,9 @@ describe("viewing the games tab", () => {
test: async () => {
ERTL.renderRouter("src/app", { initialUrl: "/games" })
- await ERTL.waitFor(() => expect(ERTL.screen).toShowText("Reload"))
+ await ERTL.waitFor(() =>
+ expect(ERTL.screen).toShowTestId("Reload Button"),
+ )
},
})
@@ -414,7 +433,7 @@ describe("viewing the games tab", () => {
await mockGamesFromApi({
response: [game],
test: async () => {
- ERTL.fireEvent.press(ERTL.screen.getByText("Reload"))
+ ERTL.fireEvent.press(ERTL.screen.getByTestId("Reload Button"))
await ERTL.waitFor(() => {
expect(ERTL.screen).toShowText(gameDate(game))
diff --git a/spec/app/index.test.tsx b/spec/app/index.test.tsx
index 702e8a9..752ecdd 100644
--- a/spec/app/index.test.tsx
+++ b/spec/app/index.test.tsx
@@ -20,7 +20,7 @@ describe("opening the app", () => {
ERTL.renderRouter("src/app")
await ERTL.waitFor(() => {
- expect(ERTL.screen).toShowTestID("Loading Spinner")
+ expect(ERTL.screen).toShowTestId("Loading Spinner")
})
},
})
@@ -59,7 +59,7 @@ describe("opening the app", () => {
ERTL.renderRouter("src/app")
await ERTL.waitFor(() => {
- expect(ERTL.screen).not.toShowTestID("Loading Spinner")
+ expect(ERTL.screen).not.toShowTestId("Loading Spinner")
})
const playerListItems = ERTL.screen.getAllByTestId("Player List Item")
@@ -136,7 +136,7 @@ describe("opening the app", () => {
ERTL.renderRouter("src/app")
await ERTL.waitFor(() => {
- expect(ERTL.screen).not.toShowTestID("Loading Spinner")
+ expect(ERTL.screen).not.toShowTestId("Loading Spinner")
})
},
})
@@ -151,7 +151,7 @@ describe("opening the app", () => {
ERTL.renderRouter("src/app")
await ERTL.waitFor(() => {
- expect(ERTL.screen).not.toShowTestID("Loading Spinner")
+ expect(ERTL.screen).not.toShowTestId("Loading Spinner")
})
},
})
@@ -205,7 +205,9 @@ describe("opening the app", () => {
test: async () => {
ERTL.renderRouter("src/app")
- await ERTL.waitFor(() => expect(ERTL.screen).toShowText("Reload"))
+ await ERTL.waitFor(() =>
+ expect(ERTL.screen).toShowTestId("Reload Button"),
+ )
},
})
})
@@ -217,14 +219,16 @@ describe("opening the app", () => {
test: async () => {
ERTL.renderRouter("src/app")
- await ERTL.waitFor(() => expect(ERTL.screen).toShowText("Reload"))
+ await ERTL.waitFor(() =>
+ expect(ERTL.screen).toShowTestId("Reload Button"),
+ )
},
})
await mockPlayersFromApi({
response: "Network Error",
test: async () => {
- ERTL.fireEvent.press(ERTL.screen.getByText("Reload"))
+ ERTL.fireEvent.press(ERTL.screen.getByTestId("Reload Button"))
await ERTL.waitFor(() =>
expect(ERTL.screen).not.toShowText(
@@ -241,17 +245,19 @@ describe("opening the app", () => {
test: async () => {
ERTL.renderRouter("src/app")
- await ERTL.waitFor(() => expect(ERTL.screen).toShowText("Reload"))
+ await ERTL.waitFor(() =>
+ expect(ERTL.screen).toShowTestId("Reload Button"),
+ )
},
})
await mockPlayersFromApi({
response: "Network Error",
test: async () => {
- ERTL.fireEvent.press(ERTL.screen.getByText("Reload"))
+ ERTL.fireEvent.press(ERTL.screen.getByTestId("Reload Button"))
await ERTL.waitFor(() =>
- expect(ERTL.screen).not.toShowText("Reload"),
+ expect(ERTL.screen).not.toShowTestId("Reload Button"),
)
},
})
@@ -263,17 +269,19 @@ describe("opening the app", () => {
test: async () => {
ERTL.renderRouter("src/app")
- await ERTL.waitFor(() => expect(ERTL.screen).toShowText("Reload"))
+ await ERTL.waitFor(() =>
+ expect(ERTL.screen).toShowTestId("Reload Button"),
+ )
},
})
await mockPlayersFromApi({
response: "Network Error",
test: async () => {
- ERTL.fireEvent.press(ERTL.screen.getByText("Reload"))
+ ERTL.fireEvent.press(ERTL.screen.getByTestId("Reload Button"))
await ERTL.waitFor(() =>
- expect(ERTL.screen).toShowTestID("Loading Spinner"),
+ expect(ERTL.screen).toShowTestId("Loading Spinner"),
)
},
})
@@ -286,7 +294,9 @@ describe("opening the app", () => {
test: async () => {
ERTL.renderRouter("src/app")
- await ERTL.waitFor(() => expect(ERTL.screen).toShowText("Reload"))
+ await ERTL.waitFor(() =>
+ expect(ERTL.screen).toShowTestId("Reload Button"),
+ )
},
})
@@ -295,7 +305,7 @@ describe("opening the app", () => {
playerFactory({ first_name: "Kelly", last_name: "Kapoor" }),
],
test: async () => {
- ERTL.fireEvent.press(ERTL.screen.getByText("Reload"))
+ ERTL.fireEvent.press(ERTL.screen.getByTestId("Reload Button"))
await ERTL.waitFor(() =>
expect(ERTL.screen).toShowText("Kelly Kapoor"),
diff --git a/spec/specHelpers/jest/setupFilesAfterEnv/jestCustomMatchers.ts b/spec/specHelpers/jest/setupFilesAfterEnv/jestCustomMatchers.ts
index 4e9a778..43129a0 100644
--- a/spec/specHelpers/jest/setupFilesAfterEnv/jestCustomMatchers.ts
+++ b/spec/specHelpers/jest/setupFilesAfterEnv/jestCustomMatchers.ts
@@ -15,7 +15,7 @@ expect.extend({
: `expected "${text}" to be shown`,
}
},
- toShowTestID: (component: RenderResult, testID: string) => {
+ toShowTestId: (component: RenderResult, testID: string) => {
const pass = component.queryByTestId(testID) !== null
return {
pass,
diff --git a/src/components/CenteredReloadButton.tsx b/src/components/CenteredReloadButton.tsx
index b6cc141..1c01acc 100644
--- a/src/components/CenteredReloadButton.tsx
+++ b/src/components/CenteredReloadButton.tsx
@@ -8,7 +8,11 @@ const CenteredReloadButton = ({
-
+
)
diff --git a/src/components/GameListItem.tsx b/src/components/GameListItem.tsx
index bb9b07b..0f8654f 100644
--- a/src/components/GameListItem.tsx
+++ b/src/components/GameListItem.tsx
@@ -1,6 +1,9 @@
import React from "react"
import * as ReactNative from "react-native"
import * as DateFNS from "date-fns"
+import useTheme from "hooks/useTheme"
+import useGameOutcome from "hooks/useGameOutcome"
+import useGameScoreColor from "hooks/useGameScoreColor"
import type { Game } from "types/Game"
const sideColumnWidth = 120
@@ -12,45 +15,26 @@ interface GameListItemProps {
}
const GameListItem = ({ game }: GameListItemProps): React.ReactElement => {
- const formattedDate = React.useMemo((): string => {
+ const dateLabel = React.useMemo((): string => {
return DateFNS.format(DateFNS.parseISO(game.played_at), "MMM d")
}, [game.played_at])
- const formattedTime = React.useMemo((): string => {
+ const timeLabel = React.useMemo((): string => {
return DateFNS.format(DateFNS.parseISO(game.played_at), "h:mm a")
}, [game.played_at])
- const outcome = React.useMemo((): "win" | "loss" | "tie" | "unplayed" => {
- if (game.goals_for !== undefined && game.goals_against !== undefined) {
- if (game.goals_for > game.goals_against) {
- return "win"
- } else if (game.goals_for < game.goals_against) {
- return "loss"
- }
- return "tie"
- }
- return "unplayed"
- }, [game.goals_for, game.goals_against])
+ const gameOutcome = useGameOutcome(game)
+
+ const gameScoreColor = useGameScoreColor(gameOutcome)
- const formattedScore = React.useMemo((): string => {
- if (outcome !== "unplayed") {
- return `${game.goals_for} - ${game.goals_against} ${outcome.at(0)!.toUpperCase()}`
+ const scoreLabel = React.useMemo((): string => {
+ if (gameOutcome !== "Unplayed") {
+ return `${game.goals_for} - ${game.goals_against} ${gameOutcome.at(0)}`
}
return ""
- }, [game.goals_for, game.goals_against, outcome])
+ }, [game.goals_for, game.goals_against, gameOutcome])
- const scoreColor = React.useMemo((): string => {
- switch (outcome) {
- case "win":
- return "green"
- case "loss":
- return "red"
- case "tie":
- return "gray"
- case "unplayed":
- return "transparent"
- }
- }, [outcome])
+ const theme = useTheme()
return (
{
style={{ flexDirection: "row", width: sideColumnWidth }}
>
- {formattedTime}
+ {timeLabel}
+
+
- {formattedDate}
+ {dateLabel}
-
+
{game.rink}
{
- {formattedScore}
+ {scoreLabel}
(
-
+}: ListItemSeparatorProps): React.ReactElement => {
+ const theme = useTheme()
+
+ return (
-
-)
+ >
+
+
+ )
+}
export default ListItemSeparator
diff --git a/src/components/PlayerListItem.tsx b/src/components/PlayerListItem.tsx
index 2f689f2..f1e47a0 100644
--- a/src/components/PlayerListItem.tsx
+++ b/src/components/PlayerListItem.tsx
@@ -1,3 +1,4 @@
+import useTheme from "hooks/useTheme"
import React from "react"
import * as ReactNative from "react-native"
import type { Player } from "types/Player"
@@ -33,6 +34,8 @@ const PlayerListItem = ({
[player.phone_number],
)
+ const theme = useTheme()
+
return (
-
+
{player.first_name}
{" "}
@@ -57,14 +60,23 @@ const PlayerListItem = ({
{formattedPhoneNumber && (
{formattedPhoneNumber}
)}
{player.jersey_number !== undefined && (
-
+
#{player.jersey_number}
)}
diff --git a/src/hooks/useGameOutcome.ts b/src/hooks/useGameOutcome.ts
new file mode 100644
index 0000000..1766188
--- /dev/null
+++ b/src/hooks/useGameOutcome.ts
@@ -0,0 +1,21 @@
+import React from "react"
+import type { Game } from "types/Game"
+import type { GameOutcome } from "types/GameOutcome"
+
+const useGameOutcome = (game: Game): GameOutcome => {
+ const gameOutcome = React.useMemo((): GameOutcome => {
+ if (game.goals_for !== undefined && game.goals_against !== undefined) {
+ if (game.goals_for > game.goals_against) {
+ return "Win"
+ } else if (game.goals_for < game.goals_against) {
+ return "Loss"
+ }
+ return "Tie"
+ }
+ return "Unplayed"
+ }, [game.goals_for, game.goals_against])
+
+ return gameOutcome
+}
+
+export default useGameOutcome
diff --git a/src/hooks/useGameScoreColor.ts b/src/hooks/useGameScoreColor.ts
new file mode 100644
index 0000000..149da0e
--- /dev/null
+++ b/src/hooks/useGameScoreColor.ts
@@ -0,0 +1,35 @@
+import React from "react"
+import type { GameOutcome } from "types/GameOutcome"
+import { color } from "./useTheme"
+
+const useGameScoreColor = (gameOutcome: GameOutcome): string => {
+ const nonIosScoreColor = React.useMemo((): string => {
+ switch (gameOutcome) {
+ case "Win":
+ return "green"
+ case "Loss":
+ return "red"
+ case "Tie":
+ return "gray"
+ case "Unplayed":
+ return "transparent"
+ }
+ }, [gameOutcome])
+
+ const iosScoreColor = React.useMemo((): string => {
+ switch (gameOutcome) {
+ case "Win":
+ return "systemGreen"
+ case "Loss":
+ return "systemRed"
+ case "Tie":
+ return "systemGray"
+ case "Unplayed":
+ return "transparent"
+ }
+ }, [gameOutcome])
+
+ return color({ ios: iosScoreColor, other: nonIosScoreColor })
+}
+
+export default useGameScoreColor
diff --git a/src/hooks/useTheme.ts b/src/hooks/useTheme.ts
index ea0619d..5506171 100644
--- a/src/hooks/useTheme.ts
+++ b/src/hooks/useTheme.ts
@@ -1,20 +1,58 @@
+import React from "react"
import * as ReactNative from "react-native"
import * as ReactNavigationNative from "@react-navigation/native"
import type { ColorScheme } from "types/ColorScheme"
-const lightTheme = {
+export const color = ({
+ ios,
+ other,
+}: {
+ ios: string
+ other: string
+}): string => {
+ return ReactNative.Platform.OS === "ios"
+ ? (ReactNative.PlatformColor(ios) as unknown as string)
+ : other
+}
+
+interface AppTheme extends ReactNavigationNative.Theme {
+ // https://reactnavigation.org/docs/themes/#basic-usage
+ dark: boolean
+ colors: {
+ primary: string
+ background: string
+ card: string
+ text: string
+ border: string
+ notification: string
+
+ // additions
+ secondaryLabel: string
+ }
+}
+
+const lightTheme: AppTheme = {
...ReactNavigationNative.DefaultTheme,
colors: {
...ReactNavigationNative.DefaultTheme.colors,
- background: "#fff",
+ primary: color({ ios: "systemPurple", other: "purple" }),
+ secondaryLabel: color({ ios: "secondaryLabel", other: "gray" }),
},
}
-const darkTheme = ReactNavigationNative.DarkTheme
-
-const useTheme = (): ReactNavigationNative.Theme => {
- const colorScheme: ColorScheme = ReactNative.useColorScheme()
+const darkTheme: AppTheme = {
+ ...ReactNavigationNative.DarkTheme,
+ colors: {
+ ...ReactNavigationNative.DarkTheme.colors,
+ primary: color({ ios: "systemPurple", other: "purple" }),
+ secondaryLabel: color({ ios: "secondaryLabel", other: "gray" }),
+ },
+}
+// We don't test other color schemes; it doesn't seem worth the effort.
+// By default, only light is tested.
+//* c8 ignore start */
+const themeFromColorScheme = (colorScheme: ColorScheme): AppTheme => {
switch (colorScheme) {
case "light":
return lightTheme
@@ -24,5 +62,17 @@ const useTheme = (): ReactNavigationNative.Theme => {
return lightTheme
}
}
+//* c8 ignore end */
+
+const useTheme = (): AppTheme => {
+ const colorScheme: ColorScheme = ReactNative.useColorScheme()
+
+ const theme = React.useMemo(
+ () => themeFromColorScheme(colorScheme),
+ [colorScheme],
+ )
+
+ return theme
+}
export default useTheme
diff --git a/src/types/GameOutcome.ts b/src/types/GameOutcome.ts
new file mode 100644
index 0000000..89bd484
--- /dev/null
+++ b/src/types/GameOutcome.ts
@@ -0,0 +1 @@
+export type GameOutcome = "Win" | "Loss" | "Tie" | "Unplayed"
diff --git a/src/types/jest.d.ts b/src/types/jest.d.ts
index a633213..9987624 100644
--- a/src/types/jest.d.ts
+++ b/src/types/jest.d.ts
@@ -4,8 +4,7 @@
declare namespace jest {
interface Matchers<_R> {
toShowText(text: string): CustomMatcherResult
- toShowTestID(text: string): CustomMatcherResult
- toHaveNavigationBarTitle(title: string): CustomMatcherResult
+ toShowTestId(text: string): CustomMatcherResult
}
}