From 63c1dcfd78c5be93537b559e2bf276b87443e7c5 Mon Sep 17 00:00:00 2001 From: Justin Wyne <1986068+wyne@users.noreply.github.com> Date: Sun, 29 Jun 2025 20:45:02 -0700 Subject: [PATCH 1/9] Claude init, test coverage --- .gitignore | 3 + CLAUDE.md | 103 ++++++++++++++++++++++++++++++++++ Contributing.md | 6 +- jest.config.ts | 25 ++++++++- package.json | 3 +- src/screens/AppInfoScreen.tsx | 8 ++- 6 files changed, 142 insertions(+), 6 deletions(-) create mode 100644 CLAUDE.md diff --git a/.gitignore b/.gitignore index 29ce2cd9..4dcd7b04 100644 --- a/.gitignore +++ b/.gitignore @@ -51,4 +51,7 @@ yarn-error.* # typescript *.tsbuildinfo +# test coverage +coverage/ + # @end expo-cli diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..7063d87c --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,103 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +ScorePad with Rounds is a React Native app built with Expo SDK 52 for tracking game scores with round-by-round history. The app is cross-platform (iOS, Android, Web) and uses TypeScript throughout. + +## Development Commands + +### Setup +```bash +nvm use # Use correct Node version +npx react-native-clean-project # Clean project if needed +npx expo prebuild # Generate native code +``` + +### Development +```bash +npm run dev # Start development server with APP_VARIANT=development +npm start # Standard expo start with dev client +npm run android # Run on Android +npm run ios # Run on iOS +``` + +### Testing and Linting +```bash +npm run test # Run all tests with Jest +npm run test:watch # Run tests in watch mode +npm run lint # Run ESLint and TypeScript checks +``` + +### Building +```bash +# Development builds +npx eas build --profile development-simulator --platform ios --local +npx eas build --profile development-simulator --platform android --local + +# Preview builds +npx eas build --platform ios --profile preview --local +npx eas build --platform android --profile preview --local + +# Production builds (remember to bump version in app.config.js) +npx expo-doctor +npx expo prebuild +npx eas build --platform ios +npx eas build --platform android +``` + +## Architecture + +### State Management +- **Redux Toolkit** with RTK Query for state management +- **Redux Persist** for data persistence with platform-specific storage: + - iOS: iCloud storage via custom `iCloudStorage` utility + - Android/Web: AsyncStorage +- Three main slices: + - `GamesSlice`: Game entities with rounds, players, and metadata + - `PlayersSlice`: Player entities with scores per round + - `SettingsSlice`: App settings and preferences + +### Navigation +- **React Navigation v6** with native stack navigator +- Main screens: List (Home), Game, Settings, Share, EditPlayer, Onboarding, AppInfo +- Custom headers for each screen using dedicated header components + +### Key Components Structure +- `src/components/`: Reusable UI components organized by feature + - `PlayerTiles/AdditionTile/`: Complex score display with animations + - `Sheets/`: Bottom sheet modals with context providers + - `Headers/`: Custom navigation headers + - `Interactions/`: Touch interaction handling (HalfTap, Swipe) +- `src/screens/`: Main screen components +- `redux/`: State management with typed hooks and selectors + +### Platform-Specific Features +- App variants for development/preview/production with different bundle IDs +- Firebase Analytics and Crashlytics integration +- iCloud document storage on iOS +- Gesture handling with react-native-gesture-handler and react-native-reanimated + +### Testing +- Jest with React Native Testing Library +- Custom mocks for Firebase, AsyncStorage, and react-native-video +- Test files co-located with source files using `.test.ts(x)` suffix + +## Code Style +- ESLint with TypeScript rules, import ordering, and Prettier integration +- Single quotes, semicolons required +- Alphabetical import ordering with React imports first +- No disabled tests, imports organized by type (builtin, external, internal, etc.) + +## Firebase Integration +- Analytics can be disabled via `EXPO_PUBLIC_FIREBASE_ANALYTICS=false` +- Debug mode available with simulator flags: + - Analytics: `-FIRAnalyticsDebugEnabled` + - Crashlytics: `-FIRDebugEnabled` + +## Development Notes +- Use `npx expo start --dev-client` for development with React DevTools +- Android development requires JDK 17 +- Version bumping required in `app.config.js` for production builds +- EAS CLI used for building and submitting to stores \ No newline at end of file diff --git a/Contributing.md b/Contributing.md index c1a40a66..4e4cbbf1 100644 --- a/Contributing.md +++ b/Contributing.md @@ -67,9 +67,9 @@ Use a development build from above, then: `npx expo start --dev-client` ## Publish -Apple: `eas submit -p ios` or `eas submit -p ios --non-interactive` +Apple: `npx eas submit -p ios` or `npx eas submit -p ios --non-interactive` -Android: `eas submit -p android --changes-not-sent-for-review` +Android: `npx eas submit -p android --changes-not-sent-for-review` ## Debug @@ -81,4 +81,4 @@ Then use the dev client to launch React Dev Tools or debug JS remotely. ### EAS -Debug eas config settings: `eas config --platform=ios --profile=development` +Debug eas config settings: `npx eas config --platform=ios --profile=development` diff --git a/jest.config.ts b/jest.config.ts index 52990c35..172fc72b 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -16,7 +16,30 @@ const config: Config = { ], moduleNameMapper: { '^react-native-video$': '__mocks__/react-native-video.js' - } + }, + collectCoverage: true, + coverageDirectory: 'coverage', + collectCoverageFrom: [ + 'src/**/*.{ts,tsx}', + 'redux/**/*.{ts,tsx}', + '!src/**/*.test.{ts,tsx}', + '!redux/**/*.test.{ts,tsx}', + '!src/**/*.d.ts', + '!src/**/index.{ts,tsx}', + '!coverage/**', + '!node_modules/**', + '!**/__mocks__/**', + '!**/vendor/**', + ], + coverageReporters: ['text', 'lcov', 'html'], + coverageThreshold: { + global: { + branches: 50, + functions: 50, + lines: 50, + statements: 50, + }, + }, }; export default config; diff --git a/package.json b/package.json index d61499da..7de10202 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,8 @@ "dev": "APP_VARIANT=development expo start", "lint": "eslint . ; tsc", "test": "jest --silent", - "test:watch": "jest --watch" + "test:watch": "jest --watch", + "test:coverage": "jest --coverage --silent" }, "dependencies": { "@babel/plugin-transform-react-jsx": "^7.22.5", diff --git a/src/screens/AppInfoScreen.tsx b/src/screens/AppInfoScreen.tsx index 3620dd92..8bd64143 100644 --- a/src/screens/AppInfoScreen.tsx +++ b/src/screens/AppInfoScreen.tsx @@ -112,7 +112,13 @@ const AppInfoScreen: React.FunctionComponent = ({ navigation }) => {
- + + + + +