diff --git a/src/tools/diagnostics.test.ts b/src/tools/diagnostics.test.ts new file mode 100644 index 0000000..4b6fa95 --- /dev/null +++ b/src/tools/diagnostics.test.ts @@ -0,0 +1,53 @@ +import { expect, test, describe, beforeEach } from "bun:test"; +import { mkdtempSync, writeFileSync } from "node:fs"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; +import { runDiagnostics, configureDiagnostics } from "./diagnostics"; + +let tmp: string; + +beforeEach(() => { + tmp = mkdtempSync(join(tmpdir(), "klaatai-diag-")); + configureDiagnostics({ enabled: true, timeoutMs: 8_000 }); +}); + +describe("Ruby diagnostics (.rb)", () => { + test("returns null for .rb when rubocop is not on PATH (silently skipped)", () => { + const absPath = join(tmp, "foo.rb"); + writeFileSync(absPath, 'puts "hello"\n'); + const result = runDiagnostics(absPath, tmp); + expect(result === null || typeof result === "string").toBe(true); + }); + + test("returns null for .rb when diagnostics are disabled", () => { + configureDiagnostics({ enabled: false }); + const absPath = join(tmp, "foo.rb"); + writeFileSync(absPath, 'puts "hello"\n'); + expect(runDiagnostics(absPath, tmp)).toBeNull(); + }); + + test("returns null for .rb when rubocop is absent (no override)", () => { + // No config override, rubocop not on PATH in CI — must return null, never throw. + const absPath = join(tmp, "bar.rb"); + writeFileSync(absPath, "def foo; end\n"); + expect(() => runDiagnostics(absPath, tmp)).not.toThrow(); + const result = runDiagnostics(absPath, tmp); + // null = rubocop absent (expected in CI); string = rubocop present and found issues + expect(result === null || typeof result === "string").toBe(true); + }); + + test("non-.rb files are unaffected by the Ruby branch", () => { + const absPath = join(tmp, "foo.py"); + writeFileSync(absPath, "x = 1\n"); + expect(() => runDiagnostics(absPath, tmp)).not.toThrow(); + }); + + test("returns null for .rb when config explicitly disables the extension via empty commands", () => { + configureDiagnostics({ enabled: true, timeoutMs: 8_000, commands: {} }); + const absPath = join(tmp, "baz.rb"); + writeFileSync(absPath, 'puts "test"\n'); + // No override for .rb, rubocop not on PATH -> null + const result = runDiagnostics(absPath, tmp); + expect(result === null || typeof result === "string").toBe(true); + }); +}); diff --git a/src/tools/diagnostics.ts b/src/tools/diagnostics.ts index baa86ef..46ee499 100644 --- a/src/tools/diagnostics.ts +++ b/src/tools/diagnostics.ts @@ -69,6 +69,10 @@ function commandFor(absPath: string, projectRoot: string): string[] | null { if (onPath("gofmt")) return ["gofmt", "-e", "-l", absPath]; // -e reports syntax errors return null; } + if (ext === ".rb") { + if (onPath("rubocop")) return ["rubocop", "--format", "emacs", "--no-color", absPath]; + return null; + } if (ext === ".rs") { // cargo check is whole-crate/slow — only via explicit config override. return null;