Skip to content

JavaScript plugin missing test_coverage hooks — test mapping always empty #514

@elfensky

Description

@elfensky

Problem

When scanning a JavaScript project (.js/.jsx/.mjs files with jsconfig.json), the test coverage detector correctly classifies test files into the test zone but cannot map them to production files. This causes most modules to be reported as untested despite having comprehensive test suites.

A common example is a Next.js project created without TypeScript — these use jsconfig.json instead of tsconfig.json and .js/.jsx/.mjs files throughout.

This is a separate issue from #502 (graph path normalization sampling).

Root Cause

The JavaScript language plugin (desloppify/languages/javascript/) has no test_coverage.py module. The TypeScript plugin has one with all the required hooks:

  • map_test_to_source()
  • resolve_import_spec()
  • strip_test_markers()
  • parse_test_import_specs()
  • has_testable_logic()

When _load_lang_test_coverage_module("javascript") is called (in mapping_imports.py:13), it returns a bare object() via get_lang_hook(). Every subsequent getattr(mod, 'map_test_to_source', None) returns None, so both naming-based and import-based mapping silently produce empty results.

Reproduction

Public repo for testing: elfensky/helldivers.bot

  • Next.js app without TypeScript, using .mjs/.jsx/.js files with jsconfig.json (no tsconfig.json)
  • Test files at src/__tests__/unit/utils/time.test.mjs importing from @/utils/time.mjs
  • 210 passing vitest tests across 16 test files
desloppify scan

State file: state-javascript.json (language correctly auto-detected).

Result: Files like time.mjs, responses.mjs, evaluateProgress.mjs all reported as untested_module despite having dedicated test files with full coverage.

Notably, tryCatch.mjs is correctly recognized as tested — likely via direct dependency graph import edges rather than the naming/import-spec mapping pipeline.

Additional Concern

Even if the JavaScript plugin fell back to the TypeScript test_coverage.py, the _TS_EXTENSIONS list (["", ".ts", ".tsx", "/index.ts", "/index.tsx"]) would never resolve .mjs/.js/.jsx imports. A JavaScript-specific version needs extensions like ["", ".js", ".jsx", ".mjs", ".cjs", "/index.js", "/index.mjs"].

The __tests__/unit/ directory nesting pattern (e.g., src/__tests__/unit/utils/foo.test.mjssrc/utils/foo.mjs) also needs handling — the current map_test_to_source only handles one level of __tests__/ nesting.

Suggested Fix

  1. Create desloppify/languages/javascript/test_coverage.py mirroring the TypeScript version with JS-appropriate extensions
  2. Register the test_coverage hook in the JavaScript plugin (currently __init__.py has no register_hooks)
  3. Handle nested __tests__/unit/ and __tests__/integration/ directory patterns in map_test_to_source()
  4. Add .mjs/.cjs/.js/.jsx to extension resolution candidates

Environment

  • desloppify 0.9.14 (pip install)
  • Run via Claude Code (as a slash command / skill)
  • JavaScript/Next.js project (no TypeScript) with vitest, .mjs files, jsconfig.json
  • macOS Darwin 25.4.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions