From 7031ec56d42fafbda00329c03fb22561f137674d Mon Sep 17 00:00:00 2001 From: Xavier Saliniere Date: Tue, 2 Sep 2025 08:02:00 -0400 Subject: [PATCH 1/2] chore: remove low value tests --- src/app/__tests__/page.test.tsx | 5 - .../__tests__/LoadSequence.test.tsx | 53 -- .../about-me/__tests__/AboutMe.test.tsx | 26 - .../__tests__/BuildInfoOutput.test.tsx | 30 -- .../__tests__/ContactOutput.test.tsx | 9 - .../cmd-outputs/__tests__/HelpOutput.test.tsx | 49 -- .../__tests__/IntroOutput.test.tsx | 16 - .../__tests__/UnknownCmdOutput.test.tsx | 21 - .../__tests__/Web3MissionOutput.test.tsx | 11 - .../__tests__/WhoamiOutput.test.tsx | 9 - .../common/__tests__/KeyListener.test.tsx | 28 +- .../contact/__tests__/Contact.test.tsx | 26 - .../layout/__tests__/Header.test.tsx | 57 -- .../layout/__tests__/TermWindow.test.tsx | 43 -- .../terminal/__tests__/CmdLink.test.tsx | 7 - .../__tests__/TerminalEmulator.test.tsx | 85 +-- .../__tests__/TerminalPrompt.test.tsx | 507 +----------------- src/constants/__tests__/commands.test.ts | 58 -- src/constants/__tests__/lang.test.ts | 50 -- src/constants/__tests__/routes.test.ts | 50 -- src/contexts/__tests__/AppContext.test.tsx | 62 --- .../__tests__/TerminalContext.test.tsx | 71 +-- src/hooks/__tests__/useIsPrerender.test.ts | 34 -- src/hooks/__tests__/useKeyHandler.test.ts | 88 +-- src/hooks/__tests__/useTermRouter.test.ts | 61 --- src/i18n/__tests__/intl.test.ts | 57 -- src/i18n/__tests__/navigation.test.ts | 54 -- src/i18n/__tests__/request.test.ts | 98 +--- src/i18n/__tests__/routing.test.ts | 30 +- src/types/__tests__/routing.test.ts | 85 --- src/types/__tests__/terminal.test.ts | 82 --- src/utils/__tests__/chunk-retry.test.ts | 41 -- src/utils/__tests__/compare-utils.test.ts | 78 --- src/utils/__tests__/helpers.test.ts | 45 -- src/utils/__tests__/metadata-utils.test.ts | 122 ----- src/utils/__tests__/terminal-utils.test.ts | 44 -- 36 files changed, 18 insertions(+), 2174 deletions(-) diff --git a/src/app/__tests__/page.test.tsx b/src/app/__tests__/page.test.tsx index 268f145..2f07d0c 100644 --- a/src/app/__tests__/page.test.tsx +++ b/src/app/__tests__/page.test.tsx @@ -14,9 +14,4 @@ describe('RootPage', () => { expect(screen.getByTestId('load-sequence')).toBeInTheDocument(); expect(screen.getByText('LoadSequence Component')).toBeInTheDocument(); }); - - it('should match snapshot', () => { - const { container } = render(); - expect(container.firstChild).toMatchSnapshot(); - }); }); diff --git a/src/components/__tests__/LoadSequence.test.tsx b/src/components/__tests__/LoadSequence.test.tsx index c97081e..e51387a 100644 --- a/src/components/__tests__/LoadSequence.test.tsx +++ b/src/components/__tests__/LoadSequence.test.tsx @@ -55,34 +55,6 @@ describe('LoadSequence', () => { expect(cursor).toHaveClass('animate-pulse'); }); - it('should eventually show first step', async () => { - render(); - - // Wait for the first step to appear - await waitFor( - () => { - expect( - screen.getByText('> Detecting user locale...'), - ).toBeInTheDocument(); - }, - { timeout: 1000 }, - ); - }); - - it('should eventually show locale detection step', async () => { - render(); - - // Wait for the locale detection step - await waitFor( - () => { - expect( - screen.getByText('> Detecting user locale...'), - ).toBeInTheDocument(); - }, - { timeout: 2000 }, - ); - }); - it('should detect English locale from browser by default', async () => { render(); @@ -169,29 +141,4 @@ describe('LoadSequence', () => { { timeout: 3000 }, ); }); - - it('should handle partial locale codes correctly', async () => { - // Set navigator.language to a specific region code - Object.defineProperty(navigator, 'language', { - writable: true, - value: 'en-GB', - }); - - render(); - - // Should still detect as English - await waitFor( - () => { - expect( - screen.getByText('> Selecting proper locale [en]'), - ).toBeInTheDocument(); - }, - { timeout: 2000 }, - ); - }); - - it('should match snapshot', () => { - const { container } = render(); - expect(container.firstChild).toMatchSnapshot(); - }); }); diff --git a/src/components/about-me/__tests__/AboutMe.test.tsx b/src/components/about-me/__tests__/AboutMe.test.tsx index 3a41b5f..9865e07 100644 --- a/src/components/about-me/__tests__/AboutMe.test.tsx +++ b/src/components/about-me/__tests__/AboutMe.test.tsx @@ -8,30 +8,4 @@ describe('AboutMe', () => { expect(screen.getByText('about me / todo')).toBeInTheDocument(); }); - - it('should render as a div element', () => { - const { container } = render(); - - expect(container.firstChild).toBeInstanceOf(HTMLDivElement); - }); - - it('should have the expected content', () => { - const { container } = render(); - - expect(container.firstChild?.textContent).toBe('about me / todo'); - }); - - it('should render without any props', () => { - expect(() => render()).not.toThrow(); - }); - - it('should match snapshot', () => { - const { container } = render(); - - expect(container.firstChild).toMatchInlineSnapshot(` -
- about me / todo -
- `); - }); }); diff --git a/src/components/cmd-outputs/__tests__/BuildInfoOutput.test.tsx b/src/components/cmd-outputs/__tests__/BuildInfoOutput.test.tsx index 356b285..4853b6d 100644 --- a/src/components/cmd-outputs/__tests__/BuildInfoOutput.test.tsx +++ b/src/components/cmd-outputs/__tests__/BuildInfoOutput.test.tsx @@ -37,34 +37,4 @@ describe('BuildInfoOutput', () => { expect(screen.getByText('Build Time:')).toBeInTheDocument(); expect(screen.getByText('IPNS Name:')).toBeInTheDocument(); }); - - it('displays formatted build timestamp', () => { - render(); - - // The timestamp should be formatted as a locale string - const buildTimeElement = screen.getByText(/Build Time:/); - expect(buildTimeElement.parentElement).toHaveTextContent('Build Time:'); - }); - - it('displays IPNS hash when configured', () => { - render(); - - expect(screen.getByText('IPNS Name:')).toBeInTheDocument(); - expect( - screen.getByText( - /k51qzi5uqu5dh5kbbff1ucw3ksphpy3vxx4en4dbtfh90pvw4mzd8nfm5r5fnl/, - ), - ).toBeInTheDocument(); - }); - - it('handles missing environment variables gracefully', () => { - vi.stubGlobal('process', { - env: {}, - }); - - render(); - - expect(screen.getByText(/Unknown/)).toBeInTheDocument(); - expect(screen.getByText(/Not configured/)).toBeInTheDocument(); - }); }); diff --git a/src/components/cmd-outputs/__tests__/ContactOutput.test.tsx b/src/components/cmd-outputs/__tests__/ContactOutput.test.tsx index bf03be7..56ceafc 100644 --- a/src/components/cmd-outputs/__tests__/ContactOutput.test.tsx +++ b/src/components/cmd-outputs/__tests__/ContactOutput.test.tsx @@ -16,17 +16,8 @@ describe('ContactOutput', () => { cmdName: Command.Contact, }; - it('renders without crashing', () => { - const { container } = render(); - expect(container).toBeInTheDocument(); - }); - it('renders the Contact component', () => { render(); expect(screen.getByText('contact / todo')).toBeInTheDocument(); }); - - it('is a class component that extends Component', () => { - expect(ContactOutput.prototype.render).toBeDefined(); - }); }); diff --git a/src/components/cmd-outputs/__tests__/HelpOutput.test.tsx b/src/components/cmd-outputs/__tests__/HelpOutput.test.tsx index 0fce328..78a80ec 100644 --- a/src/components/cmd-outputs/__tests__/HelpOutput.test.tsx +++ b/src/components/cmd-outputs/__tests__/HelpOutput.test.tsx @@ -71,31 +71,6 @@ describe('HelpOutput', () => { vi.clearAllMocks(); }); - it('renders without crashing', () => { - const { container } = render(); - expect(container.firstChild).toBeInTheDocument(); - }); - - it('renders all commands from Commands constant', () => { - render(); - - Commands.forEach((cmd) => { - // Check that at least one button with the command name exists - const buttons = screen - .getAllByRole('button') - .filter((button) => button.textContent?.includes(cmd.name)); - expect(buttons.length).toBeGreaterThan(0); - }); - }); - - it('calls translation function for command descriptions', () => { - render(); - - Commands.forEach((cmd) => { - expect(mockT).toHaveBeenCalledWith(`cmds.${cmd.name}.description`); - }); - }); - it('renders command arguments when they exist', () => { render(); @@ -113,28 +88,4 @@ describe('HelpOutput', () => { expect(mockT).toHaveBeenCalledWith('cmds.test-cmd.argsDesc.arg1'); expect(mockT).toHaveBeenCalledWith('cmds.test-cmd.argsDesc.arg2'); }); - - it('handles commands without arguments gracefully', () => { - render(); - - // Commands without arguments should still render their main button - const helpButton = screen.getByTestId('cmd-link-help'); - const clearButton = screen.getByTestId('cmd-link-clear'); - expect(helpButton).toBeInTheDocument(); - expect(clearButton).toBeInTheDocument(); - }); - - it('renders proper typography variants', () => { - render(); - - const subtitleElements = screen.getAllByTestId('typography-subtitle3'); - expect(subtitleElements.length).toBeGreaterThan(0); - }); - - it('renders with proper CSS classes', () => { - const { container } = render(); - - const mainDiv = container.firstChild as HTMLElement; - expect(mainDiv).toHaveClass('flex', 'flex-col', 'gap-y-(--lsd-spacing-8)'); - }); }); diff --git a/src/components/cmd-outputs/__tests__/IntroOutput.test.tsx b/src/components/cmd-outputs/__tests__/IntroOutput.test.tsx index 4ddb2b4..d840d66 100644 --- a/src/components/cmd-outputs/__tests__/IntroOutput.test.tsx +++ b/src/components/cmd-outputs/__tests__/IntroOutput.test.tsx @@ -34,13 +34,6 @@ describe('IntroOutput', () => { vi.clearAllMocks(); }); - it('renders without crashing', () => { - const { container } = render( - , - ); - expect(container.firstChild).toBeInTheDocument(); - }); - it('renders welcome message', () => { render(); expect(mockTRich).toHaveBeenCalledWith( @@ -68,13 +61,4 @@ describe('IntroOutput', () => { // Check for part of the ASCII art content expect(asciiDiv).toHaveTextContent('_ __'); }); - - it('renders with proper CSS classes', () => { - const { container } = render( - , - ); - - const mainDiv = container.firstChild as HTMLElement; - expect(mainDiv).toHaveClass('flex', 'flex-col'); - }); }); diff --git a/src/components/cmd-outputs/__tests__/UnknownCmdOutput.test.tsx b/src/components/cmd-outputs/__tests__/UnknownCmdOutput.test.tsx index 2a5317f..de492f1 100644 --- a/src/components/cmd-outputs/__tests__/UnknownCmdOutput.test.tsx +++ b/src/components/cmd-outputs/__tests__/UnknownCmdOutput.test.tsx @@ -17,11 +17,6 @@ vi.mock('react-icons/pi', () => ({ })); describe('UnknownCmdOutput', () => { - it('renders without crashing', () => { - const { container } = render(); - expect(container.firstChild).toBeInTheDocument(); - }); - it('renders the command name', () => { const cmdName = 'invalidCommand'; render(); @@ -45,20 +40,4 @@ describe('UnknownCmdOutput', () => { const icon = screen.getByTestId('nervous-smiley-icon'); expect(icon).toHaveAttribute('data-size', '1.2rem'); }); - - it('renders with proper CSS classes', () => { - const { container } = render(); - - const mainDiv = container.firstChild as HTMLElement; - expect(mainDiv).toHaveClass('flex', 'items-center', 'gap-x-1'); - }); - - it('displays the full error message format', () => { - const cmdName = 'someCommand'; - render(); - - // Check that both the translation key and command name are present - expect(screen.getByText(/unknownCmdErr/)).toBeInTheDocument(); - expect(screen.getByText(/someCommand/)).toBeInTheDocument(); - }); }); diff --git a/src/components/cmd-outputs/__tests__/Web3MissionOutput.test.tsx b/src/components/cmd-outputs/__tests__/Web3MissionOutput.test.tsx index 4cd3c96..e88317c 100644 --- a/src/components/cmd-outputs/__tests__/Web3MissionOutput.test.tsx +++ b/src/components/cmd-outputs/__tests__/Web3MissionOutput.test.tsx @@ -16,19 +16,8 @@ describe('Web3MissionOutput', () => { cmdName: Command.Web3Mission, }; - it('renders without crashing', () => { - const { container } = render( - , - ); - expect(container).toBeInTheDocument(); - }); - it('renders the Web3Mission component', () => { render(); expect(screen.getByText('web3 mission / todo')).toBeInTheDocument(); }); - - it('is a class component that extends Component', () => { - expect(Web3MissionOutput.prototype.render).toBeDefined(); - }); }); diff --git a/src/components/cmd-outputs/__tests__/WhoamiOutput.test.tsx b/src/components/cmd-outputs/__tests__/WhoamiOutput.test.tsx index 1db3236..97e66e8 100644 --- a/src/components/cmd-outputs/__tests__/WhoamiOutput.test.tsx +++ b/src/components/cmd-outputs/__tests__/WhoamiOutput.test.tsx @@ -16,17 +16,8 @@ describe('WhoamiOutput', () => { cmdName: Command.Whoami, }; - it('renders without crashing', () => { - const { container } = render(); - expect(container).toBeInTheDocument(); - }); - it('renders the AboutMe component', () => { render(); expect(screen.getByText('about me / todo')).toBeInTheDocument(); }); - - it('is a class component that extends Component', () => { - expect(WhoamiOutput.prototype.render).toBeDefined(); - }); }); diff --git a/src/components/common/__tests__/KeyListener.test.tsx b/src/components/common/__tests__/KeyListener.test.tsx index cd1b6a4..ffbde9b 100644 --- a/src/components/common/__tests__/KeyListener.test.tsx +++ b/src/components/common/__tests__/KeyListener.test.tsx @@ -1,5 +1,5 @@ import { fireEvent, render } from '@testing-library/react'; -import { describe, expect, it, vi } from 'vitest'; +import { beforeEach, describe, expect, it, vi } from 'vitest'; import { KeyListener } from '../KeyListener'; // Mock the AppContext @@ -15,32 +15,6 @@ describe('KeyListener', () => { vi.clearAllMocks(); }); - it('renders without crashing', () => { - const { container } = render(); - expect(container.firstChild).toBeInTheDocument(); - }); - - it('renders with correct CSS classes', () => { - const { container } = render(); - const div = container.firstChild as HTMLElement; - expect(div).toHaveClass('fixed', '-bottom-5', 'opacity-0'); - }); - - it('has popover manual attribute', () => { - const { container } = render(); - const div = container.firstChild as HTMLElement; - expect(div).toHaveAttribute('popover', 'manual'); - }); - - it('contains a button with autoFocus', () => { - const { container } = render(); - const button = container.querySelector('button'); - expect(button).toBeInTheDocument(); - expect(button).toHaveAttribute('type', 'button'); - // autoFocus is a boolean prop that may not appear as an attribute in tests - // so let's just verify the button exists and has correct type - }); - it('calls setLastKeyDown on keyDown event', () => { const { container } = render(); const button = container.querySelector('button') as HTMLButtonElement; diff --git a/src/components/contact/__tests__/Contact.test.tsx b/src/components/contact/__tests__/Contact.test.tsx index 03e36b8..d4831f9 100644 --- a/src/components/contact/__tests__/Contact.test.tsx +++ b/src/components/contact/__tests__/Contact.test.tsx @@ -8,30 +8,4 @@ describe('Contact', () => { expect(screen.getByText('contact / todo')).toBeInTheDocument(); }); - - it('should render as a div element', () => { - const { container } = render(); - - expect(container.firstChild).toBeInstanceOf(HTMLDivElement); - }); - - it('should have the expected content', () => { - const { container } = render(); - - expect(container.firstChild?.textContent).toBe('contact / todo'); - }); - - it('should render without any props', () => { - expect(() => render()).not.toThrow(); - }); - - it('should match snapshot', () => { - const { container } = render(); - - expect(container.firstChild).toMatchInlineSnapshot(` -
- contact / todo -
- `); - }); }); diff --git a/src/components/layout/__tests__/Header.test.tsx b/src/components/layout/__tests__/Header.test.tsx index 3707b50..1161d14 100644 --- a/src/components/layout/__tests__/Header.test.tsx +++ b/src/components/layout/__tests__/Header.test.tsx @@ -70,40 +70,6 @@ vi.mock('@/utils/helpers', () => ({ })); describe('Header', () => { - it('renders without crashing', () => { - const { container } = render(
); - expect(container.firstChild).toBeInTheDocument(); - }); - - it('renders with correct CSS classes', () => { - const { container } = render(
); - const headerDiv = container.firstChild as HTMLElement; - expect(headerDiv).toHaveClass( - 'flex', - 'w-full', - 'items-center', - 'justify-between', - 'tracking-tighter', - 'transition-colors', - ); - }); - - it('renders ButtonGroup component', () => { - render(
); - expect(screen.getByTestId('button-group')).toBeInTheDocument(); - }); - - it('renders language buttons for all language labels', () => { - render(
); - - Object.entries(LangLabels).forEach(([lang, label]) => { - // Check that we have a link for each language - const link = screen.getByText(label.slice(0, 2)); - expect(link).toBeInTheDocument(); - expect(link.closest('a')).toHaveAttribute('data-locale', lang); - }); - }); - it('renders GitHub link button', () => { render(
); @@ -120,27 +86,4 @@ describe('Header', () => { expect(githubLink).toHaveAttribute('rel', 'noopener'); expect(githubLink).toHaveAttribute('target', '_blank'); }); - - it('applies correct button variants and sizes', () => { - render(
); - - const buttons = screen.getAllByTestId(/button-outlined-small/); - expect(buttons.length).toBeGreaterThan(0); - - // Should have one button for each language plus the GitHub button - expect(buttons.length).toBe(Object.keys(LangLabels).length + 1); - }); - - it('renders language buttons with proper links', () => { - render(
); - - Object.keys(LangLabels).forEach((lang) => { - const link = screen.getByRole('link', { - name: new RegExp(LangLabels[lang].slice(0, 2), 'i'), - }); - expect(link).toBeInTheDocument(); - expect(link).toHaveAttribute('href', '/test-path'); - expect(link).toHaveAttribute('data-locale', lang); - }); - }); }); diff --git a/src/components/layout/__tests__/TermWindow.test.tsx b/src/components/layout/__tests__/TermWindow.test.tsx index 6839fe8..9dda2bf 100644 --- a/src/components/layout/__tests__/TermWindow.test.tsx +++ b/src/components/layout/__tests__/TermWindow.test.tsx @@ -63,30 +63,6 @@ vi.mock('@acid-info/lsd-react/client/TabItem', () => ({ describe('TerminalWindow', () => { const mockChildren =
Test content
; - it('renders without crashing', () => { - const { container } = render( - {mockChildren}, - ); - expect(container.firstChild).toBeInTheDocument(); - }); - - it('renders with correct CSS classes', () => { - const { container } = render( - {mockChildren}, - ); - const mainDiv = container.firstChild as HTMLElement; - expect(mainDiv).toHaveClass('size-full', 'flex', 'flex-col'); - }); - - it('renders Tabs component with correct props', () => { - render({mockChildren}); - - const tabs = screen.getByTestId('tabs'); - expect(tabs).toBeInTheDocument(); - expect(tabs).toHaveClass('shrink-0'); - expect(tabs).toHaveAttribute('data-full-width', 'true'); - }); - it('sets correct active tab based on pathname', () => { render({mockChildren}); @@ -112,23 +88,4 @@ describe('TerminalWindow', () => { render({mockChildren}); expect(screen.getByTestId('mock-children')).toBeInTheDocument(); }); - - it('applies terminal tab className to tab items', () => { - render({mockChildren}); - - Object.keys(Routes).forEach((routeName) => { - const tabItem = screen.getByTestId(`tab-item-${routeName}`); - // Check that the className property contains the styles reference - expect(tabItem.className).toBeDefined(); - }); - }); - - it('uses translations for tab labels', () => { - render({mockChildren}); - - Object.keys(Routes).forEach((routeName) => { - // Since our mock translation function returns the key, check for the route name - expect(screen.getByText(routeName)).toBeInTheDocument(); - }); - }); }); diff --git a/src/components/terminal/__tests__/CmdLink.test.tsx b/src/components/terminal/__tests__/CmdLink.test.tsx index 54a9c94..6b02030 100644 --- a/src/components/terminal/__tests__/CmdLink.test.tsx +++ b/src/components/terminal/__tests__/CmdLink.test.tsx @@ -166,11 +166,4 @@ describe('CmdLink', () => { expect(screen.getByText('help')).toBeInTheDocument(); expect(screen.queryByText('intro')).not.toBeInTheDocument(); }); - - it('renders with correct button props', () => { - render(); - - const button = screen.getByRole('button'); - expect(button).toHaveClass('text-xs', 'w-fit!'); - }); }); diff --git a/src/components/terminal/__tests__/TerminalEmulator.test.tsx b/src/components/terminal/__tests__/TerminalEmulator.test.tsx index c318e3f..d8bb7df 100644 --- a/src/components/terminal/__tests__/TerminalEmulator.test.tsx +++ b/src/components/terminal/__tests__/TerminalEmulator.test.tsx @@ -231,7 +231,7 @@ describe('TerminalEmulator', () => { expect(mockSetHistory).toHaveBeenCalledWith([]); }); - it('renders history items', () => { + it('renders history items with different command types', () => { const mockHistory = [ { cmdName: Command.Help, @@ -243,6 +243,10 @@ describe('TerminalEmulator', () => { output: () =>
Intro Output
, timestamp: 456, }, + { + cmdName: 'unknown-command', + timestamp: 789, + }, ]; (useTerminalContext as unknown as ReturnType).mockReturnValue( @@ -265,86 +269,7 @@ describe('TerminalEmulator', () => { expect(screen.getByTestId('help-output')).toBeInTheDocument(); expect(screen.getByTestId('intro-output')).toBeInTheDocument(); - }); - - it('renders unknown command for unrecognized commands', () => { - const mockHistory = [{ cmdName: 'unknown-command', timestamp: 123 }]; - - (useTerminalContext as unknown as ReturnType).mockReturnValue( - { - hasIntroduced: true, - history: mockHistory, - input: '', - simulatedCmd: '', - submission: '', - setHasIntroduced: mockSetHasIntroduced, - setHasRefreshed: mockSetHasRefreshed, - setHistory: mockSetHistory, - setInput: mockSetInput, - setSimulatedCmd: mockSetSimulatedCmd, - setSubmission: mockSetSubmission, - }, - ); - - render(); - expect(screen.getByTestId('unknown-cmd-output')).toBeInTheDocument(); expect(screen.getByText('unknown-command')).toBeInTheDocument(); }); - - it('handles all supported command types', () => { - const allCommands = [ - { - cmdName: Command.Help, - output: () =>
Help Output
, - timestamp: 1, - }, - { - cmdName: Command.Intro, - output: () =>
Intro Output
, - timestamp: 2, - }, - { - cmdName: Command.Contact, - output: () =>
Contact Output
, - timestamp: 3, - }, - { - cmdName: Command.Whoami, - output: () =>
Whoami Output
, - timestamp: 4, - }, - { - cmdName: Command.Web3Mission, - output: () => ( -
Web3 Mission Output
- ), - timestamp: 5, - }, - ]; - - (useTerminalContext as unknown as ReturnType).mockReturnValue( - { - hasIntroduced: true, - history: allCommands, - input: '', - simulatedCmd: '', - submission: '', - setHasIntroduced: mockSetHasIntroduced, - setHasRefreshed: mockSetHasRefreshed, - setHistory: mockSetHistory, - setInput: mockSetInput, - setSimulatedCmd: mockSetSimulatedCmd, - setSubmission: mockSetSubmission, - }, - ); - - render(); - - expect(screen.getByTestId('help-output')).toBeInTheDocument(); - expect(screen.getByTestId('intro-output')).toBeInTheDocument(); - expect(screen.getByTestId('contact-output')).toBeInTheDocument(); - expect(screen.getByTestId('whoami-output')).toBeInTheDocument(); - expect(screen.getByTestId('web3-mission-output')).toBeInTheDocument(); - }); }); diff --git a/src/components/terminal/__tests__/TerminalPrompt.test.tsx b/src/components/terminal/__tests__/TerminalPrompt.test.tsx index b95d204..8444d8f 100644 --- a/src/components/terminal/__tests__/TerminalPrompt.test.tsx +++ b/src/components/terminal/__tests__/TerminalPrompt.test.tsx @@ -145,47 +145,6 @@ describe('TerminalPrompt', () => { expect(input).toHaveAttribute('type', 'text'); }); - it('renders Terminal prompt span', () => { - render(); - - // Check for the terminal prompt span with a more flexible matcher - const promptSpan = screen.getByText((content, element) => { - return ( - element?.tagName.toLowerCase() === 'span' && - content.includes('translated_visitor') && - content.includes(':~$') - ); - }); - expect(promptSpan).toBeInTheDocument(); - }); - - it('handles componentDidMount with entry', () => { - const entry: CommandEntry = { - timestamp: 1234567890, - cmdName: Command.Help, - }; - - render(); - - expect(getTerminalEntryInput).toHaveBeenCalledWith(entry); - }); - - it('has proper flex layout structure', () => { - const { container } = render(); - - // Check the main flex container exists - const flexContainer = container.querySelector('.flex.w-full.gap-x-2'); - expect(flexContainer).toBeInTheDocument(); - }); - - it('renders style element for input styles', () => { - const { container } = render(); - - // Check that a style element exists (from styled-jsx) - const styleElements = container.querySelectorAll('style'); - expect(styleElements.length).toBeGreaterThan(0); - }); - it('handles empty setLastKeyDown gracefully', () => { const propsWithoutCallback = { i18n: mockT, @@ -198,7 +157,6 @@ describe('TerminalPrompt', () => { const input = screen.getByRole('textbox'); fireEvent.keyDown(input, { key: 'Enter' }); - // Should not throw error expect(input).toBeInTheDocument(); }); @@ -214,7 +172,7 @@ describe('TerminalPrompt', () => { expect(screen.getByRole('textbox')).toBeInTheDocument(); }); - describe('Key handling and interactions', () => { + describe('Key handling', () => { it('handles Enter key event', () => { render(); @@ -222,7 +180,6 @@ describe('TerminalPrompt', () => { fireEvent.change(input, { target: { value: 'test command' } }); fireEvent.keyDown(input, { key: 'Enter' }); - // The keyDown event should be handled by the component expect(input).toBeInTheDocument(); }); @@ -233,7 +190,6 @@ describe('TerminalPrompt', () => { fireEvent.change(input, { target: { value: 'test command' } }); fireEvent.keyDown(input, { key: 'c', ctrlKey: true }); - // The keyDown event should be handled by the component expect(input).toBeInTheDocument(); }); @@ -243,7 +199,6 @@ describe('TerminalPrompt', () => { const input = screen.getByRole('textbox'); fireEvent.keyDown(input, { key: 'ArrowUp' }); - // The keyDown event should be handled by the component expect(input).toBeInTheDocument(); }); @@ -253,7 +208,6 @@ describe('TerminalPrompt', () => { const input = screen.getByRole('textbox'); fireEvent.keyDown(input, { key: 'ArrowDown' }); - // The keyDown event should be handled by the component expect(input).toBeInTheDocument(); }); @@ -266,42 +220,11 @@ describe('TerminalPrompt', () => { Object.defineProperty(tabEvent, 'preventDefault', { value: vi.fn() }); fireEvent.keyDown(input, tabEvent); - // The keyDown event should be handled by the component expect(input).toBeInTheDocument(); }); - - it('resets history index on input', () => { - render(); - - const input = screen.getByRole('textbox'); - fireEvent.input(input); - fireEvent.change(input, { target: { value: 'new command' } }); - - expect(input).toHaveValue('new command'); - }); }); - describe('History navigation edge cases', () => { - it('handles ArrowUp with history', () => { - render(); - - const input = screen.getByRole('textbox'); - fireEvent.keyDown(input, { key: 'ArrowUp' }); - - // Should handle the key event without error - expect(input).toBeInTheDocument(); - }); - - it('handles ArrowDown with history', () => { - render(); - - const input = screen.getByRole('textbox'); - fireEvent.keyDown(input, { key: 'ArrowDown' }); - - // Should handle the key event without error - expect(input).toBeInTheDocument(); - }); - + describe('History navigation', () => { it('handles history navigation with no history', () => { const propsWithoutHistory = { ...defaultProps, @@ -332,35 +255,6 @@ describe('TerminalPrompt', () => { }); }); - describe('Component methods', () => { - it('handles componentDidUpdate behavior', () => { - // Test componentDidUpdate by verifying isNewKeyEvent is used - vi.mocked(isNewKeyEvent).mockReturnValue(false); - - const keyEvent = { key: 'Enter', ctrlKey: false } as React.KeyboardEvent; - - render(); - - // Component should handle the update without error - expect(screen.getByRole('textbox')).toBeInTheDocument(); - }); - - it('handles simulate method behavior', async () => { - // Test the simulate method indirectly through key events - render(); - - const input = screen.getByRole('textbox'); - - // Simulate typing behavior - fireEvent.change(input, { target: { value: 'h' } }); - fireEvent.change(input, { target: { value: 'he' } }); - fireEvent.change(input, { target: { value: 'hel' } }); - fireEvent.change(input, { target: { value: 'help' } }); - - expect(input).toHaveValue('help'); - }); - }); - describe('Entry formatting', () => { it('formats entry with option correctly', () => { const entryWithOption: CommandEntry = { @@ -401,7 +295,6 @@ describe('TerminalPrompt', () => { const input = screen.getByRole('textbox'); fireEvent.keyDown(input, { key: 'Enter' }); - // Should not throw error expect(input).toBeInTheDocument(); }); @@ -417,7 +310,6 @@ describe('TerminalPrompt', () => { const input = screen.getByRole('textbox'); fireEvent.keyDown(input, { key: 'Enter' }); - // Should not throw error expect(input).toBeInTheDocument(); }); }); @@ -430,7 +322,6 @@ describe('TerminalPrompt', () => { fireEvent.change(input, { target: { value: 'xyz' } }); fireEvent.keyDown(input, { key: 'Tab', preventDefault: vi.fn() }); - // Component should handle autocomplete without error expect(input).toBeInTheDocument(); }); @@ -446,404 +337,12 @@ describe('TerminalPrompt', () => { fireEvent.change(input, { target: { value: 'c' } }); fireEvent.keyDown(input, { key: 'Tab', preventDefault: vi.fn() }); - // Should not show autocomplete when entry is provided expect( screen.queryByText(/translated_autocomplete/), ).not.toBeInTheDocument(); }); }); - describe('Advanced functionality coverage', () => { - it('handles setHistoryIdx with valid index', () => { - const history: CommandEntry[] = [ - { cmdName: Command.Help, timestamp: 1, option: 'verbose' }, - { - cmdName: Command.Whoami, - timestamp: 2, - argName: 'format', - argValue: 'json', - }, - ]; - - // Mock the utility functions to return realistic data - (getTerminalEntryInput as ReturnType) - .mockReturnValueOnce('whoami --format=json') - .mockReturnValueOnce('help verbose'); - - render(); - - const input = screen.getByRole('textbox') as HTMLInputElement; - - // Navigate up through history - this should trigger setPreviousEntry and setHistoryIdx - fireEvent.keyDown(input, { key: 'ArrowUp' }); - - // Should handle history navigation and set input text - expect(input).toBeInTheDocument(); - }); - - it('handles setNextEntry when at end of history', () => { - const history: CommandEntry[] = [ - { cmdName: Command.Help, timestamp: 1 }, - { cmdName: Command.Whoami, timestamp: 2 }, - ]; - - // Mock the utility functions properly - (getTerminalEntryInput as ReturnType) - .mockReturnValueOnce('whoami') - .mockReturnValueOnce('help'); - - render(); - - const input = screen.getByRole('textbox') as HTMLInputElement; - - // Navigate to beginning of history first - fireEvent.keyDown(input, { key: 'ArrowUp' }); // Go to most recent (whoami) - fireEvent.keyDown(input, { key: 'ArrowUp' }); // Go to previous (help) - - // Then navigate forward - this tests setNextEntry logic - fireEvent.keyDown(input, { key: 'ArrowDown' }); // Go back to whoami - fireEvent.keyDown(input, { key: 'ArrowDown' }); // Should trigger resetEntry at end - - expect(input).toBeInTheDocument(); - }); - - it('handles autoComplete with multiple matching commands', () => { - render(); - - const input = screen.getByRole('textbox') as HTMLInputElement; - - // Type partial command that matches multiple commands (like 'c' for 'contact', 'clear') - fireEvent.change(input, { target: { value: 'c' } }); - - // Tab key should be handled by setLastKeyDown callback - fireEvent.keyDown(input, { key: 'Tab' }); - - // Should register the key event - expect(input).toBeInTheDocument(); - expect(input).toHaveValue('c'); - }); - - it('handles autoComplete with single matching command', () => { - render(); - - const input = screen.getByRole('textbox') as HTMLInputElement; - - // Type partial command that matches single command (help starts with 'hel') - fireEvent.change(input, { target: { value: 'hel' } }); - - // Tab key should be handled - fireEvent.keyDown(input, { key: 'Tab' }); - - // Should register the key event - expect(input).toBeInTheDocument(); - expect(input).toHaveValue('hel'); - }); - - it('handles updateCursorPosition via setTimeout', async () => { - const mockSetSelectionRange = vi.fn(); - - render(); - - const input = screen.getByRole('textbox') as HTMLInputElement; - input.setSelectionRange = mockSetSelectionRange; - - // Trigger history navigation which should call updateCursorPosition - fireEvent.keyDown(input, { key: 'ArrowUp' }); - - // Wait for setTimeout to execute - await new Promise((resolve) => setTimeout(resolve, 100)); - }); - - it('handles getPastInputStr with all entry properties', () => { - const entryWithAllProps: CommandEntry = { - cmdName: Command.Help, - timestamp: 123, - option: '--verbose', - argName: 'format', - argValue: 'json', - }; - - (getTerminalEntryInput as ReturnType).mockReturnValue( - 'help --verbose --format=json', - ); - - render(); - - // Should call getTerminalEntryInput with the entry - expect(getTerminalEntryInput).toHaveBeenCalledWith(entryWithAllProps); - }); - - it('handles setAutocomplete with callback', () => { - render(); - - const input = screen.getByRole('textbox'); - - // Type partial command to trigger autocomplete - fireEvent.change(input, { target: { value: 'c' } }); - fireEvent.keyDown(input, { key: 'Tab', preventDefault: vi.fn() }); - - // Should handle autocomplete functionality - expect(input).toBeInTheDocument(); - }); - - it('resets entry on Ctrl+C', () => { - render(); - - const input = screen.getByRole('textbox'); - - // Type some text first - fireEvent.change(input, { target: { value: 'some text' } }); - - // Press Ctrl+C - fireEvent.keyDown(input, { key: 'c', ctrlKey: true }); - - // Should reset the input (checked by not throwing error) - expect(input).toBeInTheDocument(); - }); - - it('handles Enter key submission', () => { - const mockSetSubmission = vi.fn(); - const mockSetLastKeyDown = vi.fn(); - - render( - , - ); - - const input = screen.getByRole('textbox') as HTMLInputElement; - - // Type command - fireEvent.change(input, { target: { value: 'help' } }); - - // Simulate Enter key press through the DOM event - fireEvent.keyDown(input, { key: 'Enter' }); - - // The event should be captured by setLastKeyDown - expect(mockSetLastKeyDown).toHaveBeenCalled(); - expect(input).toHaveValue('help'); - }); - - it('handles focus and scrollIntoView methods', () => { - const mockScrollIntoView = vi.fn(); - HTMLElement.prototype.scrollIntoView = mockScrollIntoView; - - render(); - - const input = screen.getByRole('textbox'); - - // Should be able to focus - input.focus(); - expect(document.activeElement).toBe(input); - }); - - it('handles simulate method functionality', async () => { - const mockSetSubmission = vi.fn(); - - render( - , - ); - - // The simulate method is complex and handles typing animation - // We'll just ensure it doesn't throw errors - await new Promise((resolve) => setTimeout(resolve, 100)); - }); - - it('handles setInput with callback', () => { - render(); - - const input = screen.getByRole('textbox'); - - // Test input change which calls setInput - fireEvent.change(input, { target: { value: 'test input' } }); - - expect(input).toHaveValue('test input'); - }); - - it('handles onBeforeInput to reset history index', () => { - const history: CommandEntry[] = [{ cmdName: Command.Help, timestamp: 1 }]; - - render(); - - const input = screen.getByRole('textbox'); - - // Navigate to history first - fireEvent.keyDown(input, { key: 'ArrowUp' }); - - // Then trigger onBeforeInput to reset history index using a custom event - const beforeInputEvent = new Event('beforeinput', { - bubbles: true, - cancelable: true, - }); - fireEvent(input, beforeInputEvent); - - expect(input).toBeInTheDocument(); - }); - }); - - describe('Direct method testing through key events', () => { - beforeEach(() => { - // Reset all mocks before each test - vi.clearAllMocks(); - vi.mocked(isNewKeyEvent).mockReturnValue(true); - }); - - it('properly triggers submit method through Enter key', () => { - const mockSetSubmission = vi.fn(); - const mockSetLastKeyDown = vi.fn(); - - render( - , - ); - - const input = screen.getByRole('textbox') as HTMLInputElement; - fireEvent.change(input, { target: { value: 'test command' } }); - - // Trigger Enter key through DOM event - fireEvent.keyDown(input, { key: 'Enter' }); - - expect(mockSetLastKeyDown).toHaveBeenCalled(); - expect(input).toHaveValue('test command'); - }); - - it('properly triggers resetEntry method through Ctrl+C', () => { - const mockSetLastKeyDown = vi.fn(); - - render( - , - ); - - const input = screen.getByRole('textbox') as HTMLInputElement; - fireEvent.change(input, { target: { value: 'some text' } }); - - // Trigger Ctrl+C through DOM event - fireEvent.keyDown(input, { key: 'c', ctrlKey: true }); - - expect(mockSetLastKeyDown).toHaveBeenCalled(); - expect(input).toHaveValue('some text'); - }); - - it('properly triggers setPreviousEntry through ArrowUp', () => { - const history: CommandEntry[] = [ - { cmdName: Command.Help, timestamp: 1 }, - { cmdName: Command.Whoami, timestamp: 2 }, - ]; - - const mockSetLastKeyDown = vi.fn(); - - render( - , - ); - - const input = screen.getByRole('textbox') as HTMLInputElement; - - // Trigger ArrowUp through DOM event - fireEvent.keyDown(input, { key: 'ArrowUp' }); - - expect(mockSetLastKeyDown).toHaveBeenCalled(); - }); - - it('properly triggers setNextEntry through ArrowDown', () => { - const history: CommandEntry[] = [ - { cmdName: Command.Help, timestamp: 1 }, - { cmdName: Command.Whoami, timestamp: 2 }, - ]; - - const mockSetLastKeyDown = vi.fn(); - - render( - , - ); - - const input = screen.getByRole('textbox') as HTMLInputElement; - - // Trigger ArrowDown through DOM event - fireEvent.keyDown(input, { key: 'ArrowDown' }); - - expect(mockSetLastKeyDown).toHaveBeenCalled(); - }); - - it('properly triggers autoComplete through Tab', () => { - const mockSetLastKeyDown = vi.fn(); - - render( - , - ); - - const input = screen.getByRole('textbox') as HTMLInputElement; - fireEvent.change(input, { target: { value: 'he' } }); - - // Trigger Tab through DOM event - fireEvent.keyDown(input, { key: 'Tab' }); - - expect(mockSetLastKeyDown).toHaveBeenCalled(); - }); - - it('tests getPastInputStr method with complex entry', () => { - const complexEntry: CommandEntry = { - cmdName: Command.Help, - timestamp: 123, - option: '--verbose', - argName: 'format', - argValue: 'json', - }; - - // Mock getTerminalEntryInput to handle complex entries - (getTerminalEntryInput as ReturnType).mockReturnValue( - 'help --verbose --format=json', - ); - - render(); - - // Should call getTerminalEntryInput with the complex entry - expect(getTerminalEntryInput).toHaveBeenCalledWith(complexEntry); - }); - - it('handles edge case of history navigation at boundaries', () => { - const history: CommandEntry[] = [{ cmdName: Command.Help, timestamp: 1 }]; - - const mockSetLastKeyDown = vi.fn(); - - render( - , - ); - - const input = screen.getByRole('textbox') as HTMLInputElement; - - // Test ArrowUp at history start - fireEvent.keyDown(input, { key: 'ArrowUp' }); - expect(mockSetLastKeyDown).toHaveBeenCalled(); - - // Test ArrowDown after navigating up - fireEvent.keyDown(input, { key: 'ArrowDown' }); - expect(mockSetLastKeyDown).toHaveBeenCalledTimes(2); - }); - }); - describe('getDisplayHost', () => { it('returns full host for regular domains', () => { Object.defineProperty(window, 'location', { @@ -879,7 +378,6 @@ describe('TerminalPrompt', () => { render(); - // Check for the shortened IPNS host in the prompt span const promptSpan = screen.getByText((content, element) => { return ( element?.tagName.toLowerCase() === 'span' && @@ -899,7 +397,6 @@ describe('TerminalPrompt', () => { render(); - // Check for the shortened IPFS host in the prompt span const promptSpan = screen.getByText((content, element) => { return ( element?.tagName.toLowerCase() === 'span' && diff --git a/src/constants/__tests__/commands.test.ts b/src/constants/__tests__/commands.test.ts index 947ee15..9211b5a 100644 --- a/src/constants/__tests__/commands.test.ts +++ b/src/constants/__tests__/commands.test.ts @@ -15,63 +15,5 @@ describe('commands', () => { expect(commandNames).toContain(Command.Whoami); expect(commandNames).toContain(Command.Web3Mission); }); - - it('should have correct structure for Clear command', () => { - const clearCommand = Commands.find((cmd) => cmd.name === Command.Clear); - - expect(clearCommand).toBeDefined(); - expect(clearCommand?.name).toBe(Command.Clear); - expect(clearCommand?.output).toBeUndefined(); - }); - - it('should have output for commands that need it', () => { - const commandsWithOutput = [ - Command.Contact, - Command.Help, - Command.Intro, - Command.Whoami, - Command.Web3Mission, - ]; - - commandsWithOutput.forEach((cmdName) => { - const command = Commands.find((cmd) => cmd.name === cmdName); - expect(command?.output).toBeDefined(); - }); - }); - - it('should have options for SetLang command', () => { - const setLangCommand = Commands.find( - (cmd) => cmd.name === Command.SetLang, - ); - - expect(setLangCommand).toBeDefined(); - expect(setLangCommand?.options).toBeDefined(); - expect(Array.isArray(setLangCommand?.options)).toBe(true); - expect(setLangCommand?.options?.length).toBeGreaterThan(0); - }); - - it('should not have duplicate commands', () => { - const commandNames = Commands.map((cmd) => cmd.name); - const uniqueCommandNames = [...new Set(commandNames)]; - - expect(commandNames.length).toBe(uniqueCommandNames.length); - }); - - it('should have valid command names that match Command enum', () => { - const validCommands = Object.values(Command); - - Commands.forEach((cmd) => { - expect(validCommands).toContain(cmd.name); - }); - }); - - it('should have all commands from Command enum', () => { - const commandNames = Commands.map((cmd) => cmd.name); - const enumCommands = Object.values(Command); - - enumCommands.forEach((enumCmd) => { - expect(commandNames).toContain(enumCmd); - }); - }); }); }); diff --git a/src/constants/__tests__/lang.test.ts b/src/constants/__tests__/lang.test.ts index a30068d..717535c 100644 --- a/src/constants/__tests__/lang.test.ts +++ b/src/constants/__tests__/lang.test.ts @@ -7,17 +7,6 @@ describe('lang', () => { expect(Lang.En).toBe('en'); expect(Lang.Fr).toBe('fr'); }); - - it('should have exactly 2 language options', () => { - const langValues = Object.values(Lang); - expect(langValues).toHaveLength(2); - }); - - it('should have string values', () => { - Object.values(Lang).forEach((lang) => { - expect(typeof lang).toBe('string'); - }); - }); }); describe('LangLabels', () => { @@ -25,44 +14,5 @@ describe('lang', () => { expect(LangLabels[Lang.En]).toBe('English'); expect(LangLabels[Lang.Fr]).toBe('Français'); }); - - it('should have labels for all Lang enum values', () => { - Object.values(Lang).forEach((lang) => { - expect(LangLabels[lang]).toBeDefined(); - expect(typeof LangLabels[lang]).toBe('string'); - expect(LangLabels[lang].length).toBeGreaterThan(0); - }); - }); - - it('should not have extra labels', () => { - const langKeys = Object.keys(LangLabels); - const enumValues = Object.values(Lang); - - expect(langKeys).toHaveLength(enumValues.length); - - langKeys.forEach((key) => { - expect(enumValues).toContain(key as Lang); - }); - }); - - it('should have proper label formatting', () => { - expect(LangLabels[Lang.En]).toMatch(/^[A-Z][a-z]+$/); - expect(LangLabels[Lang.Fr]).toMatch(/^[A-ZÀ-ÿ][a-zà-ÿ]+$/); - }); - }); - - describe('Lang and LangLabels consistency', () => { - it('should have matching keys between Lang enum and LangLabels', () => { - const enumValues = Object.values(Lang); - const labelKeys = Object.keys(LangLabels); - - enumValues.forEach((lang) => { - expect(labelKeys).toContain(lang); - }); - - labelKeys.forEach((key) => { - expect(enumValues).toContain(key as Lang); - }); - }); }); }); diff --git a/src/constants/__tests__/routes.test.ts b/src/constants/__tests__/routes.test.ts index 2ab00d0..8d35819 100644 --- a/src/constants/__tests__/routes.test.ts +++ b/src/constants/__tests__/routes.test.ts @@ -9,55 +9,5 @@ describe('routes', () => { expect(Routes.mission).toBe('/mission'); expect(Routes.contact).toBe('/contact'); }); - - it('should have exactly 4 routes', () => { - const routeKeys = Object.keys(Routes); - expect(routeKeys).toHaveLength(4); - }); - - it('should have all routes starting with /', () => { - Object.values(Routes).forEach((route) => { - expect(route).toMatch(/^\/.*$/); - }); - }); - - it('should have unique route paths', () => { - const routePaths = Object.values(Routes); - const uniquePaths = [...new Set(routePaths)]; - - expect(routePaths.length).toBe(uniquePaths.length); - }); - - it('should have terminal route as root', () => { - expect(Routes.terminal).toBe('/'); - }); - - it('should have proper route naming convention', () => { - const routeKeys = Object.keys(Routes); - - routeKeys.forEach((key) => { - expect(key).toMatch(/^[a-z]+$/); - }); - }); - - it('should have route paths matching their names', () => { - expect(Routes.whoami).toBe('/whoami'); - expect(Routes.mission).toBe('/mission'); - expect(Routes.contact).toBe('/contact'); - }); - - it('should not have trailing slashes (except root)', () => { - Object.values(Routes).forEach((route) => { - if (route !== '/') { - expect(route).not.toMatch(/\/$/); - } - }); - }); - - it('should be a valid object structure', () => { - expect(typeof Routes).toBe('object'); - expect(Routes).not.toBeNull(); - expect(Array.isArray(Routes)).toBe(false); - }); }); }); diff --git a/src/contexts/__tests__/AppContext.test.tsx b/src/contexts/__tests__/AppContext.test.tsx index d91228e..f127abf 100644 --- a/src/contexts/__tests__/AppContext.test.tsx +++ b/src/contexts/__tests__/AppContext.test.tsx @@ -143,66 +143,4 @@ describe('AppContext', () => { expect(screen.getByTestId('old-key')).toHaveTextContent('Enter'); }); - - it('should handle multiple state updates', () => { - render( - - - , - ); - - const setTrueButton = screen.getByTestId('set-terminal-true'); - const setLastKeyButton = screen.getByTestId('set-last-key'); - - act(() => { - fireEvent.click(setTrueButton); - fireEvent.click(setLastKeyButton); - }); - - expect(screen.getByTestId('is-terminal')).toHaveTextContent('true'); - expect(screen.getByTestId('last-key')).toHaveTextContent('Enter'); - }); - - it('should handle null values', () => { - const TestNullComponent = () => { - const { setLastKeyDown, setOldKeyDown } = useAppContext(); - - return ( -
- - -
- ); - }; - - render( - - - - , - ); - - const setLastNullButton = screen.getByTestId('set-last-null'); - const setOldNullButton = screen.getByTestId('set-old-null'); - - act(() => { - fireEvent.click(setLastNullButton); - fireEvent.click(setOldNullButton); - }); - - expect(screen.getByTestId('last-key')).toHaveTextContent('none'); - expect(screen.getByTestId('old-key')).toHaveTextContent('none'); - }); }); diff --git a/src/contexts/__tests__/TerminalContext.test.tsx b/src/contexts/__tests__/TerminalContext.test.tsx index b33d832..1540e27 100644 --- a/src/contexts/__tests__/TerminalContext.test.tsx +++ b/src/contexts/__tests__/TerminalContext.test.tsx @@ -1,7 +1,8 @@ import { act, renderHook } from '@testing-library/react'; import { describe, expect, it } from 'vitest'; -import type { AppRoute, CommandEntry } from '@/types/routing'; +import type { AppRoute } from '@/types/routing'; import { ViewRoute } from '@/types/routing'; +import type { CommandEntry } from '@/types/terminal'; import { Command } from '@/types/terminal'; import { TerminalStateProvider, useTerminalContext } from '../TerminalContext'; @@ -56,18 +57,6 @@ describe('TerminalContext', () => { expect(result.current.submission).toBe('test submission'); }); - it('should update simulatedCmd when setSimulatedCmd is called', () => { - const { result } = renderHook(() => useTerminalContext(), { - wrapper: TerminalStateProvider, - }); - - act(() => { - result.current.setSimulatedCmd('simulated command'); - }); - - expect(result.current.simulatedCmd).toBe('simulated command'); - }); - it('should update history when setHistory is called', () => { const { result } = renderHook(() => useTerminalContext(), { wrapper: TerminalStateProvider, @@ -99,18 +88,6 @@ describe('TerminalContext', () => { expect(result.current.hasIntroduced).toBe(true); }); - it('should update hasRefreshed when setHasRefreshed is called', () => { - const { result } = renderHook(() => useTerminalContext(), { - wrapper: TerminalStateProvider, - }); - - act(() => { - result.current.setHasRefreshed(true); - }); - - expect(result.current.hasRefreshed).toBe(true); - }); - it('should update lastRouteReq when setLastRouteReq is called', () => { const { result } = renderHook(() => useTerminalContext(), { wrapper: TerminalStateProvider, @@ -128,24 +105,6 @@ describe('TerminalContext', () => { expect(result.current.lastRouteReq).toEqual(mockRoute); }); - it('should update oldRouteReq when setOldRouteReq is called', () => { - const { result } = renderHook(() => useTerminalContext(), { - wrapper: TerminalStateProvider, - }); - - const mockRoute: AppRoute = { - viewRoute: ViewRoute.Whoami, - param: 'test', - timeStamp: Date.now(), - }; - - act(() => { - result.current.setOldRouteReq(mockRoute); - }); - - expect(result.current.oldRouteReq).toEqual(mockRoute); - }); - it('should handle multiple state updates correctly', () => { const { result } = renderHook(() => useTerminalContext(), { wrapper: TerminalStateProvider, @@ -199,30 +158,4 @@ describe('TerminalContext', () => { expect(result.current.lastRouteReq).toBeNull(); }); }); - - describe('useTerminalContext', () => { - it('should return the context value', () => { - const { result } = renderHook(() => useTerminalContext(), { - wrapper: TerminalStateProvider, - }); - - expect(result.current.input).toBe(''); - expect(result.current.submission).toBe(''); - expect(result.current.simulatedCmd).toBe(''); - expect(result.current.history).toEqual([]); - expect(result.current.hasIntroduced).toBe(false); - expect(result.current.hasRefreshed).toBe(false); - expect(result.current.lastRouteReq).toBeNull(); - expect(result.current.oldRouteReq).toBeNull(); - - expect(typeof result.current.setInput).toBe('function'); - expect(typeof result.current.setSubmission).toBe('function'); - expect(typeof result.current.setSimulatedCmd).toBe('function'); - expect(typeof result.current.setHistory).toBe('function'); - expect(typeof result.current.setHasIntroduced).toBe('function'); - expect(typeof result.current.setHasRefreshed).toBe('function'); - expect(typeof result.current.setLastRouteReq).toBe('function'); - expect(typeof result.current.setOldRouteReq).toBe('function'); - }); - }); }); diff --git a/src/hooks/__tests__/useIsPrerender.test.ts b/src/hooks/__tests__/useIsPrerender.test.ts index 48a7f2c..651b301 100644 --- a/src/hooks/__tests__/useIsPrerender.test.ts +++ b/src/hooks/__tests__/useIsPrerender.test.ts @@ -9,38 +9,4 @@ describe('useIsPrerender', () => { // In test environment, useEffect runs immediately, so isPrerender is false expect(result.current).toBe(false); }); - - it('should remain false after rerender', () => { - const { result, rerender } = renderHook(() => useIsPrerender()); - - // Initially false in test environment - expect(result.current).toBe(false); - - // Still false after rerender - rerender(); - expect(result.current).toBe(false); - }); - - it('should not change value after initial effect', () => { - const { result, rerender } = renderHook(() => useIsPrerender()); - - const initialValue = result.current; - - // Rerender multiple times - rerender(); - rerender(); - rerender(); - - // Value should remain the same - expect(result.current).toBe(initialValue); - }); - - it('should handle multiple instances independently', () => { - const { result: result1 } = renderHook(() => useIsPrerender()); - const { result: result2 } = renderHook(() => useIsPrerender()); - - // Both should be false in test environment - expect(result1.current).toBe(false); - expect(result2.current).toBe(false); - }); }); diff --git a/src/hooks/__tests__/useKeyHandler.test.ts b/src/hooks/__tests__/useKeyHandler.test.ts index ca01895..f6c8a2c 100644 --- a/src/hooks/__tests__/useKeyHandler.test.ts +++ b/src/hooks/__tests__/useKeyHandler.test.ts @@ -28,7 +28,7 @@ const createMockKeyboardEvent = ( cancelable: true, preventDefault: vi.fn(), stopPropagation: vi.fn(), - }) as KeyboardEvent; + }) as unknown as KeyboardEvent; describe('useKeyHandler', () => { const mockHandler = vi.fn(); @@ -94,90 +94,4 @@ describe('useKeyHandler', () => { expect(mockHandler).not.toHaveBeenCalled(); expect(mockSetOldKeyDown).not.toHaveBeenCalled(); }); - - it('should call handler when key event has different key', () => { - const oldKeyEvent = createMockKeyboardEvent('Enter', 123456); - const newKeyEvent = createMockKeyboardEvent('Escape', 123456); - - mockUseAppContext.mockReturnValue({ - lastKeyDown: newKeyEvent, - oldKeyDown: oldKeyEvent, - setOldKeyDown: mockSetOldKeyDown, - }); - - renderHook(() => useKeyHandler(mockHandler)); - - expect(mockHandler).toHaveBeenCalledWith(newKeyEvent); - expect(mockSetOldKeyDown).toHaveBeenCalledWith(newKeyEvent); - }); - - it('should call handler when key event has different timestamp', () => { - const oldKeyEvent = createMockKeyboardEvent('Enter', 123456); - const newKeyEvent = createMockKeyboardEvent('Enter', 789012); - - mockUseAppContext.mockReturnValue({ - lastKeyDown: newKeyEvent, - oldKeyDown: oldKeyEvent, - setOldKeyDown: mockSetOldKeyDown, - }); - - renderHook(() => useKeyHandler(mockHandler)); - - expect(mockHandler).toHaveBeenCalledWith(newKeyEvent); - expect(mockSetOldKeyDown).toHaveBeenCalledWith(newKeyEvent); - }); - - it('should handle multiple key events correctly', () => { - const keyEvent1 = createMockKeyboardEvent('Enter', 123456); - const keyEvent2 = createMockKeyboardEvent('Escape', 789012); - - // First render with first key event - mockUseAppContext.mockReturnValue({ - lastKeyDown: keyEvent1, - oldKeyDown: null, - setOldKeyDown: mockSetOldKeyDown, - }); - - const { rerender } = renderHook(() => useKeyHandler(mockHandler)); - - expect(mockHandler).toHaveBeenCalledWith(keyEvent1); - expect(mockSetOldKeyDown).toHaveBeenCalledWith(keyEvent1); - - // Clear mocks and set up for second key event - vi.clearAllMocks(); - - mockUseAppContext.mockReturnValue({ - lastKeyDown: keyEvent2, - oldKeyDown: keyEvent1, - setOldKeyDown: mockSetOldKeyDown, - }); - - rerender(); - - expect(mockHandler).toHaveBeenCalledWith(keyEvent2); - expect(mockSetOldKeyDown).toHaveBeenCalledWith(keyEvent2); - }); - - it('should handle activation/deactivation correctly', () => { - const keyEvent = createMockKeyboardEvent('Enter', 123456); - - mockUseAppContext.mockReturnValue({ - lastKeyDown: keyEvent, - oldKeyDown: null, - setOldKeyDown: mockSetOldKeyDown, - }); - - const { rerender } = renderHook( - ({ deactivated }) => useKeyHandler(mockHandler, deactivated), - { initialProps: { deactivated: true } }, - ); - - // Should not call handler when deactivated - expect(mockHandler).not.toHaveBeenCalled(); - - // Activate and rerender - rerender({ deactivated: false }); - - expect(mockHandler).toHaveBeenCalledWith(keyEvent); - }); }); diff --git a/src/hooks/__tests__/useTermRouter.test.ts b/src/hooks/__tests__/useTermRouter.test.ts index 770f45d..7e2382d 100644 --- a/src/hooks/__tests__/useTermRouter.test.ts +++ b/src/hooks/__tests__/useTermRouter.test.ts @@ -86,65 +86,4 @@ describe('useTermRouter', () => { expect(mockHandler).not.toHaveBeenCalled(); expect(mockSetOldRouteReq).not.toHaveBeenCalled(); }); - - it('should call handler when route has different timestamp', () => { - const oldRouteReq: AppRoute = { - viewRoute: ViewRoute.Terminal, - timeStamp: 12345, - }; - - const newRouteReq: AppRoute = { - viewRoute: ViewRoute.Terminal, - timeStamp: 54321, - }; - - mockUseTerminalContext.mockReturnValue({ - lastRouteReq: newRouteReq, - oldRouteReq: oldRouteReq, - setOldRouteReq: mockSetOldRouteReq, - }); - - renderHook(() => useTermRouter(ViewRoute.Terminal, mockHandler)); - - expect(mockHandler).toHaveBeenCalledWith(newRouteReq); - expect(mockSetOldRouteReq).toHaveBeenCalledWith(newRouteReq); - }); - - it('should handle route with parameters', () => { - const lastRouteReq: AppRoute = { - viewRoute: ViewRoute.Contact, - param: 'email', - timeStamp: Date.now(), - }; - - mockUseTerminalContext.mockReturnValue({ - lastRouteReq, - oldRouteReq: null, - setOldRouteReq: mockSetOldRouteReq, - }); - - renderHook(() => useTermRouter(ViewRoute.Contact, mockHandler)); - - expect(mockHandler).toHaveBeenCalledWith(lastRouteReq); - expect(mockSetOldRouteReq).toHaveBeenCalledWith(lastRouteReq); - }); - - it('should handle numeric parameters', () => { - const lastRouteReq: AppRoute = { - viewRoute: ViewRoute.Blog, - param: 42, - timeStamp: Date.now(), - }; - - mockUseTerminalContext.mockReturnValue({ - lastRouteReq, - oldRouteReq: null, - setOldRouteReq: mockSetOldRouteReq, - }); - - renderHook(() => useTermRouter(ViewRoute.Blog, mockHandler)); - - expect(mockHandler).toHaveBeenCalledWith(lastRouteReq); - expect(mockSetOldRouteReq).toHaveBeenCalledWith(lastRouteReq); - }); }); diff --git a/src/i18n/__tests__/intl.test.ts b/src/i18n/__tests__/intl.test.ts index e2163f2..72dcbad 100644 --- a/src/i18n/__tests__/intl.test.ts +++ b/src/i18n/__tests__/intl.test.ts @@ -38,63 +38,6 @@ describe('i18n intl configuration', () => { expect(routing.localePrefix).toBe('always'); expect(routing.localeDetection).toBe(false); }); - - it('should have proper locales array', () => { - expect(Array.isArray(routing.locales)).toBe(true); - expect(routing.locales).toContain('en'); - expect(routing.locales).toContain('fr'); - expect(routing.locales).toHaveLength(2); - }); - - it('should have English as default locale', () => { - expect(routing.defaultLocale).toBe('en'); - expect(routing.locales).toContain(routing.defaultLocale); - }); - - it('should have locale prefix always enabled', () => { - expect(routing.localePrefix).toBe('always'); - }); - - it('should have locale detection disabled', () => { - expect(routing.localeDetection).toBe(false); - }); - }); - - describe('configuration structure', () => { - it('should export routing as an object', () => { - expect(typeof routing).toBe('object'); - expect(routing).not.toBeNull(); - }); - - it('should have all required routing properties', () => { - expect(routing).toHaveProperty('locales'); - expect(routing).toHaveProperty('defaultLocale'); - expect(routing).toHaveProperty('localePrefix'); - expect(routing).toHaveProperty('localeDetection'); - }); - - it('should have correct property types', () => { - expect(Array.isArray(routing.locales)).toBe(true); - expect(typeof routing.defaultLocale).toBe('string'); - expect(typeof routing.localePrefix).toBe('string'); - expect(typeof routing.localeDetection).toBe('boolean'); - }); - }); - - describe('locale validation', () => { - it('should only contain valid locale codes', () => { - const validLocales = ['en', 'fr']; - routing.locales.forEach((locale) => { - expect(validLocales).toContain(locale); - expect(typeof locale).toBe('string'); - expect(locale.length).toBe(2); - }); - }); - - it('should have unique locales', () => { - const uniqueLocales = [...new Set(routing.locales)]; - expect(uniqueLocales).toHaveLength(routing.locales.length); - }); }); describe('getRequestConfig', () => { diff --git a/src/i18n/__tests__/navigation.test.ts b/src/i18n/__tests__/navigation.test.ts index 9fe5edf..e289cfd 100644 --- a/src/i18n/__tests__/navigation.test.ts +++ b/src/i18n/__tests__/navigation.test.ts @@ -31,59 +31,5 @@ describe('i18n navigation', () => { expect(navigation.useRouter).toBeDefined(); expect(navigation.getPathname).toBeDefined(); }); - - it('should export Link component', async () => { - const { Link } = await import('../navigation'); - expect(Link).toBeDefined(); - expect(typeof Link).toBe('function'); - }); - - it('should export redirect function', async () => { - const { redirect } = await import('../navigation'); - expect(redirect).toBeDefined(); - expect(typeof redirect).toBe('function'); - }); - - it('should export usePathname hook', async () => { - const { usePathname } = await import('../navigation'); - expect(usePathname).toBeDefined(); - expect(typeof usePathname).toBe('function'); - }); - - it('should export useRouter hook', async () => { - const { useRouter } = await import('../navigation'); - expect(useRouter).toBeDefined(); - expect(typeof useRouter).toBe('function'); - }); - - it('should export getPathname function', async () => { - const { getPathname } = await import('../navigation'); - expect(getPathname).toBeDefined(); - expect(typeof getPathname).toBe('function'); - }); - - it('should have all navigation utilities available', async () => { - const navigation = await import('../navigation'); - const { Link, redirect, usePathname, useRouter, getPathname } = - navigation; - const exports = { Link, redirect, usePathname, useRouter, getPathname }; - - for (const [name, func] of Object.entries(exports)) { - expect(func, `${name} should be defined`).toBeDefined(); - expect(typeof func, `${name} should be a function`).toBe('function'); - } - }); - - it('should export exactly 5 navigation utilities', async () => { - const navigation = await import('../navigation'); - const exportedKeys = Object.keys(navigation); - - expect(exportedKeys).toContain('Link'); - expect(exportedKeys).toContain('redirect'); - expect(exportedKeys).toContain('usePathname'); - expect(exportedKeys).toContain('useRouter'); - expect(exportedKeys).toContain('getPathname'); - expect(exportedKeys).toHaveLength(5); - }); }); }); diff --git a/src/i18n/__tests__/request.test.ts b/src/i18n/__tests__/request.test.ts index 821b46a..b211cbd 100644 --- a/src/i18n/__tests__/request.test.ts +++ b/src/i18n/__tests__/request.test.ts @@ -18,42 +18,6 @@ vi.mock('./routing', () => ({ describe('i18n request configuration', () => { describe('getRequestConfig', () => { - it('should export a request configuration function', async () => { - // Import after mocks are set up - const requestConfig = await import('../request'); - - expect(requestConfig.default).toBeDefined(); - expect(typeof requestConfig.default).toBe('function'); - }); - - it('should be a function that can be called with request locale parameter', async () => { - const { hasLocale } = await import('next-intl'); - const requestConfig = await import('../request'); - - // Mock hasLocale to return true for valid locales - vi.mocked(hasLocale).mockImplementation((locales, locale) => - (locales as string[]).includes(locale as string), - ); - - // Mock dynamic import - vi.doMock( - '@/i18n/messages/en.json', - () => ({ - default: { test: 'English test message' }, - }), - { virtual: true }, - ); - - const mockRequestLocale = Promise.resolve('en'); - const result = await requestConfig.default({ - requestLocale: mockRequestLocale, - }); - - expect(result).toBeDefined(); - expect(result).toHaveProperty('locale'); - expect(result).toHaveProperty('messages'); - }); - it('should handle valid locales correctly', async () => { const { hasLocale } = await import('next-intl'); const requestConfig = await import('../request'); @@ -62,13 +26,9 @@ describe('i18n request configuration', () => { vi.mocked(hasLocale).mockReturnValue(true); // Mock dynamic import - vi.doMock( - '@/i18n/messages/en.json', - () => ({ - default: { welcome: 'Welcome' }, - }), - { virtual: true }, - ); + vi.doMock('@/i18n/messages/en.json', () => ({ + default: { welcome: 'Welcome' }, + })); const mockRequestLocale = Promise.resolve('en'); const result = await requestConfig.default({ @@ -87,13 +47,9 @@ describe('i18n request configuration', () => { vi.mocked(hasLocale).mockReturnValue(false); // Mock dynamic import for default locale - vi.doMock( - '@/i18n/messages/en.json', - () => ({ - default: { welcome: 'Welcome' }, - }), - { virtual: true }, - ); + vi.doMock('@/i18n/messages/en.json', () => ({ + default: { welcome: 'Welcome' }, + })); const mockRequestLocale = Promise.resolve('invalid'); const result = await requestConfig.default({ @@ -103,47 +59,5 @@ describe('i18n request configuration', () => { expect(result.locale).toBe('en'); // Should fall back to default expect(hasLocale).toHaveBeenCalledWith(['en', 'fr'], 'invalid'); }); - - it('should handle different valid locales', async () => { - const { hasLocale } = await import('next-intl'); - const requestConfig = await import('../request'); - - // Test French locale - vi.mocked(hasLocale).mockReturnValue(true); - - // Mock dynamic import for French - vi.doMock( - '@/i18n/messages/fr.json', - () => ({ - default: { welcome: 'Bienvenue' }, - }), - { virtual: true }, - ); - - const mockRequestLocale = Promise.resolve('fr'); - const result = await requestConfig.default({ - requestLocale: mockRequestLocale, - }); - - expect(result.locale).toBe('fr'); - expect(hasLocale).toHaveBeenCalledWith(['en', 'fr'], 'fr'); - }); - }); - - describe('module structure', () => { - it('should export default function', async () => { - const module = await import('../request'); - - expect(module.default).toBeDefined(); - expect(typeof module.default).toBe('function'); - }); - - it('should not export named exports', async () => { - const module = await import('../request'); - - // Should only have default export - const exports = Object.keys(module).filter((key) => key !== 'default'); - expect(exports).toHaveLength(0); - }); }); }); diff --git a/src/i18n/__tests__/routing.test.ts b/src/i18n/__tests__/routing.test.ts index 8346877..f0d7363 100644 --- a/src/i18n/__tests__/routing.test.ts +++ b/src/i18n/__tests__/routing.test.ts @@ -3,39 +3,11 @@ import { routing } from '../routing'; describe('i18n routing', () => { describe('routing configuration', () => { - it('should have correct locales configured', () => { + it('should have correct routing configuration', () => { expect(routing.locales).toEqual(['en', 'fr']); - }); - - it('should have correct default locale', () => { expect(routing.defaultLocale).toBe('en'); - }); - - it('should have localePrefix set to always', () => { expect(routing.localePrefix).toBe('always'); - }); - - it('should have localeDetection disabled', () => { expect(routing.localeDetection).toBe(false); }); - - it('should export a valid routing object', () => { - expect(routing).toBeDefined(); - expect(typeof routing).toBe('object'); - expect(routing.locales).toBeInstanceOf(Array); - expect(routing.locales.length).toBeGreaterThan(0); - }); - - it('should include English locale', () => { - expect(routing.locales).toContain('en'); - }); - - it('should include French locale', () => { - expect(routing.locales).toContain('fr'); - }); - - it('should only have 2 locales', () => { - expect(routing.locales).toHaveLength(2); - }); }); }); diff --git a/src/types/__tests__/routing.test.ts b/src/types/__tests__/routing.test.ts index 5a725cd..6c15cfa 100644 --- a/src/types/__tests__/routing.test.ts +++ b/src/types/__tests__/routing.test.ts @@ -10,44 +10,9 @@ describe('routing types', () => { expect(ViewRoute.Blog).toBe('/blog'); expect(ViewRoute.Contact).toBe('/contact'); }); - - it('should have exactly 4 routes', () => { - const routeValues = Object.values(ViewRoute); - expect(routeValues).toHaveLength(4); - }); - - it('should have string values for all routes', () => { - Object.values(ViewRoute).forEach((route) => { - expect(typeof route).toBe('string'); - expect(route.startsWith('/')).toBe(true); - }); - }); - - it('should not have duplicate values', () => { - const routeValues = Object.values(ViewRoute); - const uniqueValues = [...new Set(routeValues)]; - expect(routeValues.length).toBe(uniqueValues.length); - }); - - it('should use lowercase paths', () => { - Object.values(ViewRoute).forEach((route) => { - expect(route).toBe(route.toLowerCase()); - }); - }); }); describe('AppRoute interface', () => { - it('should accept valid AppRoute object with minimal properties', () => { - const route: AppRoute = { - viewRoute: ViewRoute.Terminal, - timeStamp: Date.now(), - }; - - expect(route.viewRoute).toBe(ViewRoute.Terminal); - expect(typeof route.timeStamp).toBe('number'); - expect(route.param).toBeUndefined(); - }); - it('should accept AppRoute with string param', () => { const route: AppRoute = { viewRoute: ViewRoute.Whoami, @@ -71,28 +36,9 @@ describe('routing types', () => { expect(route.param).toBe(123); expect(typeof route.timeStamp).toBe('number'); }); - - it('should accept all ViewRoute values', () => { - Object.values(ViewRoute).forEach((viewRoute) => { - const route: AppRoute = { - viewRoute, - timeStamp: Date.now(), - }; - - expect(route.viewRoute).toBe(viewRoute); - }); - }); }); describe('RouteData interface', () => { - it('should accept valid RouteData object', () => { - const routeData: RouteData = { - params: Promise.resolve({ locale: 'en' }), - }; - - expect(routeData.params).toBeInstanceOf(Promise); - }); - it('should handle different locales', async () => { const routeDataEn: RouteData = { params: Promise.resolve({ locale: 'en' }), @@ -108,36 +54,5 @@ describe('routing types', () => { expect(paramsEn.locale).toBe('en'); expect(paramsFr.locale).toBe('fr'); }); - - it('should accept various locale formats', async () => { - const locales = ['en', 'fr', 'en-US', 'fr-CA', 'de-DE']; - - for (const locale of locales) { - const routeData: RouteData = { - params: Promise.resolve({ locale }), - }; - - const params = await routeData.params; - expect(params.locale).toBe(locale); - } - }); - }); - - describe('Type relationships', () => { - it('should work together in realistic scenarios', () => { - const appRoute: AppRoute = { - viewRoute: ViewRoute.Contact, - param: 'form-submitted', - timeStamp: Date.now(), - }; - - const routeData: RouteData = { - params: Promise.resolve({ locale: 'en' }), - }; - - expect(appRoute.viewRoute).toBe('/contact'); - expect(typeof appRoute.param).toBe('string'); - expect(routeData.params).toBeInstanceOf(Promise); - }); }); }); diff --git a/src/types/__tests__/terminal.test.ts b/src/types/__tests__/terminal.test.ts index 177159e..321565f 100644 --- a/src/types/__tests__/terminal.test.ts +++ b/src/types/__tests__/terminal.test.ts @@ -19,42 +19,9 @@ describe('terminal types', () => { expect(Command.SetLang).toBe('set-lang'); expect(Command.Whoami).toBe('whoami'); }); - - it('should have exactly 8 commands', () => { - const commandValues = Object.values(Command); - expect(commandValues).toHaveLength(8); - }); - - it('should have string values for all commands', () => { - Object.values(Command).forEach((command) => { - expect(typeof command).toBe('string'); - expect(command.length).toBeGreaterThan(0); - }); - }); - - it('should use kebab-case for multi-word commands', () => { - expect(Command.Web3Mission).toBe('web3-mission'); - expect(Command.SetLang).toBe('set-lang'); - }); - - it('should not have duplicate values', () => { - const commandValues = Object.values(Command); - const uniqueValues = [...new Set(commandValues)]; - expect(commandValues.length).toBe(uniqueValues.length); - }); }); describe('CommandEntry interface', () => { - it('should accept valid CommandEntry object', () => { - const entry: CommandEntry = { - timestamp: Date.now(), - cmdName: Command.Clear, - }; - - expect(entry.timestamp).toBeTypeOf('number'); - expect(entry.cmdName).toBe(Command.Clear); - }); - it('should accept CommandEntry with all optional properties', () => { const mockOutput = () => null; @@ -72,47 +39,9 @@ describe('terminal types', () => { expect(entry.argName).toBe('test-arg'); expect(entry.argValue).toBe('test-value'); }); - - it('should work with numeric argValue', () => { - const entry: CommandEntry = { - timestamp: Date.now(), - cmdName: Command.SetLang, - argValue: '123', - }; - - expect(entry.argValue).toBe('123'); - }); - }); - - describe('CommandOutputProps interface', () => { - it('should accept valid CommandOutputProps object', () => { - const mockTranslator = (key: string) => key; - const entry: CommandEntry = { - timestamp: Date.now(), - cmdName: Command.Help, - }; - - const props: CommandOutputProps = { - entry, - t: mockTranslator, - }; - - expect(props.entry).toBe(entry); - expect(props.t).toBe(mockTranslator); - expect(typeof props.t).toBe('function'); - }); }); describe('CommandArgument interface', () => { - it('should accept valid CommandArgument object', () => { - const arg: CommandArgument = { - name: 'language', - }; - - expect(arg.name).toBe('language'); - expect(arg.options).toBeUndefined(); - }); - it('should accept CommandArgument with options', () => { const arg: CommandArgument = { name: 'language', @@ -126,17 +55,6 @@ describe('terminal types', () => { }); describe('CommandInfo interface', () => { - it('should accept valid CommandInfo object with minimal properties', () => { - const info: CommandInfo = { - name: Command.Clear, - }; - - expect(info.name).toBe(Command.Clear); - expect(info.output).toBeUndefined(); - expect(info.arguments).toBeUndefined(); - expect(info.options).toBeUndefined(); - }); - it('should accept CommandInfo with all properties', () => { const mockOutput = () => null; const mockArguments: CommandArgument[] = [ diff --git a/src/utils/__tests__/chunk-retry.test.ts b/src/utils/__tests__/chunk-retry.test.ts index 6c80502..69c24f2 100644 --- a/src/utils/__tests__/chunk-retry.test.ts +++ b/src/utils/__tests__/chunk-retry.test.ts @@ -39,22 +39,6 @@ describe('ChunkRetryManager', () => { expect(mockLoadFn).toHaveBeenCalledTimes(1); }); - it('should track retry statistics', async () => { - const mockLoadFn = vi.fn().mockImplementation(() => { - const error = new Error('Network timeout'); - error.name = 'NetworkError'; - throw error; - }); - - await expect( - manager.retryChunkLoad('test-chunk', mockLoadFn), - ).rejects.toThrow(); - - const stats = manager.getRetryStats(); - expect(stats['test-chunk']).toBeDefined(); - expect(stats['test-chunk']).toBeGreaterThan(0); - }, 10000); // 10 second timeout - it('should use exponential backoff', async () => { const startTime = Date.now(); const mockLoadFn = vi.fn().mockImplementation(() => { @@ -81,29 +65,4 @@ describe('ChunkRetryManager', () => { expect(mockLoadFn).toHaveBeenCalledTimes(1); expect(manager.getRetryStats()).toEqual({}); }); - - it('should handle chunk loading errors correctly', async () => { - const mockLoadFn = vi.fn().mockImplementation(() => { - const error = new Error('Loading chunk 123 failed'); - error.name = 'ChunkLoadError'; - throw error; - }); - - await expect( - manager.retryChunkLoad('test-chunk', mockLoadFn), - ).rejects.toThrow('Loading chunk 123 failed'); - expect(mockLoadFn).toHaveBeenCalledTimes(4); // 1 initial + 3 retries - }, 15000); - - it('should handle network timeouts correctly', async () => { - const mockLoadFn = vi.fn().mockImplementation(() => { - const error = new Error('Failed to fetch'); - throw error; - }); - - await expect( - manager.retryChunkLoad('test-chunk', mockLoadFn), - ).rejects.toThrow('Failed to fetch'); - expect(mockLoadFn).toHaveBeenCalledTimes(4); // 1 initial + 3 retries - }, 15000); }); diff --git a/src/utils/__tests__/compare-utils.test.ts b/src/utils/__tests__/compare-utils.test.ts index 1b0d991..d3f4489 100644 --- a/src/utils/__tests__/compare-utils.test.ts +++ b/src/utils/__tests__/compare-utils.test.ts @@ -14,30 +14,6 @@ describe('compare-utils', () => { expect(isNewRouteEvent(null, newEvent)).toBe(true); }); - it('should return true when newEvent exists and oldEvent is undefined', () => { - const newEvent: AppRoute = { - viewRoute: ViewRoute.Terminal, - timeStamp: 123456, - }; - expect(isNewRouteEvent(undefined, newEvent)).toBe(true); - }); - - it('should return false when newEvent is null', () => { - const oldEvent: AppRoute = { - viewRoute: ViewRoute.Terminal, - timeStamp: 123456, - }; - expect(isNewRouteEvent(oldEvent, null)).toBe(false); - }); - - it('should return false when newEvent is undefined', () => { - const oldEvent: AppRoute = { - viewRoute: ViewRoute.Terminal, - timeStamp: 123456, - }; - expect(isNewRouteEvent(oldEvent, undefined)).toBe(false); - }); - it('should return true when viewRoute is different', () => { const oldEvent: AppRoute = { viewRoute: ViewRoute.Terminal, @@ -89,33 +65,6 @@ describe('compare-utils', () => { }; expect(isNewRouteEvent(oldEvent, newEvent)).toBe(false); }); - - it('should handle undefined params correctly', () => { - const oldEvent: AppRoute = { - viewRoute: ViewRoute.Terminal, - timeStamp: 123456, - }; - const newEvent: AppRoute = { - viewRoute: ViewRoute.Terminal, - param: 'param1', - timeStamp: 123456, - }; - expect(isNewRouteEvent(oldEvent, newEvent)).toBe(true); - }); - - it('should handle numeric params', () => { - const oldEvent: AppRoute = { - viewRoute: ViewRoute.Terminal, - param: 1, - timeStamp: 123456, - }; - const newEvent: AppRoute = { - viewRoute: ViewRoute.Terminal, - param: 2, - timeStamp: 123456, - }; - expect(isNewRouteEvent(oldEvent, newEvent)).toBe(true); - }); }); describe('isNewKeyEvent', () => { @@ -144,21 +93,6 @@ describe('compare-utils', () => { expect(isNewKeyEvent(null, newEvent)).toBe(true); }); - it('should return true when newEvent exists and oldEvent is undefined', () => { - const newEvent = createKeyboardEvent('Enter', 123456); - expect(isNewKeyEvent(undefined, newEvent)).toBe(true); - }); - - it('should return false when newEvent is null', () => { - const oldEvent = createKeyboardEvent('Enter', 123456); - expect(isNewKeyEvent(oldEvent, null)).toBe(false); - }); - - it('should return false when newEvent is undefined', () => { - const oldEvent = createKeyboardEvent('Enter', 123456); - expect(isNewKeyEvent(oldEvent, undefined)).toBe(false); - }); - it('should return true when key is different', () => { const oldEvent = createKeyboardEvent('Enter', 123456); const newEvent = createKeyboardEvent('Escape', 123456); @@ -176,17 +110,5 @@ describe('compare-utils', () => { const newEvent = createKeyboardEvent('Enter', 123456); expect(isNewKeyEvent(oldEvent, newEvent)).toBe(false); }); - - it('should handle special keys', () => { - const oldEvent = createKeyboardEvent('ArrowUp', 123456); - const newEvent = createKeyboardEvent('ArrowDown', 123456); - expect(isNewKeyEvent(oldEvent, newEvent)).toBe(true); - }); - - it('should handle space key', () => { - const oldEvent = createKeyboardEvent(' ', 123456); - const newEvent = createKeyboardEvent('Enter', 123456); - expect(isNewKeyEvent(oldEvent, newEvent)).toBe(true); - }); }); }); diff --git a/src/utils/__tests__/helpers.test.ts b/src/utils/__tests__/helpers.test.ts index 15026d6..58633ba 100644 --- a/src/utils/__tests__/helpers.test.ts +++ b/src/utils/__tests__/helpers.test.ts @@ -12,50 +12,5 @@ describe('helpers', () => { 'class1 class2 class3', ); }); - - it('should handle numbers by filtering them out', () => { - expect(cx('class1', 123, 'class2')).toBe('class1 class2'); - }); - - it('should handle arrays by flattening them', () => { - expect(cx(['class1', 'class2'], 'class3')).toBe('class1 class2 class3'); - }); - - it('should handle nested arrays', () => { - // Only one level of flattening, nested arrays are filtered out (not strings) - expect(cx(['class1', ['class2', 'class3']], 'class4')).toBe( - 'class1 class4', - ); - }); - - it('should trim the result', () => { - // Only trims outer whitespace, not between words - expect(cx(' class1 ', ' class2 ')).toBe('class1 class2'); - }); - - it('should return empty string for no valid classes', () => { - expect(cx(null, undefined, false, 123)).toBe(''); - }); - - it('should handle empty arrays', () => { - expect(cx([], 'class1')).toBe('class1'); - }); - - it('should handle mixed nested structures', () => { - // Nested arrays are filtered out since they're not strings - expect( - cx(['class1', null, ['class2', undefined, 'class3']], false, 'class4'), - ).toBe('class1 class4'); - }); - - it('should handle empty strings', () => { - // Empty strings are included in the join, creating extra spaces - expect(cx('', 'class1', '', 'class2')).toBe('class1 class2'); - }); - - it('should handle whitespace-only strings', () => { - // Whitespace-only strings are included in the join - expect(cx(' ', 'class1', ' ', 'class2')).toBe('class1 class2'); - }); }); }); diff --git a/src/utils/__tests__/metadata-utils.test.ts b/src/utils/__tests__/metadata-utils.test.ts index 1921ecc..76e5745 100644 --- a/src/utils/__tests__/metadata-utils.test.ts +++ b/src/utils/__tests__/metadata-utils.test.ts @@ -77,127 +77,5 @@ describe('metadata-utils', () => { namespace: 'Pages', }); }); - - it('should handle different locales', async () => { - const { getTranslations } = await import('next-intl/server'); - const mockGetTranslations = vi.mocked(getTranslations); - - const mockTMeta = vi.fn((key: string) => { - if (key === 'title') return 'Site de Test'; - if (key === 'description') return 'Description de Test'; - return key; - }); - - mockGetTranslations.mockResolvedValue(mockTMeta); - - const routeData: RouteData = { - params: Promise.resolve({ locale: 'fr' }), - }; - - const result = await setPageMeta(routeData); - - expect(result).toEqual({ - title: 'Site de Test', - description: 'Description de Test', - }); - - expect(mockGetTranslations).toHaveBeenCalledWith({ - locale: 'fr', - namespace: 'Metadata', - }); - }); - - it('should handle whoami page', async () => { - const { getTranslations } = await import('next-intl/server'); - const mockGetTranslations = vi.mocked(getTranslations); - - const mockTMeta = vi.fn((key: string) => { - if (key === 'title') return 'My Site'; - if (key === 'description') return 'My Description'; - return key; - }); - - const mockTPages = vi.fn((key: string) => { - if (key === 'whoami') return 'Who Am I'; - return key; - }); - - mockGetTranslations - .mockResolvedValueOnce(mockTMeta) - .mockResolvedValueOnce(mockTPages); - - const routeData: RouteData = { - params: Promise.resolve({ locale: 'en' }), - }; - - const result = await setPageMeta(routeData, 'whoami'); - - expect(result).toEqual({ - title: 'Who Am I @ My Site', - description: 'My Description', - }); - }); - - it('should handle mission page', async () => { - const { getTranslations } = await import('next-intl/server'); - const mockGetTranslations = vi.mocked(getTranslations); - - const mockTMeta = vi.fn((key: string) => { - if (key === 'title') return 'My Site'; - if (key === 'description') return 'My Description'; - return key; - }); - - const mockTPages = vi.fn((key: string) => { - if (key === 'mission') return 'Mission'; - return key; - }); - - mockGetTranslations - .mockResolvedValueOnce(mockTMeta) - .mockResolvedValueOnce(mockTPages); - - const routeData: RouteData = { - params: Promise.resolve({ locale: 'en' }), - }; - - const result = await setPageMeta(routeData, 'mission'); - - expect(result).toEqual({ - title: 'Mission @ My Site', - description: 'My Description', - }); - }); - - it('should handle terminal page', async () => { - const { getTranslations } = await import('next-intl/server'); - const mockGetTranslations = vi.mocked(getTranslations); - - const mockTMeta = vi.fn((key: string) => { - if (key === 'title') return 'My Site'; - if (key === 'description') return 'My Description'; - return key; - }); - - const mockTPages = vi.fn((key: string) => { - if (key === 'terminal') return 'Terminal'; - return key; - }); - - mockGetTranslations - .mockResolvedValueOnce(mockTMeta) - .mockResolvedValueOnce(mockTPages); - - const routeData: RouteData = { - params: Promise.resolve({ locale: 'en' }), - }; - - const result = await setPageMeta(routeData, 'terminal'); - - expect(result).toEqual({ - title: 'Terminal @ My Site', - description: 'My Description', - }); - }); }); }); diff --git a/src/utils/__tests__/terminal-utils.test.ts b/src/utils/__tests__/terminal-utils.test.ts index cb10e22..bfeeb97 100644 --- a/src/utils/__tests__/terminal-utils.test.ts +++ b/src/utils/__tests__/terminal-utils.test.ts @@ -179,30 +179,6 @@ describe('terminal-utils', () => { vi.restoreAllMocks(); }); - - it('should handle empty input', () => { - const mockDate = 1234567890; - vi.spyOn(Date, 'now').mockReturnValue(mockDate); - - const entry = parseTerminalEntry(''); - - expect(entry.cmdName).toBe('' as Command); - expect(entry.timestamp).toBe(mockDate); - - vi.restoreAllMocks(); - }); - - it('should handle command with multiple spaces', () => { - const mockDate = 1234567890; - vi.spyOn(Date, 'now').mockReturnValue(mockDate); - - const entry = parseTerminalEntry('help extra args'); - - expect(entry.cmdName).toBe(Command.Help); - expect(entry.option).toBe(''); // split(' ') with multiple spaces creates empty strings - - vi.restoreAllMocks(); - }); }); describe('getTerminalEntryInput', () => { @@ -247,25 +223,5 @@ describe('terminal-utils', () => { expect(getTerminalEntryInput(entry)).toBe('set-lang en --lang=english'); }); - - it('should handle entry with only argName but no argValue', () => { - const entry: CommandEntry = { - cmdName: Command.SetLang, - argName: 'lang', - timestamp: 123456, - }; - - expect(getTerminalEntryInput(entry)).toBe('set-lang --lang=undefined'); - }); - - it('should handle entry with only argValue but no argName', () => { - const entry: CommandEntry = { - cmdName: Command.SetLang, - argValue: 'english', - timestamp: 123456, - }; - - expect(getTerminalEntryInput(entry)).toBe('set-lang'); - }); }); }); From 8f09dbc84ca09b0f632d1e6b761dcfc1fce5317d Mon Sep 17 00:00:00 2001 From: Xavier Saliniere Date: Tue, 2 Sep 2025 08:13:48 -0400 Subject: [PATCH 2/2] docs: minor README update --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 385f750..0ac0ea2 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Licensed under GPL-3.0. Still a work in progress, but it already lives on the InterPlanetary FileSystem: -- IPNS Hash: `k2k4r8ng8uzrtqb5ham8kao889m8qezu96z4w3lpinyqghum43veb6n3` +- IPNS Name: `k2k4r8ng8uzrtqb5ham8kao889m8qezu96z4w3lpinyqghum43veb6n3` - [Access through eth.limo](https://nipsys.eth.limo) - [Access through dweb.link](https://k2k4r8ng8uzrtqb5ham8kao889m8qezu96z4w3lpinyqghum43veb6n3.ipns.dweb.link/) @@ -26,8 +26,8 @@ Still a work in progress, but it already lives on the InterPlanetary FileSystem: - [x] responsive design - [x] internationalization - [x] automatic deployment on IPFS -- [_] content is still being written -- [_] pages are still being added & refined +- [] content is still being written +- [] pages are still being added & refined ## commands