The jollywhoppers homepage ๐Ÿฌ๐Ÿ”

refactor: reorganize project structure and add comprehensive documentation

- Organize components into subdirectories by type (layout, cards, sections, ui)
- Centralize TypeScript types in src/lib/types/
- Move documentation files to docs/ directory
- Create comprehensive PROJECT_STRUCTURE.md guide
- Add README files for lib/, utils/, tests/, and config/
- Set up test directory structure (unit, integration, e2e)
- Reorganize assets with icons subdirectory
- Fix favicon import path in layout
- Update component exports and imports to reflect new structure

This reorganization improves maintainability, discoverability, and follows
SvelteKit best practices for larger projects.

ewancroft.uk 3220aee2 dd86b304

verified
COMPONENTS.md docs/COMPONENTS.md
LUCIDE_ICONS.md docs/LUCIDE_ICONS.md
+266
PROJECT_STRUCTURE.md
··· 1 + # Jolly Whoppers - Project Structure 2 + 3 + This document provides a comprehensive overview of the project's directory structure and organization. 4 + 5 + ## Project Root 6 + 7 + ``` 8 + jollywhoppers/ 9 + โ”œโ”€โ”€ .git/ # Git repository data 10 + โ”œโ”€โ”€ .svelte-kit/ # SvelteKit build artifacts (generated) 11 + โ”œโ”€โ”€ .tangled/ # Tangled-specific files 12 + โ”œโ”€โ”€ .vscode/ # VS Code workspace settings 13 + โ”œโ”€โ”€ config/ # Additional configuration files 14 + โ”œโ”€โ”€ docs/ # Project documentation 15 + โ”œโ”€โ”€ node_modules/ # Dependencies (generated) 16 + โ”œโ”€โ”€ src/ # Source code 17 + โ”œโ”€โ”€ static/ # Static assets served at root 18 + โ”œโ”€โ”€ tests/ # Test files 19 + โ”œโ”€โ”€ .gitignore # Git ignore patterns 20 + โ”œโ”€โ”€ .npmrc # npm configuration 21 + โ”œโ”€โ”€ .prettierignore # Prettier ignore patterns 22 + โ”œโ”€โ”€ .prettierrc # Prettier configuration 23 + โ”œโ”€โ”€ LICENSE # Project license (AGPL-3.0) 24 + โ”œโ”€โ”€ package.json # Project dependencies and scripts 25 + โ”œโ”€โ”€ pnpm-lock.yaml # pnpm lock file 26 + โ”œโ”€โ”€ pnpm-workspace.yaml # pnpm workspace configuration 27 + โ”œโ”€โ”€ PROJECT_STRUCTURE.md # This file 28 + โ”œโ”€โ”€ README.md # Project README 29 + โ”œโ”€โ”€ svelte.config.js # SvelteKit configuration 30 + โ”œโ”€โ”€ tsconfig.json # TypeScript configuration 31 + โ””โ”€โ”€ vite.config.ts # Vite build configuration 32 + ``` 33 + 34 + ## Source Directory (`src/`) 35 + 36 + The main application source code. 37 + 38 + ``` 39 + src/ 40 + โ”œโ”€โ”€ lib/ # Shared library code 41 + โ”‚ โ”œโ”€โ”€ assets/ # Static assets 42 + โ”‚ โ”‚ โ”œโ”€โ”€ brand/ # Brand assets (logos) 43 + โ”‚ โ”‚ โ”œโ”€โ”€ fonts/ # Custom fonts 44 + โ”‚ โ”‚ โ”œโ”€โ”€ icons/ # Icon files 45 + โ”‚ โ”‚ โ””โ”€โ”€ images/ # Image files 46 + โ”‚ โ”œโ”€โ”€ components/ # Svelte components 47 + โ”‚ โ”‚ โ”œโ”€โ”€ cards/ # Card components 48 + โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ MemberCard.svelte 49 + โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ ProjectCard.svelte 50 + โ”‚ โ”‚ โ”œโ”€โ”€ layout/ # Layout components 51 + โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ Header.svelte 52 + โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ Hero.svelte 53 + โ”‚ โ”‚ โ”œโ”€โ”€ sections/ # Section components 54 + โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ About.svelte 55 + โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ MemberGrid.svelte 56 + โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ ProjectGrid.svelte 57 + โ”‚ โ”‚ โ”œโ”€โ”€ ui/ # UI components 58 + โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ Avatar.svelte 59 + โ”‚ โ”‚ โ””โ”€โ”€ index.ts # Component exports 60 + โ”‚ โ”œโ”€โ”€ services/ # Business logic services 61 + โ”‚ โ”‚ โ””โ”€โ”€ atproto/ # AT Protocol integration 62 + โ”‚ โ”‚ โ”œโ”€โ”€ agents.ts 63 + โ”‚ โ”‚ โ”œโ”€โ”€ cache.ts 64 + โ”‚ โ”‚ โ”œโ”€โ”€ index.ts 65 + โ”‚ โ”‚ โ”œโ”€โ”€ list.ts 66 + โ”‚ โ”‚ โ”œโ”€โ”€ README.md 67 + โ”‚ โ”‚ โ””โ”€โ”€ types.ts 68 + โ”‚ โ”œโ”€โ”€ styles/ # Global styles 69 + โ”‚ โ”‚ โ”œโ”€โ”€ open-props.css 70 + โ”‚ โ”‚ โ””โ”€โ”€ root-colours.css 71 + โ”‚ โ”œโ”€โ”€ types/ # TypeScript type definitions 72 + โ”‚ โ”‚ โ”œโ”€โ”€ components.ts 73 + โ”‚ โ”‚ โ””โ”€โ”€ index.ts 74 + โ”‚ โ”œโ”€โ”€ utils/ # Utility functions 75 + โ”‚ โ”‚ โ””โ”€โ”€ README.md 76 + โ”‚ โ”œโ”€โ”€ constants.ts # Application constants 77 + โ”‚ โ”œโ”€โ”€ index.ts # Main library exports 78 + โ”‚ โ””โ”€โ”€ README.md # Library documentation 79 + โ”œโ”€โ”€ routes/ # SvelteKit routes 80 + โ”‚ โ”œโ”€โ”€ +layout.svelte # Root layout 81 + โ”‚ โ”œโ”€โ”€ +layout.ts # Layout load function 82 + โ”‚ โ”œโ”€โ”€ +page.server.ts # Server-side page logic 83 + โ”‚ โ””โ”€โ”€ +page.svelte # Home page 84 + โ”œโ”€โ”€ app.d.ts # TypeScript app definitions 85 + โ””โ”€โ”€ app.html # HTML template 86 + ``` 87 + 88 + ## Tests Directory (`tests/`) 89 + 90 + All test files organized by test type. 91 + 92 + ``` 93 + tests/ 94 + โ”œโ”€โ”€ unit/ # Unit tests 95 + โ”‚ โ””โ”€โ”€ README.md 96 + โ”œโ”€โ”€ integration/ # Integration tests 97 + โ”‚ โ””โ”€โ”€ README.md 98 + โ”œโ”€โ”€ e2e/ # End-to-end tests 99 + โ”‚ โ””โ”€โ”€ README.md 100 + โ””โ”€โ”€ README.md # Testing documentation 101 + ``` 102 + 103 + ## Documentation Directory (`docs/`) 104 + 105 + Project documentation files. 106 + 107 + ``` 108 + docs/ 109 + โ”œโ”€โ”€ COMPONENTS.md # Component documentation 110 + โ””โ”€โ”€ LUCIDE_ICONS.md # Icon usage documentation 111 + ``` 112 + 113 + ## Configuration Directory (`config/`) 114 + 115 + Additional configuration files (most configs remain at root for tool compatibility). 116 + 117 + ``` 118 + config/ 119 + โ””โ”€โ”€ README.md # Configuration documentation 120 + ``` 121 + 122 + ## Static Directory (`static/`) 123 + 124 + Static files served at the root URL. 125 + 126 + ``` 127 + static/ 128 + โ””โ”€โ”€ robots.txt # Search engine crawler instructions 129 + ``` 130 + 131 + ## Key Files 132 + 133 + ### Root Configuration Files 134 + 135 + - **`package.json`** - Project metadata, dependencies, and npm scripts 136 + - **`tsconfig.json`** - TypeScript compiler configuration 137 + - **`svelte.config.js`** - SvelteKit framework configuration 138 + - **`vite.config.ts`** - Vite build tool configuration 139 + - **`.prettierrc`** - Code formatting rules 140 + - **`.gitignore`** - Files to exclude from Git 141 + 142 + ### Application Entry Points 143 + 144 + - **`src/app.html`** - HTML template wrapper 145 + - **`src/routes/+layout.svelte`** - Root layout component 146 + - **`src/routes/+page.svelte`** - Home page component 147 + - **`src/lib/index.ts`** - Main library exports 148 + 149 + ## Component Organization 150 + 151 + Components are organized by type: 152 + 153 + 1. **Layout Components** (`components/layout/`) 154 + - Page structure components (Header, Footer, Hero) 155 + - Define overall page layout 156 + 157 + 2. **Card Components** (`components/cards/`) 158 + - Reusable card designs (ProjectCard, MemberCard) 159 + - Display individual items in a consistent format 160 + 161 + 3. **Section Components** (`components/sections/`) 162 + - Major page sections (ProjectGrid, MemberGrid, About) 163 + - Compose cards and content into cohesive sections 164 + 165 + 4. **UI Components** (`components/ui/`) 166 + - Generic, reusable UI elements (Avatar, Button, Input) 167 + - Shared across multiple contexts 168 + 169 + ## Type Organization 170 + 171 + Types are centralized in `src/lib/types/`: 172 + 173 + - **`components.ts`** - Component prop types 174 + - **`index.ts`** - Type re-exports for easy importing 175 + 176 + Import types using: 177 + ```typescript 178 + import type { Project, Member, AboutItem } from '$lib/types'; 179 + ``` 180 + 181 + ## Service Organization 182 + 183 + Services contain business logic and API integrations: 184 + 185 + - **`atproto/`** - AT Protocol (Bluesky) integration 186 + - List fetching 187 + - Profile data 188 + - Caching 189 + 190 + Add new services as subdirectories following the same pattern. 191 + 192 + ## Asset Organization 193 + 194 + Assets are categorized by type: 195 + 196 + - **`brand/`** - Logo, wordmarks, brand guidelines 197 + - **`icons/`** - Icon files (favicon, app icons) 198 + - **`images/`** - Photos, illustrations, graphics 199 + - **`fonts/`** - Custom web fonts 200 + 201 + ## Testing Organization 202 + 203 + Tests are organized by scope: 204 + 205 + - **`unit/`** - Test individual functions/components 206 + - **`integration/`** - Test multiple components working together 207 + - **`e2e/`** - Test complete user workflows 208 + 209 + ## Import Path Aliases 210 + 211 + The project uses `$lib` as an alias for `src/lib`: 212 + 213 + ```typescript 214 + // Instead of: import { Header } from '../../lib/components/Header.svelte' 215 + // Use: 216 + import { Header } from '$lib/components'; 217 + ``` 218 + 219 + ## Build Artifacts 220 + 221 + Generated files (not committed to Git): 222 + 223 + - **`.svelte-kit/`** - SvelteKit build output 224 + - **`node_modules/`** - npm dependencies 225 + - **`build/`** - Production build output (if generated) 226 + 227 + ## Best Practices 228 + 229 + 1. **Follow the structure** - Place files in their designated locations 230 + 2. **Use index files** - Simplify imports with barrel exports 231 + 3. **Keep it organized** - Create subdirectories as needed 232 + 4. **Document changes** - Update this file when structure changes 233 + 5. **Use TypeScript** - Define types for everything 234 + 6. **Test your code** - Write tests in the appropriate directory 235 + 236 + ## Adding New Features 237 + 238 + ### New Component 239 + 1. Create in appropriate `components/` subdirectory 240 + 2. Add to `components/index.ts` 241 + 3. Add tests in `tests/unit/components/` 242 + 243 + ### New Service 244 + 1. Create in `services/` subdirectory 245 + 2. Export from service index 246 + 3. Add tests in `tests/unit/services/` 247 + 248 + ### New Type 249 + 1. Add to appropriate file in `types/` 250 + 2. Export from `types/index.ts` 251 + 252 + ### New Utility 253 + 1. Create in `utils/` (organized by purpose) 254 + 2. Add tests in `tests/unit/utils/` 255 + 256 + ## Related Documentation 257 + 258 + - **`README.md`** - Project overview and getting started 259 + - **`src/lib/README.md`** - Library structure details 260 + - **`docs/COMPONENTS.md`** - Component usage guide 261 + - **`tests/README.md`** - Testing guidelines 262 + 263 + --- 264 + 265 + **Last Updated:** December 2025 266 + **Version:** 2.0 (Reorganized Structure)
+21
config/README.md
··· 1 + # Configuration Directory 2 + 3 + This directory is reserved for additional configuration files that don't need to be at the project root. 4 + 5 + ## Root Configuration Files 6 + 7 + The following configuration files remain at the project root for tool compatibility: 8 + - `.prettierrc` - Prettier formatting configuration 9 + - `.prettierignore` - Prettier ignore patterns 10 + - `.npmrc` - npm configuration 11 + - `tsconfig.json` - TypeScript configuration 12 + - `svelte.config.js` - SvelteKit configuration 13 + - `vite.config.ts` - Vite build tool configuration 14 + - `.gitignore` - Git ignore patterns 15 + 16 + ## Future Use 17 + 18 + Add non-root configuration files here, such as: 19 + - Environment-specific configs 20 + - Custom build configurations 21 + - Tool-specific settings that support non-root locations
+162
src/lib/README.md
··· 1 + # Library Directory Structure 2 + 3 + This directory contains all shared code, components, and resources for the application. 4 + 5 + ## Structure Overview 6 + 7 + ``` 8 + src/lib/ 9 + โ”œโ”€โ”€ assets/ # Static assets (images, icons, fonts, branding) 10 + โ”œโ”€โ”€ components/ # Reusable Svelte components 11 + โ”œโ”€โ”€ services/ # Business logic and API services 12 + โ”œโ”€โ”€ styles/ # Global styles and design tokens 13 + โ”œโ”€โ”€ types/ # TypeScript type definitions 14 + โ”œโ”€โ”€ utils/ # Utility functions and helpers 15 + โ”œโ”€โ”€ constants.ts # Application constants and configuration 16 + โ””โ”€โ”€ index.ts # Main library exports 17 + ``` 18 + 19 + ## Directory Details 20 + 21 + ### `assets/` - Static Assets 22 + Organized by asset type: 23 + - `assets/brand/` - Logo and brand assets 24 + - `assets/icons/` - Icon files (SVG, PNG) 25 + - `assets/images/` - Images and graphics 26 + - `assets/fonts/` - Custom font files 27 + 28 + ### `components/` - Svelte Components 29 + Organized by component type: 30 + - `components/layout/` - Layout components (Header, Hero, Footer) 31 + - `components/cards/` - Card components (ProjectCard, MemberCard) 32 + - `components/sections/` - Section components (ProjectGrid, MemberGrid, About) 33 + - `components/ui/` - Reusable UI components (Avatar, Button, Input) 34 + 35 + Each component directory should include: 36 + - Component `.svelte` files 37 + - Component-specific types (if needed) 38 + - Component index for exports 39 + 40 + ### `services/` - Business Logic 41 + Service modules organized by domain: 42 + - `services/atproto/` - AT Protocol integration 43 + - Add more services as needed (API clients, data fetching, etc.) 44 + 45 + ### `styles/` - Global Styles 46 + - `styles/open-props.css` - Open Props imports 47 + - `styles/root-colours.css` - Brand color tokens 48 + - Additional global styles as needed 49 + 50 + ### `types/` - TypeScript Types 51 + Centralized type definitions: 52 + - `types/components.ts` - Component prop types 53 + - `types/api.ts` - API response types (when needed) 54 + - `types/models.ts` - Data model types (when needed) 55 + 56 + ### `utils/` - Utilities 57 + Helper functions organized by purpose: 58 + - String manipulation 59 + - Date formatting 60 + - Validation 61 + - API helpers 62 + 63 + ## Import Patterns 64 + 65 + ### Aliased Imports 66 + Use the `$lib` alias for all library imports: 67 + 68 + ```typescript 69 + // Components 70 + import { Header, Hero, ProjectCard } from '$lib/components'; 71 + 72 + // Types 73 + import type { Project, Member } from '$lib/types'; 74 + 75 + // Services 76 + import { getListMembers } from '$lib/services/atproto'; 77 + 78 + // Utils 79 + import { formatDate } from '$lib/utils/date'; 80 + 81 + // Constants 82 + import { SITE_CONFIG, PROJECTS } from '$lib/constants'; 83 + ``` 84 + 85 + ### Direct Imports 86 + For more specific imports or tree-shaking: 87 + 88 + ```typescript 89 + import Header from '$lib/components/layout/Header.svelte'; 90 + import type { Project } from '$lib/types/components'; 91 + ``` 92 + 93 + ## Adding New Content 94 + 95 + ### Adding a Component 96 + 97 + 1. Create the component in the appropriate subdirectory 98 + 2. Add to the component's index.ts 99 + 3. Export from `components/index.ts` if widely used 100 + 101 + ```typescript 102 + // src/lib/components/ui/Button.svelte 103 + <script lang="ts"> 104 + // Component code 105 + </script> 106 + 107 + // src/lib/components/index.ts 108 + export { default as Button } from './ui/Button.svelte'; 109 + ``` 110 + 111 + ### Adding a Type 112 + 113 + 1. Add to appropriate file in `types/` 114 + 2. Export from `types/index.ts` 115 + 116 + ```typescript 117 + // src/lib/types/models.ts 118 + export type User = { 119 + id: string; 120 + name: string; 121 + }; 122 + 123 + // src/lib/types/index.ts 124 + export type { User } from './models'; 125 + ``` 126 + 127 + ### Adding a Utility 128 + 129 + 1. Create utility file in `utils/` 130 + 2. Export functions 131 + 3. Optionally add to `utils/index.ts` 132 + 133 + ```typescript 134 + // src/lib/utils/string.ts 135 + export function capitalize(str: string): string { 136 + return str.charAt(0).toUpperCase() + str.slice(1); 137 + } 138 + ``` 139 + 140 + ## Best Practices 141 + 142 + 1. **Organize by feature/type** - Group related code together 143 + 2. **Use index files** - Simplify imports with barrel exports 144 + 3. **Keep components focused** - Single responsibility principle 145 + 4. **Type everything** - Leverage TypeScript for safety 146 + 5. **Document complex code** - Add comments for clarity 147 + 6. **Test utilities** - Write unit tests for helpers 148 + 7. **Reuse components** - Build composable, reusable pieces 149 + 150 + ## File Naming Conventions 151 + 152 + - **Components**: PascalCase (e.g., `ProjectCard.svelte`) 153 + - **Types**: camelCase or PascalCase (e.g., `components.ts`) 154 + - **Utilities**: camelCase (e.g., `dateUtils.ts`) 155 + - **Constants**: SCREAMING_SNAKE_CASE in file (e.g., `SITE_CONFIG`) 156 + - **Files**: camelCase or kebab-case (e.g., `apiHelpers.ts` or `api-helpers.ts`) 157 + 158 + ## Related Documentation 159 + 160 + - See `docs/COMPONENTS.md` for detailed component documentation 161 + - See `docs/LUCIDE_ICONS.md` for icon usage 162 + - See `tests/README.md` for testing guidelines
src/lib/assets/favicon.svg src/lib/assets/icons/favicon.svg
src/lib/components/About.svelte src/lib/components/sections/About.svelte
src/lib/components/Avatar.svelte src/lib/components/ui/Avatar.svelte
src/lib/components/Header.svelte src/lib/components/layout/Header.svelte
src/lib/components/Hero.svelte src/lib/components/layout/Hero.svelte
src/lib/components/MemberCard.svelte src/lib/components/cards/MemberCard.svelte
+1 -1
src/lib/components/MemberGrid.svelte src/lib/components/sections/MemberGrid.svelte
··· 1 1 <script lang="ts"> 2 - import MemberCard from './MemberCard.svelte'; 2 + import MemberCard from '../cards/MemberCard.svelte'; 3 3 4 4 let { 5 5 title = 'Members',
src/lib/components/ProjectCard.svelte src/lib/components/cards/ProjectCard.svelte
+1 -1
src/lib/components/ProjectGrid.svelte src/lib/components/sections/ProjectGrid.svelte
··· 1 1 <script lang="ts"> 2 - import ProjectCard from './ProjectCard.svelte'; 2 + import ProjectCard from '../cards/ProjectCard.svelte'; 3 3 4 4 let { 5 5 title = 'Projects',
+16 -27
src/lib/components/index.ts
··· 1 1 // Component exports for easy importing 2 - export { default as Header } from './Header.svelte'; 3 - export { default as Hero } from './Hero.svelte'; 4 - export { default as ProjectCard } from './ProjectCard.svelte'; 5 - export { default as ProjectGrid } from './ProjectGrid.svelte'; 6 - export { default as MemberCard } from './MemberCard.svelte'; 7 - export { default as MemberGrid } from './MemberGrid.svelte'; 8 - export { default as About } from './About.svelte'; 9 - export { default as Avatar } from './Avatar.svelte'; 10 2 11 - // Types 12 - export type Project = { 13 - title: string; 14 - href?: string; 15 - // Optional project-specific fields 16 - disabled?: boolean; 17 - logo?: string; 18 - handle?: string; 19 - }; 3 + // Layout components 4 + export { default as Header } from './layout/Header.svelte'; 5 + export { default as Hero } from './layout/Hero.svelte'; 6 + 7 + // Card components 8 + export { default as ProjectCard } from './cards/ProjectCard.svelte'; 9 + export { default as MemberCard } from './cards/MemberCard.svelte'; 10 + 11 + // Section components 12 + export { default as ProjectGrid } from './sections/ProjectGrid.svelte'; 13 + export { default as MemberGrid } from './sections/MemberGrid.svelte'; 14 + export { default as About } from './sections/About.svelte'; 20 15 21 - export type Member = { 22 - title: string; 23 - href: string; 24 - avatar?: string; 25 - handle: string; 26 - }; 16 + // UI components 17 + export { default as Avatar } from './ui/Avatar.svelte'; 27 18 28 - export type AboutItem = { 29 - label: string; 30 - href?: string; 31 - }; 19 + // Re-export types for convenience 20 + export type { Project, Member, AboutItem } from '$lib/types';
+21
src/lib/types/components.ts
··· 1 + // Component type definitions 2 + export type Project = { 3 + title: string; 4 + href?: string; 5 + // Optional project-specific fields 6 + disabled?: boolean; 7 + logo?: string; 8 + handle?: string; 9 + }; 10 + 11 + export type Member = { 12 + title: string; 13 + href: string; 14 + avatar?: string; 15 + handle: string; 16 + }; 17 + 18 + export type AboutItem = { 19 + label: string; 20 + href?: string; 21 + };
+2
src/lib/types/index.ts
··· 1 + // Type exports for easy importing 2 + export type { Project, Member, AboutItem } from './components';
+71
src/lib/utils/README.md
··· 1 + # Utilities 2 + 3 + This directory contains utility functions and helper modules used throughout the application. 4 + 5 + ## Structure 6 + 7 + Create subdirectories as needed: 8 + 9 + ``` 10 + utils/ 11 + โ”œโ”€โ”€ date/ # Date manipulation utilities 12 + โ”œโ”€โ”€ string/ # String manipulation utilities 13 + โ”œโ”€โ”€ validation/ # Validation helpers 14 + โ”œโ”€โ”€ format/ # Formatting functions 15 + โ””โ”€โ”€ api/ # API helper functions 16 + ``` 17 + 18 + ## Example Utilities 19 + 20 + ### String Utilities (`utils/string.ts`) 21 + 22 + ```typescript 23 + export function slugify(text: string): string { 24 + return text 25 + .toLowerCase() 26 + .trim() 27 + .replace(/[^\w\s-]/g, '') 28 + .replace(/[\s_-]+/g, '-') 29 + .replace(/^-+|-+$/g, ''); 30 + } 31 + 32 + export function truncate(text: string, length: number): string { 33 + if (text.length <= length) return text; 34 + return text.slice(0, length) + '...'; 35 + } 36 + ``` 37 + 38 + ### Date Utilities (`utils/date.ts`) 39 + 40 + ```typescript 41 + export function formatDate(date: Date): string { 42 + return new Intl.DateTimeFormat('en-US', { 43 + year: 'numeric', 44 + month: 'long', 45 + day: 'numeric' 46 + }).format(date); 47 + } 48 + 49 + export function isValidDate(date: string): boolean { 50 + return !isNaN(Date.parse(date)); 51 + } 52 + ``` 53 + 54 + ## Best Practices 55 + 56 + 1. **Keep functions pure** - No side effects when possible 57 + 2. **Single responsibility** - Each function does one thing well 58 + 3. **Type everything** - Use TypeScript for type safety 59 + 4. **Document complex logic** - Add JSDoc comments 60 + 5. **Test utilities** - Write unit tests for all utilities 61 + 6. **Export as needed** - Create index.ts for convenient imports 62 + 63 + ## Usage 64 + 65 + ```typescript 66 + // Import specific utilities 67 + import { slugify, truncate } from '$lib/utils/string'; 68 + 69 + // Or import from index if available 70 + import { formatDate, slugify } from '$lib/utils'; 71 + ```
+1 -1
src/routes/+layout.svelte
··· 1 1 <script lang="ts"> 2 - import favicon from '$lib/assets/favicon.svg'; 2 + import favicon from '$lib/assets/icons/favicon.svg'; 3 3 import '$lib/styles/open-props.css'; 4 4 import '$lib/styles/root-colours.css'; 5 5
+91
tests/README.md
··· 1 + # Tests 2 + 3 + This directory contains all tests for the Jolly Whoppers project. 4 + 5 + ## Structure 6 + 7 + ``` 8 + tests/ 9 + โ”œโ”€โ”€ unit/ # Unit tests for components, services, and utilities 10 + โ”œโ”€โ”€ integration/ # Integration tests for multiple components/modules 11 + โ””โ”€โ”€ e2e/ # End-to-end tests for complete user workflows 12 + ``` 13 + 14 + ## Test Types 15 + 16 + ### Unit Tests (`tests/unit/`) 17 + - Test individual components in isolation 18 + - Test utility functions and services 19 + - Fast execution, no external dependencies 20 + - Mock all external dependencies 21 + 22 + ### Integration Tests (`tests/integration/`) 23 + - Test multiple components working together 24 + - Test API integrations 25 + - Test page-level functionality 26 + - May use test databases or mock services 27 + 28 + ### E2E Tests (`tests/e2e/`) 29 + - Test complete user workflows in a real browser 30 + - Test the application as end users would use it 31 + - Slowest but most comprehensive 32 + - Use actual application environment 33 + 34 + ## Setup 35 + 36 + To set up testing, install a test framework: 37 + 38 + ```bash 39 + # Vitest (recommended for unit/integration tests) 40 + pnpm add -D vitest @testing-library/svelte 41 + 42 + # Playwright (recommended for e2e tests) 43 + pnpm add -D @playwright/test 44 + ``` 45 + 46 + ## Running Tests 47 + 48 + Add these scripts to `package.json`: 49 + 50 + ```json 51 + { 52 + "scripts": { 53 + "test": "vitest", 54 + "test:unit": "vitest run tests/unit", 55 + "test:integration": "vitest run tests/integration", 56 + "test:e2e": "playwright test", 57 + "test:coverage": "vitest run --coverage" 58 + } 59 + } 60 + ``` 61 + 62 + Then run: 63 + 64 + ```bash 65 + # Run all tests 66 + pnpm test 67 + 68 + # Run specific test types 69 + pnpm test:unit 70 + pnpm test:integration 71 + pnpm test:e2e 72 + 73 + # Run with coverage 74 + pnpm test:coverage 75 + ``` 76 + 77 + ## Best Practices 78 + 79 + 1. **Write tests as you develop** - Don't wait until the end 80 + 2. **Test behavior, not implementation** - Focus on what the code does, not how 81 + 3. **Keep tests isolated** - Each test should be independent 82 + 4. **Use descriptive names** - Test names should explain what they test 83 + 5. **Maintain tests** - Update tests when features change 84 + 6. **Aim for good coverage** - But don't obsess over 100% 85 + 86 + ## Resources 87 + 88 + - [Vitest Documentation](https://vitest.dev/) 89 + - [Testing Library](https://testing-library.com/) 90 + - [Playwright Documentation](https://playwright.dev/) 91 + - [SvelteKit Testing Guide](https://kit.svelte.dev/docs/testing)
+36
tests/e2e/README.md
··· 1 + # End-to-End Tests 2 + 3 + Place end-to-end tests here for testing complete user workflows in a browser environment. 4 + 5 + ## Structure 6 + 7 + ``` 8 + e2e/ 9 + โ”œโ”€โ”€ user-flows/ # Complete user journey tests 10 + โ”œโ”€โ”€ pages/ # Page-specific e2e tests 11 + โ””โ”€โ”€ fixtures/ # Test data and fixtures 12 + ``` 13 + 14 + ## Tools 15 + 16 + Consider using: 17 + - [Playwright](https://playwright.dev/) - Modern e2e testing framework 18 + - [Cypress](https://www.cypress.io/) - Popular e2e testing framework 19 + 20 + ## Example (Playwright) 21 + 22 + ```typescript 23 + import { test, expect } from '@playwright/test'; 24 + 25 + test('home page loads correctly', async ({ page }) => { 26 + await page.goto('/'); 27 + await expect(page.locator('h1')).toContainText('Jolly Whoppers'); 28 + await expect(page.locator('.project-grid')).toBeVisible(); 29 + }); 30 + ``` 31 + 32 + ## Running Tests 33 + 34 + ```bash 35 + pnpm test:e2e 36 + ```
+34
tests/integration/README.md
··· 1 + # Integration Tests 2 + 3 + Place integration tests here for testing multiple components, modules, or services working together. 4 + 5 + ## Structure 6 + 7 + ``` 8 + integration/ 9 + โ”œโ”€โ”€ api/ # API integration tests 10 + โ”œโ”€โ”€ pages/ # Page-level integration tests 11 + โ””โ”€โ”€ flows/ # User flow integration tests 12 + ``` 13 + 14 + ## Example 15 + 16 + ```typescript 17 + import { describe, it, expect } from 'vitest'; 18 + import { render } from '@testing-library/svelte'; 19 + import HomePage from '$lib/routes/+page.svelte'; 20 + 21 + describe('Home Page Integration', () => { 22 + it('displays all sections correctly', () => { 23 + const { getByText } = render(HomePage); 24 + expect(getByText('Projects')).toBeTruthy(); 25 + expect(getByText('About')).toBeTruthy(); 26 + }); 27 + }); 28 + ``` 29 + 30 + ## Running Tests 31 + 32 + ```bash 33 + pnpm test:integration 34 + ```
+33
tests/unit/README.md
··· 1 + # Unit Tests 2 + 3 + Place unit tests here for individual components, functions, and modules. 4 + 5 + ## Structure 6 + 7 + ``` 8 + unit/ 9 + โ”œโ”€โ”€ components/ # Component unit tests 10 + โ”œโ”€โ”€ services/ # Service unit tests 11 + โ””โ”€โ”€ utils/ # Utility function tests 12 + ``` 13 + 14 + ## Example 15 + 16 + ```typescript 17 + import { describe, it, expect } from 'vitest'; 18 + import { render } from '@testing-library/svelte'; 19 + import Header from '$lib/components/layout/Header.svelte'; 20 + 21 + describe('Header', () => { 22 + it('renders correctly', () => { 23 + const { container } = render(Header); 24 + expect(container).toBeTruthy(); 25 + }); 26 + }); 27 + ``` 28 + 29 + ## Running Tests 30 + 31 + ```bash 32 + pnpm test:unit 33 + ```