UNPKG

@digitalnodecom/node-red-contrib-analyzer

Version:

A Node-RED global service that monitors function nodes for debugging artifacts and performance issues. Features real-time quality metrics, Vue.js dashboard, and comprehensive code analysis.

333 lines (277 loc) 12.5 kB
const { detectDebuggingTraits, parseIgnoreDirectives, shouldIgnoreLine } = require('../../lib/detection/detector'); describe('Ignore Directives', () => { describe('parseIgnoreDirectives', () => { test('should parse ignore-start and ignore-end directives', () => { const lines = [ 'console.log("normal");', '// @nr-analyzer-ignore-start', 'return;', 'node.warn("debug");', '// @nr-analyzer-ignore-end', 'console.log("normal again");' ]; const result = parseIgnoreDirectives(lines); expect(result.ignoreRegions).toEqual([ { start: 2, end: 5 } ]); expect(result.ignoreLines.size).toBe(0); expect(result.ignoreNextLines.size).toBe(0); }); test('should parse ignore-line directive', () => { const lines = [ 'console.log("normal");', 'return; // @nr-analyzer-ignore-line', 'console.log("normal again");' ]; const result = parseIgnoreDirectives(lines); expect(result.ignoreRegions).toEqual([]); expect(result.ignoreLines.has(2)).toBe(true); expect(result.ignoreNextLines.size).toBe(0); }); test('should parse ignore-next directive', () => { const lines = [ 'console.log("normal");', '// @nr-analyzer-ignore-next', 'return;', 'console.log("normal again");' ]; const result = parseIgnoreDirectives(lines); expect(result.ignoreRegions).toEqual([]); expect(result.ignoreLines.size).toBe(0); expect(result.ignoreNextLines.has(3)).toBe(true); }); test('should handle multiple ignore regions', () => { const lines = [ 'console.log("normal");', '// @nr-analyzer-ignore-start', 'return;', '// @nr-analyzer-ignore-end', 'console.log("normal");', '// @nr-analyzer-ignore-start', 'node.warn("debug");', '// @nr-analyzer-ignore-end', 'console.log("normal again");' ]; const result = parseIgnoreDirectives(lines); expect(result.ignoreRegions).toEqual([ { start: 2, end: 4 }, { start: 6, end: 8 } ]); }); test('should handle mixed directive types', () => { const lines = [ 'console.log("normal");', '// @nr-analyzer-ignore-start', 'return;', '// @nr-analyzer-ignore-end', 'node.warn("debug"); // @nr-analyzer-ignore-line', '// @nr-analyzer-ignore-next', 'const test = "test";', 'console.log("normal again");' ]; const result = parseIgnoreDirectives(lines); expect(result.ignoreRegions).toEqual([ { start: 2, end: 4 } ]); expect(result.ignoreLines.has(5)).toBe(true); expect(result.ignoreNextLines.has(7)).toBe(true); }); test('should handle case insensitive directives', () => { const lines = [ 'console.log("normal");', '// @NR-ANALYZER-IGNORE-START', 'return;', '// @nr-analyzer-ignore-END', 'console.log("normal again");' ]; const result = parseIgnoreDirectives(lines); expect(result.ignoreRegions).toEqual([ { start: 2, end: 4 } ]); }); test('should handle unmatched ignore-start (no corresponding end)', () => { const lines = [ 'console.log("normal");', '// @nr-analyzer-ignore-start', 'return;', 'node.warn("debug");', 'console.log("normal again");' ]; const result = parseIgnoreDirectives(lines); expect(result.ignoreRegions).toEqual([]); }); }); describe('shouldIgnoreLine', () => { test('should return true for lines in ignore regions', () => { const ignoreRegions = [{ start: 2, end: 4 }]; const ignoreLines = new Set(); const ignoreNextLines = new Set(); expect(shouldIgnoreLine(2, ignoreRegions, ignoreLines, ignoreNextLines)).toBe(true); expect(shouldIgnoreLine(3, ignoreRegions, ignoreLines, ignoreNextLines)).toBe(true); expect(shouldIgnoreLine(4, ignoreRegions, ignoreLines, ignoreNextLines)).toBe(true); expect(shouldIgnoreLine(1, ignoreRegions, ignoreLines, ignoreNextLines)).toBe(false); expect(shouldIgnoreLine(5, ignoreRegions, ignoreLines, ignoreNextLines)).toBe(false); }); test('should return true for explicitly ignored lines', () => { const ignoreRegions = []; const ignoreLines = new Set([3, 7]); const ignoreNextLines = new Set(); expect(shouldIgnoreLine(3, ignoreRegions, ignoreLines, ignoreNextLines)).toBe(true); expect(shouldIgnoreLine(7, ignoreRegions, ignoreLines, ignoreNextLines)).toBe(true); expect(shouldIgnoreLine(1, ignoreRegions, ignoreLines, ignoreNextLines)).toBe(false); expect(shouldIgnoreLine(5, ignoreRegions, ignoreLines, ignoreNextLines)).toBe(false); }); test('should return true for ignore-next lines', () => { const ignoreRegions = []; const ignoreLines = new Set(); const ignoreNextLines = new Set([3, 7]); expect(shouldIgnoreLine(3, ignoreRegions, ignoreLines, ignoreNextLines)).toBe(true); expect(shouldIgnoreLine(7, ignoreRegions, ignoreLines, ignoreNextLines)).toBe(true); expect(shouldIgnoreLine(1, ignoreRegions, ignoreLines, ignoreNextLines)).toBe(false); expect(shouldIgnoreLine(5, ignoreRegions, ignoreLines, ignoreNextLines)).toBe(false); }); }); describe('detectDebuggingTraits with ignore directives', () => { test('should ignore issues in ignore regions', () => { const code = ` console.log("normal"); // @nr-analyzer-ignore-start return; node.warn("debug"); // @nr-analyzer-ignore-end console.log("normal again"); `.trim(); const issues = detectDebuggingTraits(code, 2); // Should detect the 2 console.log statements outside ignore region expect(issues).toHaveLength(2); expect(issues[0].type).toBe('console-log'); expect(issues[0].line).toBe(1); expect(issues[1].type).toBe('console-log'); expect(issues[1].line).toBe(6); }); test('should ignore issues with ignore-line directive', () => { const code = ` console.log("normal"); return; // @nr-analyzer-ignore-line node.warn("debug"); `.trim(); const issues = detectDebuggingTraits(code, 2); // Should detect console.log and node.warn, but not the return (ignored) expect(issues).toHaveLength(2); expect(issues[0].type).toBe('console-log'); expect(issues[0].line).toBe(1); expect(issues[1].type).toBe('node-warn'); expect(issues[1].line).toBe(3); }); test('should ignore issues with ignore-next directive', () => { const code = ` console.log("normal"); // @nr-analyzer-ignore-next return; node.warn("debug"); `.trim(); const issues = detectDebuggingTraits(code, 2); // Should detect console.log and node.warn, but not return (ignored by ignore-next) expect(issues).toHaveLength(2); expect(issues[0].type).toBe('console-log'); expect(issues[0].line).toBe(1); expect(issues[1].type).toBe('node-warn'); expect(issues[1].line).toBe(4); }); test('should handle multiple ignore types together', () => { const code = ` console.log("normal"); // @nr-analyzer-ignore-start return; const debug = "debug"; // @nr-analyzer-ignore-end node.warn("debug1"); // @nr-analyzer-ignore-line // @nr-analyzer-ignore-next node.warn("debug2"); node.warn("debug3"); `.trim(); const issues = detectDebuggingTraits(code, 3); // Should detect console.log and the last node.warn only expect(issues).toHaveLength(2); expect(issues[0].type).toBe('console-log'); expect(issues[0].line).toBe(1); expect(issues[1].type).toBe('node-warn'); expect(issues[1].line).toBe(9); }); test('should ignore hardcoded values in ignore regions', () => { const code = ` console.log("normal"); // @nr-analyzer-ignore-start const test = "test"; const debug = "debug"; const temp = "temp"; const num = 123; // @nr-analyzer-ignore-end const realTest = "test"; node.log(realTest); `.trim(); const issues = detectDebuggingTraits(code, 3); // Should detect only console.log and hardcoded test outside ignore region const relevantIssues = issues.filter(issue => issue.type === 'console-log' || issue.type.startsWith('hardcoded-') ); expect(relevantIssues).toHaveLength(2); expect(relevantIssues.some(issue => issue.type === 'console-log' && issue.line === 1)).toBe(true); expect(relevantIssues.some(issue => issue.type === 'hardcoded-test' && issue.line === 8)).toBe(true); }); test('should ignore TODO comments in ignore regions', () => { const code = ` console.log("normal"); // @nr-analyzer-ignore-start // TODO: This is ignored // FIXME: This is also ignored // @nr-analyzer-ignore-end // TODO: This should be detected `.trim(); const issues = detectDebuggingTraits(code, 2); // Should detect console.log and the TODO outside ignore region expect(issues).toHaveLength(2); expect(issues[0].type).toBe('console-log'); expect(issues[0].line).toBe(1); expect(issues[1].type).toBe('todo-comment'); expect(issues[1].line).toBe(6); }); test('should ignore multiple empty lines in ignore regions', () => { const code = ` console.log("normal"); // @nr-analyzer-ignore-start // Multiple empty lines above should be ignored // @nr-analyzer-ignore-end console.log("normal again"); `.trim(); const issues = detectDebuggingTraits(code, 3); // Should detect both console.log statements and the empty lines outside ignore region expect(issues).toHaveLength(3); expect(issues[0].type).toBe('console-log'); expect(issues[0].line).toBe(1); expect(issues[1].type).toBe('console-log'); expect(issues[1].line).toBe(9); expect(issues[2].type).toBe('multiple-empty-lines'); expect(issues[2].line).toBe(7); }); test('should handle nested ignore directives gracefully', () => { const code = ` console.log("normal"); // @nr-analyzer-ignore-start return; // @nr-analyzer-ignore-start (nested, should be ignored) node.warn("debug"); // @nr-analyzer-ignore-end // @nr-analyzer-ignore-end console.log("normal again"); `.trim(); const issues = detectDebuggingTraits(code, 2); // Should detect both console.log statements outside ignore region expect(issues).toHaveLength(2); expect(issues[0].type).toBe('console-log'); expect(issues[0].line).toBe(1); expect(issues[1].type).toBe('console-log'); expect(issues[1].line).toBe(8); }); }); });