package linthost

import (
  "strings"
  "testing"
)

// TestRuleCorpusPreferPromiseRejectErrors verifies a reduced trigger from the lint rule corpus
// fixture typescript-prefer-promise-reject-errors.ts under a real
// Program.
//
// The rule is type-aware: it inspects the reject argument's type via
// `ctx.Checker.GetTypeAtLocation` and flags primitive rejections. A parser-only
// engine run skips the rule, so this test reuses the `command_*` shape: seed a
// tsconfig project, run `ttsc lint check`, and assert on the rendered diagnostics.
//
// 1. Seed a project that rejects with a string literal.
// 2. Run `check` with typescript/prefer-promise-reject-errors enabled as error.
// 3. Assert the command exits non-zero and stderr mentions the rule.
//
// @evidence contracts/testing.md#behavioral-verification Rejecting with a string primitive must report.
// @evidence contracts/testing.md#independent-expectations The original authored input fixes exactly one typescript/prefer-promise-reject-errors rendered error at line 2, code 2 and empty stdout; its independently authored typed counterpart requires code 0 and no rule errors.
// @evidence contracts/testing.md#distinguishing-cases An Error instance is a supported rejection boundary.
// @evidence contracts/testing.md#execution-ownership TestRuleCorpusPreferPromiseRejectErrors invokes the in-process check command and shared typed semantic oracles over real Program/Checker instances; fixture configuration feeds that operation without a native build, child compiler or installed consumer.
func TestRuleCorpusPreferPromiseRejectErrors(t *testing.T) {
  root := seedLintProject(t, `function bad(): Promise<never> {
  return Promise.reject("boom");
}
void bad();
`)
  seedLintRules(t, root, map[string]string{"typescript/prefer-promise-reject-errors": "error"})

  code, stdout, stderr := captureCommandOutput(t, func() int {
    return run([]string{
      "check",
      "--cwd", root,
      "--plugins-json", lintManifest(t),
    })
  })
  if code != 2 || stdout != "" || !strings.Contains(stderr, "[typescript/prefer-promise-reject-errors]") {
    t.Fatalf("prefer-promise-reject-errors diagnostic mismatch: code=%d stdout=%q stderr=%q", code, stdout, stderr)
  }
  assertTypedRuleRenderedErrors(t, "typescript/prefer-promise-reject-errors", stderr, 2)
  assertTypedRuleCleanSource(t, "typescript/prefer-promise-reject-errors", "function good(): Promise<never> { return Promise.reject(new Error(\"boom\")); }\nvoid good;\n")
}
