import * as assert from 'assert'; import * as vscode from 'vscode'; import { LinterContext } from '../../core/LinterContext'; import { SyntaxRule } from '../../core/rules/SyntaxRule'; import { BlockRule } from '../../core/rules/BlockRule'; suite('Linter Test Suite', () => { test('SyntaxRule: Ignoriert URLs und Sonderzeichen in Strings', () => { const rule = new SyntaxRule(); const ctx = new LinterContext(); ctx.activePhaseName = 'body'; // Erlaubte Zone const rawLine = ' log.debug("https://example.com/api?q=1//test");'; rule.checkLine(rawLine.trim(), rawLine, 0, ctx, [rawLine]); // Darf keinen Fehler werfen (weder fehlendes Semikolon noch kaputter Kommentar) assert.strictEqual(ctx.diagnostics.length, 0); }); test('SyntaxRule: Erfasst TODOs als Information', () => { const rule = new SyntaxRule(); const ctx = new LinterContext(); const rawLine = ' // TODO: Diese Funktion refactoren'; rule.checkLine(rawLine.trim(), rawLine, 0, ctx, [rawLine]); assert.strictEqual(ctx.diagnostics.length, 1); assert.strictEqual(ctx.diagnostics[0].severity, vscode.DiagnosticSeverity.Information); assert.ok(ctx.diagnostics[0].message.includes("TODO: Diese Funktion refactoren")); }); test('SyntaxRule: Multi-Line if-Bedingung ohne Semikolon-Fehler', () => { const rule = new SyntaxRule(); const ctx = new LinterContext(); ctx.activePhaseName = 'body'; // Zeile 1: or-Umbruch rule.checkLine('if x = 1 or', 'if x = 1 or', 0, ctx, []); assert.strictEqual(ctx.diagnostics.length, 0); assert.strictEqual(ctx.inConditionBlock, true); // Zeile 2: then-Abschluss rule.checkLine('y = 2 then', 'y = 2 then', 1, ctx, []); assert.strictEqual(ctx.diagnostics.length, 0, "'then' darf kein Semikolon am Ende verlangen!"); assert.strictEqual(ctx.inConditionBlock, false); }); test('SyntaxRule: Akzeptiert Zuweisungen in erlaubten Zonen (z.B. metadata)', () => { const rule = new SyntaxRule(); const ctx = new LinterContext(); ctx.inModuleMetadata = true; // Wir sind im Modul-Metadata const rawLine = " origin := 'Custom';"; rule.checkLine(rawLine.trim(), rawLine, 0, ctx, [rawLine]); assert.strictEqual(ctx.diagnostics.length, 0, "Zuweisungen müssen in metadata erlaubt sein"); }); test('BlockRule: if/for/while Stack-Tracking', () => { const rule = new BlockRule(); const ctx = new LinterContext(); ctx.hasModuleDef = true; ctx.inBlock = 'pattern'; // Öffnet Block rule.checkLine('if true then', 'if true then', 0, ctx, []); assert.strictEqual(ctx.openControlBlocks.length, 1); assert.strictEqual(ctx.openControlBlocks[0].type, 'if'); // Schließt falschen Block (end for statt end if) rule.checkLine('end for;', 'end for;', 1, ctx, []); assert.strictEqual(ctx.diagnostics.length, 1); assert.ok(ctx.diagnostics[0].message.includes("Falsches Ende")); }); });