From 6965b14659aa6cc9252c1f4c51f08ef060c9599f Mon Sep 17 00:00:00 2001 From: NinadAmane Date: Wed, 8 Jul 2026 23:22:45 +0530 Subject: [PATCH] test(GeneratorClient): add type-compiler validation and schema constraints test suite --- .../navbar.responsive-breakpoints.test.tsx | 6 +- .../GeneratorClient.type-compiler.test.tsx | 109 ++++++++++++++++++ 2 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 app/generator/GeneratorClient.type-compiler.test.tsx diff --git a/app/components/navbar.responsive-breakpoints.test.tsx b/app/components/navbar.responsive-breakpoints.test.tsx index b347e3531..eceb6568b 100644 --- a/app/components/navbar.responsive-breakpoints.test.tsx +++ b/app/components/navbar.responsive-breakpoints.test.tsx @@ -142,14 +142,14 @@ describe('Navbar Responsive Breakpoints & Menu Toggle', () => { expect(screen.getByRole('button', { name: 'Open menu' })).toBeDefined(); }); - it('4. Hides the desktop nav row on mobile and only reveals mobile hamburger controls, via complementary md: classes', () => { + it('4. Hides the desktop nav row on mobile and only reveals mobile hamburger controls, via complementary lg: classes', () => { const { container } = render(); - const desktopNavRow = container.querySelector('.hidden.items-center.gap-2.md\\:flex'); + const desktopNavRow = container.querySelector('.hidden.items-center.gap-2.lg\\:flex'); expect(desktopNavRow).toBeInTheDocument(); const mobileControls = container.querySelector( - '.md\\:hidden.inline-flex.items-center.justify-center.gap-1' + '.lg\\:hidden.inline-flex.items-center.justify-center.gap-1' ); expect(mobileControls).toBeInTheDocument(); }); diff --git a/app/generator/GeneratorClient.type-compiler.test.tsx b/app/generator/GeneratorClient.type-compiler.test.tsx new file mode 100644 index 000000000..83fe2268d --- /dev/null +++ b/app/generator/GeneratorClient.type-compiler.test.tsx @@ -0,0 +1,109 @@ +import { describe, expectTypeOf, it } from 'vitest'; +import { GeneratorClient } from './GeneratorClient'; +import type { + GeneratorState, + Technology, + Social, + TechCategory, + SocialCategory, + IconType, +} from './types'; +import type { + GitHubUser, + GitHubRepo, + GitHubSocialAccount, + ImportedData, +} from './utils/githubMapper'; +import { mapGitHubData } from './utils/githubMapper'; + +describe('GeneratorClient TypeScript Compiler Validation', () => { + // 1. Use type-testing assertions (expectTypeOf) to enforce field property configurations. + it('enforces field property configurations of GeneratorState', () => { + expectTypeOf().toEqualTypeOf(); + expectTypeOf().toEqualTypeOf(); + expectTypeOf().toEqualTypeOf(); + expectTypeOf().toEqualTypeOf(); + expectTypeOf().toEqualTypeOf>(); + expectTypeOf().toEqualTypeOf(); + expectTypeOf().toEqualTypeOf(); + expectTypeOf().toEqualTypeOf(); + expectTypeOf().toEqualTypeOf(); + expectTypeOf().toEqualTypeOf(); + expectTypeOf().toEqualTypeOf(); + expectTypeOf().toEqualTypeOf(); + expectTypeOf().toEqualTypeOf<'top' | 'middle' | 'bottom'>(); + }); + + // 2. Assert that invalid prop parameters are blocked during static type checking. + it('blocks invalid prop parameters during static type checking', () => { + // GeneratorClient has no props + expectTypeOf(GeneratorClient).toBeFunction(); + + void ({ + name: 'John Doe', + description: 'Bio details', + selectedTechs: [], + selectedSocials: [], + socialLinks: {}, + githubUsername: 'john', + showCommitPulse: true, + commitPulseAccent: '#ff0000', + showRepoSpotlight: false, + spotlightRepo: '', + showSnakeGraph: false, + showPacmanGraph: false, + // @ts-expect-error graphPlacement must be 'top' | 'middle' | 'bottom' + graphPlacement: 'left', + } satisfies GeneratorState); + + void ({ + name: 'John Doe', + description: 'Bio details', + // @ts-expect-error selectedTechs must be array of strings + selectedTechs: 'react', + selectedSocials: [], + socialLinks: {}, + githubUsername: 'john', + showCommitPulse: true, + commitPulseAccent: '#ff0000', + showRepoSpotlight: false, + spotlightRepo: '', + showSnakeGraph: false, + showPacmanGraph: false, + graphPlacement: 'top', + } satisfies GeneratorState); + }); + + // 3. Verify custom types accept optional/nullable values without compile errors. + it('verifies custom GitHub data types accept optional/nullable values without compile errors', () => { + const user: GitHubUser = { + name: null, + bio: null, + blog: null, + twitter_username: null, + email: null, + }; + + expectTypeOf(user.name).toEqualTypeOf(); + expectTypeOf(user.bio).toEqualTypeOf(); + }); + + // 4. Verify field configurations and types for Technology and Social interfaces. + it('verifies Technology and Social interfaces and categories', () => { + expectTypeOf().toEqualTypeOf(); + expectTypeOf().toEqualTypeOf(); + expectTypeOf().toEqualTypeOf(); + expectTypeOf().toEqualTypeOf(); + }); + + // 5. Verify schema validation constraints return strict validation reports. + it('verifies parameter constraints and return shapes on mapGitHubData', () => { + expectTypeOf(mapGitHubData).parameter(0).toEqualTypeOf(); + expectTypeOf(mapGitHubData).parameter(1).toEqualTypeOf(); + expectTypeOf(mapGitHubData).parameter(2).toEqualTypeOf(); + expectTypeOf(mapGitHubData).returns.toEqualTypeOf(); + + // @ts-expect-error mapGitHubData parameter 0 must satisfy GitHubUser structure + void mapGitHubData({ name: 123 }, [], []); + }); +});