Skip to content

[nightshift] Test Gap Finder #2

@nightshift-micr

Description

@nightshift-micr

[nightshift] Test Gap Finder: micr-dev/projects

Summary

micr-dev/projects is a Next.js 16 portfolio/showcase site with zero test coverage. No test framework is installed, no test files exist, and no test scripts are defined in package.json.

Repository Stats

  • Framework: Next.js 16.1.6, React 19, TypeScript 5.9
  • Source files: 4 (page.tsx, layout.tsx, smooth-scroll.tsx, skiper80.tsx)
  • Total LOC: ~210 lines of application code
  • Test files: 0
  • Test dependencies: None

Findings

P1 — No test infrastructure exists

No test framework (Jest, Vitest, React Testing Library) is installed in package.json. The scripts section has no test command.

Impact: Any code change risks regressions with no automated safety net.

Recommendation: Install Vitest + React Testing Library (@testing-library/react, @testing-library/jest-dom). Add a test script to package.json.

P2 — getRepoSections() parser untested (app/page.tsx, lines 10-38)

The getRepoSections() function parses REPO.md with custom string logic:

  • Splits on \r?\n, trims lines, skips blanks and # Repo List header
  • Parses ## prefixed sections into {heading, titles[]} structs
  • Accumulates titles into the current section

Untested edge cases:

  • Empty REPO.md file → returns [] (no error)
  • REPO.md with titles before any ## heading → titles silently dropped
  • Lines with only whitespace → trimmed to empty, skipped
  • Malformed headings like ### or ##No space → not parsed as sections
  • Very large files → memory/performance

Recommendation: Add unit tests for getRepoSections() covering empty input, no-sections input, malformed headings, and typical multi-section input.

P2 — Skiper80 component state logic untested (components/skiper/skiper80.tsx)

The Skiper80 component (lines 22-84) has state-dependent behavior:

  • isHoveredIndex defaults to 0, cycles through placeholderImages
  • items is computed via sections.flatMap() — image index uses modulo
  • Line 57: isHoveredIndex == index uses loose equality (should be ===)
  • items.indexOf(title) on line 50 is O(n) and could return -1 for duplicates

Untested behaviors:

  • Empty sections array → no items rendered, no crash
  • Sections with empty titles arrays → section heading shown, no items
  • Duplicate titles across sections → indexOf returns first match
  • Index wrapping via % placeholderImages.length

Recommendation: Add component tests with React Testing Library. Test hover state changes, empty input, and duplicate title handling.

P3 — SmoothScroll cleanup untested (app/smooth-scroll.tsx, lines 6-33)

The Lenis smooth scroll integration:

  • Creates requestAnimationFrame loop on mount
  • Cleans up via cancelAnimationFrame + lenis.destroy() on unmount
  • No error handling if Lenis constructor fails (e.g., SSR mismatch)

Recommendation: Test that cleanup properly cancels animation frames and destroys Lenis instance.

P3 — Loose equality operator (skiper80.tsx, line 57)

style={{ opacity: isHoveredIndex == index ? 1 : 0.5 }}

Uses == instead of ===. While both operands are numbers (so behavior is identical), this is inconsistent with TypeScript best practices and the rest of the codebase.

Priority Recommendations

  1. Install Vitest + React Testing Library — foundational infrastructure
  2. Test getRepoSections() parser — pure function, easy to unit test, highest ROI
  3. Test Skiper80 rendering — verify empty/edge-case inputs
  4. Add test script to package.json — enables CI integration

Estimated Test Coverage Gap

Module Current Target
app/page.tsx 0% 80%+
components/skiper/skiper80.tsx 0% 70%+
app/smooth-scroll.tsx 0% 60%+
app/layout.tsx 0% N/A (metadata only)
Overall 0% 70%+

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions