bmc-tpl-code-all-around/src/test/suite/linter.test.ts

75 lines
3.1 KiB
TypeScript

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"));
});
});