Skip to content

Runtime/IO rules have no test-file awareness — every consumer hand-maintains the same override list #3

Description

@artile

Summary

The runtime/IO-discipline rules — effect-run-in-body, avoid-sync-fs, avoid-direct-json, use-clock-service, use-filesystem-service, use-path-service, stream-large-files, avoid-native-object-helpers, prefer-effect-fn, require-effect-concurrency, use-console-service, avoid-process-env, … — have no built-in test-file detection. In a test they fire on constructs that are legitimate at the test harness boundary, forcing every consumer to hand-maintain a disable list.

Reproduction / current cost

A codebase that runs tests on bun:test treats a test body as the harness boundary: Effect.runPromise(...) in a test, readFileSync of a fixture, JSON.parse of a fixture, and new Date() / Date.now() in assertions are all correct — yet each trips a rule. The only remedy today is two hand-written overrides blocks in the consumer's .oxlintrc.json:

{
  "files": ["**/*.test.ts", "**/scripts/**", "src/main.ts"],
  "rules": { "effect/use-console-service": "off", "effect/avoid-process-env": "off" }
},
{
  "files": ["**/*.test.ts"],
  "rules": {
    "effect/effect-run-in-body": "off",      // bun:test harness boundary
    "effect/avoid-sync-fs": "off",           // fixture loading
    "effect/avoid-direct-json": "off",       // JSON.parse of fixtures
    "effect/use-filesystem-service": "off",
    "effect/use-path-service": "off",
    "effect/stream-large-files": "off",
    "effect/use-clock-service": "off",       // new Date()/Date.now() in assertions
    "effect/avoid-native-object-helpers": "off",
    "effect/prefer-effect-fn": "off",        // spans add nothing in a test body
    "effect/require-effect-concurrency": "off"
  }
}

This list is fragile: every new IO/runtime rule upstream adds means every consumer must remember to extend the override, or eat false positives in test files.

Expected vs actual

  • Expected: the plugin knows a test file is the harness boundary and does not demand production runtime discipline there — or at least ships a copy-pasteable recommended override so consumers don't reverse-engineer it.
  • Actual: no test awareness; each rule fires in test files and every consumer reconstructs the same disable list by hand.

Proposed fix direction

  • Built-in test-glob awareness: let the affected rules no-op (or self-relax) on a configurable testFiles glob (default **/*.{test,spec}.{ts,tsx}), the way many ESLint rules special-case test files, or
  • Ship a documented recommended override set (e.g. an exported recommendedTestOverrides config fragment, or a README section) so consumers get the boundary right in one line, and
  • Tag each rule in its docs as production-only vs always-on so it's clear which belong in the test override and which should stay on.

Filed from downstream adoption in a CosmOS/Effect-4 codebase (vendored pristine fork of upstream 0.3.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