fix: resolve TypeScript linting errors in test files

- Add null checks with non-null assertions in docs-mapper.test.ts
- Add undefined checks with non-null assertions in node-parser-outputs.test.ts
- Use type assertions (as any) for workflow objects in validator tests
- Fix fuzzy search test query to be less typo-heavy

All TypeScript strict checks now pass successfully.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
czlonkowski
2025-08-07 17:57:08 +02:00
parent a77379b40b
commit 00f3f1fbfd
5 changed files with 95 additions and 83 deletions

View File

@@ -318,17 +318,18 @@ Use this node when you need to process large datasets in smaller chunks.
const result = await docsMapper.fetchDocumentation('splitInBatches');
expect(result).toContain('CRITICAL OUTPUT CONNECTION INFORMATION');
expect(result).toContain('⚠️ OUTPUT INDICES ARE COUNTERINTUITIVE ⚠️');
expect(result).toContain('Output 0 (index 0) = "done"');
expect(result).toContain('Output 1 (index 1) = "loop"');
expect(result).toContain('Correct Connection Pattern:');
expect(result).toContain('Common Mistake:');
expect(result).toContain('AI assistants often connect these backwards');
expect(result).not.toBeNull();
expect(result!).toContain('CRITICAL OUTPUT CONNECTION INFORMATION');
expect(result!).toContain('⚠️ OUTPUT INDICES ARE COUNTERINTUITIVE ⚠️');
expect(result!).toContain('Output 0 (index 0) = "done"');
expect(result!).toContain('Output 1 (index 1) = "loop"');
expect(result!).toContain('Correct Connection Pattern:');
expect(result!).toContain('Common Mistake:');
expect(result!).toContain('AI assistants often connect these backwards');
// Should insert before "When to use" section
const insertionIndex = result.indexOf('## When to use');
const guidanceIndex = result.indexOf('CRITICAL OUTPUT CONNECTION INFORMATION');
const insertionIndex = result!.indexOf('## When to use');
const guidanceIndex = result!.indexOf('CRITICAL OUTPUT CONNECTION INFORMATION');
expect(guidanceIndex).toBeLessThan(insertionIndex);
expect(guidanceIndex).toBeGreaterThan(0);
});
@@ -347,10 +348,11 @@ This node splits data into batches.
const result = await docsMapper.fetchDocumentation('splitInBatches');
expect(result).toContain('CRITICAL OUTPUT CONNECTION INFORMATION');
expect(result).not.toBeNull();
expect(result!).toContain('CRITICAL OUTPUT CONNECTION INFORMATION');
// Should be inserted at the beginning since no "When to use" section
expect(result.indexOf('CRITICAL OUTPUT CONNECTION INFORMATION')).toBeLessThan(
result.indexOf('# Split In Batches Node')
expect(result!.indexOf('CRITICAL OUTPUT CONNECTION INFORMATION')).toBeLessThan(
result!.indexOf('# Split In Batches Node')
);
});
@@ -420,15 +422,16 @@ Configure your conditions here.
const result = await docsMapper.fetchDocumentation('n8n-nodes-base.if');
expect(result).toContain('Output Connection Information');
expect(result).toContain('Output 0 (index 0) = "true"');
expect(result).toContain('Output 1 (index 1) = "false"');
expect(result).toContain('Items that match the condition');
expect(result).toContain('Items that do not match the condition');
expect(result).not.toBeNull();
expect(result!).toContain('Output Connection Information');
expect(result!).toContain('Output 0 (index 0) = "true"');
expect(result!).toContain('Output 1 (index 1) = "false"');
expect(result!).toContain('Items that match the condition');
expect(result!).toContain('Items that do not match the condition');
// Should insert before "Node parameters" section
const parametersIndex = result.indexOf('## Node parameters');
const outputInfoIndex = result.indexOf('Output Connection Information');
const parametersIndex = result!.indexOf('## Node parameters');
const outputInfoIndex = result!.indexOf('Output Connection Information');
expect(outputInfoIndex).toBeLessThan(parametersIndex);
expect(outputInfoIndex).toBeGreaterThan(0);
});
@@ -483,10 +486,11 @@ Use this node to route data.
const result = await docsMapper.fetchDocumentation('splitInBatches');
expect(result).toContain('CRITICAL OUTPUT CONNECTION INFORMATION');
expect(result).not.toBeNull();
expect(result!).toContain('CRITICAL OUTPUT CONNECTION INFORMATION');
// Should be prepended when no insertion point found (but there's a newline before original content)
const guidanceIndex = result.indexOf('CRITICAL OUTPUT CONNECTION INFORMATION');
expect(guidanceIndex).toBeLessThan(result.indexOf('Simple content'));
const guidanceIndex = result!.indexOf('CRITICAL OUTPUT CONNECTION INFORMATION');
expect(guidanceIndex).toBeLessThan(result!.indexOf('Simple content'));
expect(guidanceIndex).toBeLessThanOrEqual(5); // Allow for some whitespace
});
@@ -496,8 +500,9 @@ Use this node to route data.
const result = await docsMapper.fetchDocumentation('splitInBatches');
expect(result).toContain('CRITICAL OUTPUT CONNECTION INFORMATION');
expect(result.length).toBeGreaterThan(0);
expect(result).not.toBeNull();
expect(result!).toContain('CRITICAL OUTPUT CONNECTION INFORMATION');
expect(result!.length).toBeGreaterThan(0);
});
it('should handle content with multiple "When to use" sections', async () => {
@@ -515,10 +520,11 @@ Detailed usage.
const result = await docsMapper.fetchDocumentation('splitInBatches');
expect(result).toContain('CRITICAL OUTPUT CONNECTION INFORMATION');
expect(result).not.toBeNull();
expect(result!).toContain('CRITICAL OUTPUT CONNECTION INFORMATION');
// Should insert before first occurrence
const firstWhenToUse = result.indexOf('## When to use (overview)');
const guidanceIndex = result.indexOf('CRITICAL OUTPUT CONNECTION INFORMATION');
const firstWhenToUse = result!.indexOf('## When to use (overview)');
const guidanceIndex = result!.indexOf('CRITICAL OUTPUT CONNECTION INFORMATION');
expect(guidanceIndex).toBeLessThan(firstWhenToUse);
});
@@ -538,7 +544,8 @@ Content here.
const result = await docsMapper.fetchDocumentation('splitInBatches');
// Should still add enhancement (method doesn't check for existing enhancements)
const criticalSections = (result.match(/CRITICAL OUTPUT CONNECTION INFORMATION/g) || []).length;
expect(result).not.toBeNull();
const criticalSections = (result!.match(/CRITICAL OUTPUT CONNECTION INFORMATION/g) || []).length;
expect(criticalSections).toBe(2); // Original + new enhancement
});
@@ -548,8 +555,9 @@ Content here.
const result = await docsMapper.fetchDocumentation('splitInBatches');
expect(result).toContain('CRITICAL OUTPUT CONNECTION INFORMATION');
expect(result.length).toBeGreaterThan(largeContent.length);
expect(result).not.toBeNull();
expect(result!).toContain('CRITICAL OUTPUT CONNECTION INFORMATION');
expect(result!.length).toBeGreaterThan(largeContent.length);
});
});

