Skip to main content
Glama
parser_godot4.test.ts5.76 kB
import { ParserGodot4 } from '../parser_godot4'; describe('ParserGodot4', () => { let parser: ParserGodot4; beforeEach(() => { parser = new ParserGodot4(); }); describe('parseFirstError', () => { it('should parse script errors with file and line', () => { const logOutput = ` Running tests... ERROR: Invalid call. Nonexistent function 'get_damage' in base 'Node'. At: res://scripts/combat/fighter.gd:45 @ _ready() Some other output `; const error = parser.parseFirstError(logOutput); expect(error).toEqual({ file: 'res://scripts/combat/fighter.gd', line: 45, message: "Invalid call. Nonexistent function 'get_damage' in base 'Node'.", stack: expect.any(Array), type: 'script_error' }); }); it('should parse alternative error format', () => { const logOutput = ` ERROR: res://scripts/player.gd:123 - Attempt to call function 'move' on a null value `; const error = parser.parseFirstError(logOutput); expect(error).toEqual({ file: 'res://scripts/player.gd', line: 123, message: "Attempt to call function 'move' on a null value", stack: expect.any(Array), type: 'script_error' }); }); it('should parse parse errors', () => { const logOutput = ` SCRIPT ERROR: Parse Error at line 67: Expected ')' after expression Path: res://scripts/combat/state_machine.gd `; const error = parser.parseFirstError(logOutput); expect(error).toEqual({ file: '', line: 67, message: "Parse Error: Expected ')' after expression", stack: expect.any(Array), type: 'parse_error' }); }); it('should parse runtime errors', () => { const logOutput = ` SCRIPT ERROR: Invalid get index 'health' (on base: 'null instance') At: res://scripts/combat/fighter.gd:89 @ take_damage() `; const error = parser.parseFirstError(logOutput); expect(error).toEqual({ file: 'res://scripts/combat/fighter.gd', line: 89, message: "Invalid get index 'health' (on base: 'null instance')", stack: expect.any(Array), type: 'runtime_error' }); }); it('should return null for logs without errors', () => { const logOutput = ` Running tests... All tests completed successfully No errors found `; const error = parser.parseFirstError(logOutput); expect(error).toBeNull(); }); it('should extract stack traces', () => { const logOutput = ` ERROR: Invalid call. Nonexistent function 'get_damage' At: res://scripts/combat/fighter.gd:45 @ _ready() at fighter.gd:45 @ _ready() at main.gd:12 @ _on_start_pressed() `; const error = parser.parseFirstError(logOutput); expect(error?.stack).toContain('at fighter.gd:45 @ _ready()'); expect(error?.stack).toContain('at main.gd:12 @ _on_start_pressed()'); }); }); describe('normalizeFilePath', () => { it('should normalize file paths to res:// format', () => { const testPaths = [ ['/absolute/path/to/res/scripts/test.gd', 'res://scripts/test.gd'], ['scripts/test.gd', 'res://scripts/test.gd'], ['res://scripts/test.gd', 'res://scripts/test.gd'], ]; testPaths.forEach(([input, expected]) => { // Access private method for testing const result = (parser as any).normalizeFilePath(input); expect(result).toBe(expected); }); }); }); describe('parseAllErrors', () => { it('should parse multiple errors from log output', () => { const logOutput = ` ERROR: res://scripts/player.gd:10 - First error Some output ERROR: res://scripts/enemy.gd:20 - Second error More output SCRIPT ERROR: Parse Error at line 5: Third error `; const errors = parser.parseAllErrors(logOutput); expect(errors).toHaveLength(3); expect(errors[0].message).toBe('First error'); expect(errors[1].message).toBe('Second error'); expect(errors[2].message).toBe('Parse Error: Third error'); }); }); describe('isTestFailure', () => { it('should detect test failures', () => { const failureOutputs = [ 'Test failed: assertion error', 'ERROR: Something went wrong', 'ASSERTION FAILED: condition not met' ]; failureOutputs.forEach(output => { expect(parser.isTestFailure(output)).toBe(true); }); }); it('should detect successful test runs', () => { const successOutput = 'All tests passed successfully'; expect(parser.isTestFailure(successOutput)).toBe(false); }); }); describe('extractTestResults', () => { it('should extract gdUnit4 test results', () => { const logOutput = ` Running CombatTest Running PlayerTest Running EnemyTest Results: 15 passed, 2 failed `; const results = parser.extractTestResults(logOutput); expect(results.passed).toBe(15); expect(results.failed).toBe(2); expect(results.total).toBe(17); expect(results.suites).toContain('CombatTest'); expect(results.suites).toContain('PlayerTest'); expect(results.suites).toContain('EnemyTest'); }); it('should handle output without results', () => { const logOutput = 'Some random output'; const results = parser.extractTestResults(logOutput); expect(results.passed).toBe(0); expect(results.failed).toBe(0); expect(results.total).toBe(0); expect(results.suites).toHaveLength(0); }); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Snack-JPG/Godot-Sentinel-MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server