diff --git a/src/application/Parser/Script/Compiler/Function/SharedFunctionsParser.ts b/src/application/Parser/Script/Compiler/Function/SharedFunctionsParser.ts index 60f8d425..9cdb4173 100644 --- a/src/application/Parser/Script/Compiler/Function/SharedFunctionsParser.ts +++ b/src/application/Parser/Script/Compiler/Function/SharedFunctionsParser.ts @@ -98,6 +98,7 @@ function hasCall(data: FunctionData): data is CallFunctionData { } function ensureValidFunctions(functions: readonly FunctionData[]) { + ensureNoUnnamedFunctions(functions); ensureNoDuplicatesInFunctionNames(functions); ensureEitherCallOrCodeIsDefined(functions); ensureNoDuplicateCode(functions); @@ -108,6 +109,16 @@ function printList(list: readonly string[]): string { return `"${list.join('","')}"`; } +function ensureNoUnnamedFunctions(functions: readonly FunctionData[]) { + const functionsWithoutNames = functions.filter( + (func) => !func.name || func.name.trim().length === 0, + ); + if (functionsWithoutNames.length) { + const invalidFunctions = functionsWithoutNames.map((f) => JSON.stringify(f)); + throw new Error(`Some function(s) have no names:\n${invalidFunctions.join('\n')}`); + } +} + function ensureEitherCallOrCodeIsDefined(holders: readonly FunctionData[]) { // Ensure functions do not define both call and code const withBothCallAndCode = holders.filter((holder) => hasCode(holder) && hasCall(holder)); diff --git a/tests/unit/application/Parser/Script/Compiler/Function/SharedFunctionsParser.spec.ts b/tests/unit/application/Parser/Script/Compiler/Function/SharedFunctionsParser.spec.ts index 47616539..29426618 100644 --- a/tests/unit/application/Parser/Script/Compiler/Function/SharedFunctionsParser.spec.ts +++ b/tests/unit/application/Parser/Script/Compiler/Function/SharedFunctionsParser.spec.ts @@ -26,6 +26,27 @@ describe('SharedFunctionsParser', () => { }); describe('parseFunctions', () => { describe('validates functions', () => { + it('throws when functions have no names', () => { + // arrange + const invalidFunctions = [ + createFunctionDataWithCode() + .withCode('test function 1') + .withName(' '), // Whitespace, + createFunctionDataWithCode() + .withCode('test function 2') + .withName(undefined as unknown as string), // Undefined + createFunctionDataWithCode() + .withCode('test function 3') + .withName(''), // Empty + ]; + const expectedError = `Some function(s) have no names:\n${invalidFunctions.map((f) => JSON.stringify(f)).join('\n')}`; + // act + const act = () => new ParseFunctionsCallerWithDefaults() + .withFunctions(invalidFunctions) + .parseFunctions(); + // assert + expect(act).to.throw(expectedError); + }); it('throws when functions have same names', () => { // arrange const name = 'same-func-name';