View File

@@ -306,10 +306,12 @@ describe('NodeParser - Output Extraction', () => {
expect(result.outputNames).toEqual(['done', 'loop']);
// Verify the counterintuitive order: done=0, loop=1
expect(result.outputs[0].displayName).toBe('Done');
expect(result.outputs[1].displayName).toBe('Loop');
expect(result.outputNames[0]).toBe('done');
expect(result.outputNames[1]).toBe('loop');
expect(result.outputs).toBeDefined();
expect(result.outputNames).toBeDefined();
expect(result.outputs![0].displayName).toBe('Done');
expect(result.outputs![1].displayName).toBe('Loop');
expect(result.outputNames![0]).toBe('done');
expect(result.outputNames![1]).toBe('loop');
});
it('should handle Switch node with multiple outputs', () => {
@@ -406,8 +408,9 @@ describe('NodeParser - Output Extraction', () => {
const result = parser.parse(NodeClass, 'n8n-nodes-base');
expect(result.outputs).toHaveLength(2);
expect(result.outputs[0].displayName).toBe('Done');
expect(result.outputs[1].displayName).toBe('Loop');
expect(result.outputs).toBeDefined();
expect(result.outputs![0].displayName).toBe('Done');
expect(result.outputs![1].displayName).toBe('Loop');
expect(result.outputNames).toEqual(['done', 'loop']);
});
@@ -442,8 +445,9 @@ describe('NodeParser - Output Extraction', () => {
const result = parser.parse(NodeClass, 'n8n-nodes-base');
expect(result.outputs).toHaveLength(2);
expect(result.outputs[0].displayName).toBe('True');
expect(result.outputs[1].displayName).toBe('False');
expect(result.outputs).toBeDefined();
expect(result.outputs![0].displayName).toBe('True');
expect(result.outputs![1].displayName).toBe('False');
expect(result.outputNames).toEqual(['true', 'false']);
});

View File

@@ -82,7 +82,7 @@ describe('Loop Output Fix - Edge Cases', () => {
}
};
const result = await validator.validateWorkflow(workflow);
const result = await validator.validateWorkflow(workflow as any);
// Should not crash or produce output-related errors
expect(result).toBeDefined();
@@ -113,7 +113,7 @@ describe('Loop Output Fix - Edge Cases', () => {
connections: {}
};
const result = await validator.validateWorkflow(workflow);
const result = await validator.validateWorkflow(workflow as any);
expect(result).toBeDefined();
expect(result.valid).toBeTruthy(); // Empty workflow with webhook should be valid
@@ -147,7 +147,7 @@ describe('Loop Output Fix - Edge Cases', () => {
}
};
const result = await validator.validateWorkflow(workflow);
const result = await validator.validateWorkflow(workflow as any);
// Should warn about self-reference but not crash
const selfRefWarnings = result.warnings.filter(w =>
@@ -188,7 +188,7 @@ describe('Loop Output Fix - Edge Cases', () => {
}
};
const result = await validator.validateWorkflow(workflow);
const result = await validator.validateWorkflow(workflow as any);
const negativeIndexErrors = result.errors.filter(e =>
e.message?.includes('Invalid connection index -1')
@@ -234,7 +234,7 @@ describe('Loop Output Fix - Edge Cases', () => {
}
};
const result = await validator.validateWorkflow(workflow);
const result = await validator.validateWorkflow(workflow as any);
// Should validate without crashing (n8n allows large indices)
expect(result).toBeDefined();
@@ -266,7 +266,7 @@ describe('Loop Output Fix - Edge Cases', () => {
}
};
const result = await validator.validateWorkflow(workflow);
const result = await validator.validateWorkflow(workflow as any);
// Should handle gracefully without crashing
expect(result).toBeDefined();
@@ -306,7 +306,7 @@ describe('Loop Output Fix - Edge Cases', () => {
}
};
const result = await validator.validateWorkflow(workflow);
const result = await validator.validateWorkflow(workflow as any);
// Should handle malformed connections but report errors
expect(result).toBeDefined();
@@ -366,7 +366,7 @@ describe('Loop Output Fix - Edge Cases', () => {
connections
};
const result = await validator.validateWorkflow(workflow);
const result = await validator.validateWorkflow(workflow as any);
// Should warn about missing loop back because depth limit prevents detection
const loopBackWarnings = result.warnings.filter(w =>
@@ -423,7 +423,7 @@ describe('Loop Output Fix - Edge Cases', () => {
}
};
const result = await validator.validateWorkflow(workflow);
const result = await validator.validateWorkflow(workflow as any);
// Should complete without hanging and warn about missing loop back
expect(result).toBeDefined();
@@ -469,7 +469,7 @@ describe('Loop Output Fix - Edge Cases', () => {
}
};
const result = await validator.validateWorkflow(workflow);
const result = await validator.validateWorkflow(workflow as any);
// Should warn about missing loop back and self-reference
const loopBackWarnings = result.warnings.filter(w =>
@@ -526,7 +526,7 @@ describe('Loop Output Fix - Edge Cases', () => {
}
};
const result = await validator.validateWorkflow(workflow);
const result = await validator.validateWorkflow(workflow as any);
// Should handle without performance issues
expect(result).toBeDefined();
@@ -589,7 +589,7 @@ describe('Loop Output Fix - Edge Cases', () => {
}
};
const result = await validator.validateWorkflow(workflow);
const result = await validator.validateWorkflow(workflow as any);
// Should validate all connection types
expect(result).toBeDefined();
@@ -615,7 +615,7 @@ describe('Loop Output Fix - Edge Cases', () => {
connections: {}
};
const result = await validator.validateWorkflow(workflow);
const result = await validator.validateWorkflow(workflow as any);
// Should not produce SplitInBatches-specific warnings for isolated node
const splitWarnings = result.warnings.filter(w =>
@@ -657,7 +657,7 @@ describe('Loop Output Fix - Edge Cases', () => {
}
};
const result = await validator.validateWorkflow(workflow);
const result = await validator.validateWorkflow(workflow as any);
// Should NOT warn about empty loop output (it's only a problem if loop connects to something but doesn't loop back)
// An empty loop output is valid - it just means no looping occurs
@@ -703,7 +703,7 @@ describe('Loop Output Fix - Edge Cases', () => {
}
};
const result = await validator.validateWorkflow(workflow);
const result = await validator.validateWorkflow(workflow as any);
// Both outputs go to same node which loops back - should be valid
// No warnings about loop back since it does connect back
@@ -749,7 +749,7 @@ describe('Loop Output Fix - Edge Cases', () => {
}
};
const result = await validator.validateWorkflow(workflow);
const result = await validator.validateWorkflow(workflow as any);
// Should error about reversed outputs since function node on done output connects back
const reversedErrors = result.errors.filter(e =>
@@ -776,7 +776,7 @@ describe('Loop Output Fix - Edge Cases', () => {
connections: {}
};
const result = await validator.validateWorkflow(workflow);
const result = await validator.validateWorkflow(workflow as any);
// Should report unknown node type error
const unknownNodeErrors = result.errors.filter(e =>
@@ -817,7 +817,7 @@ describe('Loop Output Fix - Edge Cases', () => {
};
const startTime = Date.now();
const result = await validator.validateWorkflow(workflow);
const result = await validator.validateWorkflow(workflow as any);
const duration = Date.now() - startTime;
// Should complete within reasonable time (< 5 seconds)
@@ -855,7 +855,7 @@ describe('Loop Output Fix - Edge Cases', () => {
connections
};
const result = await validator.validateWorkflow(workflow);
const result = await validator.validateWorkflow(workflow as any);
// Should validate all nodes without performance issues
expect(result).toBeDefined();

View File

@@ -64,7 +64,7 @@ describe('WorkflowValidator - SplitInBatches Validation (Simplified)', () => {
}
};
const result = await validator.validateWorkflow(workflow);
const result = await validator.validateWorkflow(workflow as any);
// Should complete validation without crashing
expect(result).toBeDefined();
@@ -114,7 +114,7 @@ describe('WorkflowValidator - SplitInBatches Validation (Simplified)', () => {
}
};
const result = await validator.validateWorkflow(workflow);
const result = await validator.validateWorkflow(workflow as any);
// Should identify potential processing nodes
expect(result).toBeDefined();
@@ -163,7 +163,7 @@ describe('WorkflowValidator - SplitInBatches Validation (Simplified)', () => {
}
};
const result = await validator.validateWorkflow(workflow);
const result = await validator.validateWorkflow(workflow as any);
// Should not warn about final nodes on done output
expect(result).toBeDefined();
@@ -205,7 +205,7 @@ describe('WorkflowValidator - SplitInBatches Validation (Simplified)', () => {
}
};
const result = await validator.validateWorkflow(workflow);
const result = await validator.validateWorkflow(workflow as any);
const negativeIndexErrors = result.errors.filter(e =>
e.message?.includes('Invalid connection index -1')
@@ -239,7 +239,7 @@ describe('WorkflowValidator - SplitInBatches Validation (Simplified)', () => {
}
};
const result = await validator.validateWorkflow(workflow);
const result = await validator.validateWorkflow(workflow as any);
const missingNodeErrors = result.errors.filter(e =>
e.message?.includes('non-existent node')
@@ -276,7 +276,7 @@ describe('WorkflowValidator - SplitInBatches Validation (Simplified)', () => {
}
};
const result = await validator.validateWorkflow(workflow);
const result = await validator.validateWorkflow(workflow as any);
// Should not warn about self-reference for SplitInBatches
const selfRefWarnings = result.warnings.filter(w =>
@@ -311,7 +311,7 @@ describe('WorkflowValidator - SplitInBatches Validation (Simplified)', () => {
}
};
const result = await validator.validateWorkflow(workflow);
const result = await validator.validateWorkflow(workflow as any);
// Should warn about self-reference for non-loop nodes
const selfRefWarnings = result.warnings.filter(w =>
@@ -368,7 +368,7 @@ describe('WorkflowValidator - SplitInBatches Validation (Simplified)', () => {
}
};
const result = await validator.validateWorkflow(workflow);
const result = await validator.validateWorkflow(workflow as any);
// Should validate without major errors
expect(result).toBeDefined();
@@ -399,7 +399,7 @@ describe('WorkflowValidator - SplitInBatches Validation (Simplified)', () => {
connections: {}
};
const result = await validator.validateWorkflow(workflow);
const result = await validator.validateWorkflow(workflow as any);
// Should handle gracefully without crashing
expect(result).toBeDefined();
@@ -422,7 +422,7 @@ describe('WorkflowValidator - SplitInBatches Validation (Simplified)', () => {
connections: {}
};
const result = await validator.validateWorkflow(workflow);
const result = await validator.validateWorkflow(workflow as any);
// Should report unknown node error
const unknownErrors = result.errors.filter(e =>

View File

@@ -98,7 +98,7 @@ describe('WorkflowValidator - Loop Node Validation', () => {
}
};
const result = await validator.validateWorkflow(workflow);
const result = await validator.validateWorkflow(workflow as any);
// The validator should detect the processing node name/type pattern and loop back
const reversedErrors = result.errors.filter(e =>
@@ -125,7 +125,7 @@ describe('WorkflowValidator - Loop Node Validation', () => {
// No loop back from Process Item
});
const result = await validator.validateWorkflow(workflow);
const result = await validator.validateWorkflow(workflow as any);
expect(result.warnings).toContainEqual(
expect.objectContaining({
@@ -153,7 +153,7 @@ describe('WorkflowValidator - Loop Node Validation', () => {
}
});
const result = await validator.validateWorkflow(workflow);
const result = await validator.validateWorkflow(workflow as any);
expect(result.warnings).toContainEqual(
expect.objectContaining({
@@ -182,7 +182,7 @@ describe('WorkflowValidator - Loop Node Validation', () => {
// Process Item doesn't connect back to Split In Batches
});
const result = await validator.validateWorkflow(workflow);
const result = await validator.validateWorkflow(workflow as any);
expect(result.warnings).toContainEqual(
expect.objectContaining({
@@ -241,7 +241,7 @@ describe('WorkflowValidator - Loop Node Validation', () => {
}
};
const result = await validator.validateWorkflow(workflow);
const result = await validator.validateWorkflow(workflow as any);
// Should not have SplitInBatches-specific errors or warnings
const splitErrors = result.errors.filter(e =>
@@ -317,7 +317,7 @@ describe('WorkflowValidator - Loop Node Validation', () => {
}
};
const result = await validator.validateWorkflow(complexWorkflow);
const result = await validator.validateWorkflow(complexWorkflow as any);
// Should accept this correct structure without warnings
const loopWarnings = result.warnings.filter(w =>
@@ -369,7 +369,7 @@ describe('WorkflowValidator - Loop Node Validation', () => {
}
};
const result = await validator.validateWorkflow(workflow);
const result = await validator.validateWorkflow(workflow as any);
const hasProcessingWarning = result.warnings.some(w =>
w.message?.includes('appears to be a processing node')
@@ -409,7 +409,7 @@ describe('WorkflowValidator - Loop Node Validation', () => {
}
};
const result = await validator.validateWorkflow(workflow);
const result = await validator.validateWorkflow(workflow as any);
// Should not warn about missing loop back since it exists
const missingLoopBackWarnings = result.warnings.filter(w =>
@@ -454,7 +454,7 @@ describe('WorkflowValidator - Loop Node Validation', () => {
}
};
const result = await validator.validateWorkflow(workflow);
const result = await validator.validateWorkflow(workflow as any);
// Should not warn about missing loop back since indirect loop exists
const missingLoopBackWarnings = result.warnings.filter(w =>
@@ -507,7 +507,7 @@ describe('WorkflowValidator - Loop Node Validation', () => {
connections
};
const result = await validator.validateWorkflow(workflow);
const result = await validator.validateWorkflow(workflow as any);
// Should warn about missing loop back because depth limit prevents detection
const missingLoopBackWarnings = result.warnings.filter(w =>
@@ -546,7 +546,7 @@ describe('WorkflowValidator - Loop Node Validation', () => {
}
};
const result = await validator.validateWorkflow(workflow);
const result = await validator.validateWorkflow(workflow as any);
// Should complete without hanging and warn about missing loop back
const missingLoopBackWarnings = result.warnings.filter(w =>
@@ -578,7 +578,7 @@ describe('WorkflowValidator - Loop Node Validation', () => {
}
};
const result = await validator.validateWorkflow(workflow);
const result = await validator.validateWorkflow(workflow as any);
// Should not warn about self-reference for SplitInBatches
const selfReferenceWarnings = result.warnings.filter(w =>
@@ -607,7 +607,7 @@ describe('WorkflowValidator - Loop Node Validation', () => {
}
};
const result = await validator.validateWorkflow(workflow);
const result = await validator.validateWorkflow(workflow as any);
// Should warn about self-reference for non-loop nodes
const selfReferenceWarnings = result.warnings.filter(w =>
@@ -639,7 +639,7 @@ describe('WorkflowValidator - Loop Node Validation', () => {
}
};
const result = await validator.validateWorkflow(workflow);
const result = await validator.validateWorkflow(workflow as any);
// Should have connection error for non-existent node
const connectionErrors = result.errors.filter(e =>
@@ -669,7 +669,7 @@ describe('WorkflowValidator - Loop Node Validation', () => {
}
};
const result = await validator.validateWorkflow(workflow);
const result = await validator.validateWorkflow(workflow as any);
// Should not crash and should not have SplitInBatches-specific errors
expect(result).toBeDefined();
@@ -696,7 +696,7 @@ describe('WorkflowValidator - Loop Node Validation', () => {
}
};
const result = await validator.validateWorkflow(workflow);
const result = await validator.validateWorkflow(workflow as any);
// Should handle gracefully without crashing
expect(result).toBeDefined();