← back to ClawCoder

src/tests/lib/scorer.test.ts

80 lines

import { describe, it, expect } from 'vitest'
import { analyzeClaudeMd } from '@/lib/analyzer/scorer'

const goodClaudeMd = `# CLAUDE.md

## Workflow
- Make small, reviewable changes.
- Run tests after behavior changes.

## Safety
- Don't modify .env or credentials.
- Don't force push or reset hard.
- Never delete protected files.

## Commands
- Install: npm install
- Dev: npm run dev
- Test: npm test
- Lint: npm run lint

## Code style
Follow .claude/rules/code-style.md

## Architecture
@docs/ARCHITECTURE.md
`

const badClaudeMd = `# My Project
This is my project. It does stuff.
` + 'x\n'.repeat(250)

const secretsClaudeMd = `# CLAUDE.md
API_KEY=sk-abc123def456ghi789
password = hunter2
`

describe('CLAUDE.md Scorer', () => {
  it('scores well-structured content highly', () => {
    const result = analyzeClaudeMd(goodClaudeMd)
    expect(result.overallScore).toBeGreaterThan(60)
    expect(result.letterGrade).toMatch(/^[ABC]/)
    expect(result.percentage).toBeGreaterThan(60)
  })

  it('penalizes bloated content', () => {
    const result = analyzeClaudeMd(badClaudeMd)
    const lineCount = result.criteria.find(c => c.id === 'line-count')!
    expect(lineCount.score).toBeLessThan(lineCount.maxScore)
  })

  it('detects secrets', () => {
    const result = analyzeClaudeMd(secretsClaudeMd)
    const secrets = result.criteria.find(c => c.id === 'no-secrets')!
    expect(secrets.score).toBe(0)
    expect(secrets.findings.length).toBeGreaterThan(0)
  })

  it('returns pros and cons', () => {
    const result = analyzeClaudeMd(goodClaudeMd)
    expect(result.pros.length).toBeGreaterThan(0)
  })

  it('detects modular imports', () => {
    const result = analyzeClaudeMd(goodClaudeMd)
    const modular = result.criteria.find(c => c.id === 'modular-imports')!
    expect(modular.score).toBeGreaterThan(0)
  })

  it('detects missing build commands in minimal content', () => {
    const result = analyzeClaudeMd('# CLAUDE.md\n\nHello world\n')
    const cmds = result.criteria.find(c => c.id === 'build-commands')!
    expect(cmds.score).toBe(0)
  })

  it('returns correct line count', () => {
    const result = analyzeClaudeMd(goodClaudeMd)
    expect(result.lineCount).toBe(goodClaudeMd.split('\n').length)
  })
})