Skip to content

[BUG] Coverage analyzer misses semantic wrappers and drops coverage provenance #291

Description

@ifBars

Summary

The coverage analyzer under-reports semantic S1API coverage when an API mirrors or adapts a game type without retaining a directly discoverable native type reference. It also reports many covered types without identifying the S1API type responsible for that coverage.

The current stable workflow artifact from run https://github.com/ifBars/S1API/actions/runs/33136305032 reports 409/1,096 eligible game types covered (37.32%), but:

  • ScheduleOne.Temperature.TemperatureUtility is listed as uncovered even though S1API.Temperature.TemperatureUtility directly delegates to it.
  • ScheduleOne.Temperature.TemperatureEmitterInfo is listed as uncovered even though the delivered temperature API exposes the managed mirror.
  • ScheduleOne.Casino.CasinoGameInteraction and ScheduleOne.Casino.CardController remain uncovered after the managed casino lifecycle API was delivered in [FEATURE] Expose casino game state and lifecycle events #239.
  • 104 of the 409 covered types (25.43%) have no coveredBy value in the JSON report.

Current behavior

ApiAssemblyAnalyzer infers coverage from reflection-visible native type references in fields, properties, signatures, IL tokens, inheritance, generics, and attributes. CoverageCalculator then adds nested-type and fuzzy-name heuristics.

This misses intentionally runtime-agnostic mirrors/snapshots and reflection-based adapters. Separately, FindCoveringApiType only handles exact/normalized matches and the fuzzy cache, so types accepted through the parent/nested strategy can be marked covered without provenance.

Expected behavior

The report should distinguish verified semantic mappings from heuristic candidates and identify the responsible S1API type for every type counted as covered.

Proposed scope

  • Add an explicit, testable mapping mechanism for APIs that intentionally cover a native type without exposing it in the public surface. An internal attribute or analyzer-owned manifest using normalized type names would both fit.
  • Carry the matched S1API type and match strategy through coverage calculation instead of returning only a boolean.
  • Populate coveredBy for exact, normalized, nested, explicit, and accepted fuzzy matches.
  • Add regression fixtures for direct wrappers, runtime-agnostic mirrors, reflection-based adapters, nested types, and similarly named unrelated types.
  • Include the match strategy in the detailed JSON report so fuzzy matches can be audited.
  • Re-run stable coverage and update the badge/history only after the corrected report is reviewed.

Non-goals

  • Implementing member-level coverage in this issue; the repository currently documents that metric as disabled.
  • Counting every incidental native reference as full public API coverage.
  • Making the public mod-author API expose game or generated IL2CPP types solely to satisfy the analyzer.

Acceptance criteria

  • The known temperature examples are attributed to their S1API APIs rather than reported as uncovered.
  • Casino types intentionally covered by [FEATURE] Expose casino game state and lifecycle events #239 can be explicitly attributed without relying on fragile name similarity.
  • Every type counted as covered has a non-empty provenance and match strategy.
  • Regression tests reject at least one similarly named but unrelated false-positive case.
  • The generated report remains deterministic across repeated runs against the same assemblies.

Activity

  1. added
    bugSomething isn't working
    MediumEdge case bugs, etc
    on Aug 29, 2026
  2. self-assigned this
    on Aug 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

MediumEdge case bugs, etcbugSomething isn't working

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions