diff --git a/app/javascript/interpreter/executor.ts b/app/javascript/interpreter/executor.ts index 5837a90a3e..969e7179f3 100644 --- a/app/javascript/interpreter/executor.ts +++ b/app/javascript/interpreter/executor.ts @@ -479,10 +479,7 @@ export class Executor callee = this.evaluate(expression.callee) } catch (e) { if (isRuntimeError(e) && e.type == 'CouldNotFindValueWithName') { - if ( - expression.callee instanceof VariableExpression && - e.context?.didYouMean?.function?.length > 0 - ) { + if (e.context?.didYouMean?.function?.length > 0) { const alternative = e.context.didYouMean.function this.error('CouldNotFindFunctionWithNameSuggestion', e.location, { ...e.context, @@ -491,7 +488,12 @@ export class Executor }) } - this.error('CouldNotFindFunctionWithName', e.location, e.context) + this.error('CouldNotFindFunctionWithName', e.location, { + ...e.context, + ...{ + name: expression.callee.name.lexeme, + }, + }) } throw e diff --git a/app/javascript/interpreter/expression.ts b/app/javascript/interpreter/expression.ts index 514a2bb1bc..e046d985a4 100644 --- a/app/javascript/interpreter/expression.ts +++ b/app/javascript/interpreter/expression.ts @@ -30,7 +30,7 @@ export abstract class Expression { export class CallExpression extends Expression { constructor( - public callee: Expression, + public callee: VariableExpression, public paren: Token, public args: Expression[], public location: Location diff --git a/app/javascript/interpreter/locales/system/translation.json b/app/javascript/interpreter/locales/system/translation.json index 01cb91371e..2f38b5d2b3 100644 --- a/app/javascript/interpreter/locales/system/translation.json +++ b/app/javascript/interpreter/locales/system/translation.json @@ -68,7 +68,7 @@ }, "runtime": { "CouldNotEvaluateFunction": "CouldNotEvaluateFunction", - "CouldNotFindFunctionWithName": "CouldNotFindFunctionWithName", + "CouldNotFindFunctionWithName": "CouldNotFindFunctionWithName: name: {{name}}", "CouldNotFindFunctionWithNameSuggestion": "CouldNotFindFunctionWithNameSuggestion: name: {{name}}, suggestion: {{suggestion}}", "CouldNotFindValueWithName": "CouldNotFindValueWithName: name: {{name}}", "InfiniteLoop": "InfiniteLoop", @@ -76,17 +76,18 @@ "InvalidExpression": "InvalidExpression", "InvalidIndexGetterTarget": "InvalidIndexGetterTarget", "InvalidIndexSetterTarget": "InvalidIndexSetterTarget", - "InvalidNumberOfArguments": "InvalidNumberOfArguments: maxArity: {{maxArity}}, numberOfArgs: {{numberOfArgs}}", "InvalidNumberOfArgumentsWithOptionalArguments": "InvalidNumberOfArgumentsWithOptionalArguments: minArity: {{minArity}}, maxArity: {{maxArity}}, numberOfArgs: {{numberOfArgs}}", "InvalidUnaryOperator": "InvalidUnaryOperator", - "MissingParenthesesForFunctionCall": "MissingParenthesesForFunctionCall", + "MissingParenthesesForFunctionCall": "MissingParenthesesForFunctionCall: name: {{name}}", "NonCallableTarget": "NonCallableTarget", "OperandMustBeBoolean": "OperandMustBeBoolean", "OperandMustBeNumber": "OperandMustBeNumber", "OperandsMustBeNumber": "OperandsMustBeNumber", "OperandsMustBeTwoNumbersOrTwoStrings": "OperandsMustBeTwoNumbersOrTwoStrings", "RepeatCountMustBeGreaterThanZero": "RepeatCountMustBeGreaterThanZero", - "RepeatCountMustBeNumber": "RepeatCountMustBeNumber" + "RepeatCountMustBeNumber": "RepeatCountMustBeNumber", + "TooManyArguments": "TooManyArguments: arity: {{arity}}, numberOfArgs: {{numberOfArgs}}", + "TooFewArguments": "TooFewArguments: arity: {{arity}}, numberOfArgs: {{numberOfArgs}}" }, "disabledLanguageFeature": { "ExcludeListViolation": "ExcludeListViolation: tokenType: {{tokenType}}", diff --git a/test/javascript/interpreter/interpreter.test.ts b/test/javascript/interpreter/interpreter.test.ts index 73b434dfa3..baba1cf83f 100644 --- a/test/javascript/interpreter/interpreter.test.ts +++ b/test/javascript/interpreter/interpreter.test.ts @@ -4,6 +4,15 @@ import { evaluateFunction, } from '@/interpreter/interpreter' import type { ExecutionContext } from '@/interpreter/executor' +import { changeLanguage } from '@/interpreter/translator' + +beforeAll(() => { + changeLanguage('system') +}) + +afterAll(() => { + changeLanguage('en') +}) describe('statements', () => { describe('expression', () => { @@ -1141,6 +1150,9 @@ describe('errors', () => { expect(frames[0].error).not.toBeNull() expect(frames[0].error!.category).toBe('RuntimeError') expect(frames[0].error!.type).toBe('CouldNotFindFunctionWithName') + expect(frames[0].error!.message).toBe( + 'CouldNotFindFunctionWithName: name: foo' + ) expect(error).toBeNull() }) @@ -1162,6 +1174,9 @@ describe('errors', () => { expect(frames[2].error).not.toBeNull() expect(frames[2].error!.category).toBe('RuntimeError') expect(frames[2].error!.type).toBe('CouldNotFindFunctionWithName') + expect(frames[2].error!.message).toBe( + 'CouldNotFindFunctionWithName: name: foo' + ) expect(error).toBeNull() }) }) @@ -1214,7 +1229,7 @@ describe('errors', () => { expect(frames[0].error!.category).toBe('RuntimeError') expect(frames[0].error!.type).toBe('TooManyArguments') expect(frames[0].error!.message).toBe( - 'Did you add an extra argument? This function expects to be called with 0 arguments but you called it with 1.' + 'TooManyArguments: arity: 0, numberOfArgs: 1' ) expect(error).toBeNull() }) @@ -1238,7 +1253,7 @@ describe('errors', () => { expect(frames[0].error!.category).toBe('RuntimeError') expect(frames[0].error!.type).toBe('TooFewArguments') expect(frames[0].error!.message).toBe( - 'Did you forget an argument? This function expects to be called with 1 arguments but you called it with 0.' + 'TooFewArguments: arity: 1, numberOfArgs: 0' ) expect(error).toBeNull() }) @@ -1255,6 +1270,9 @@ describe('errors', () => { expect(frames[0].error).not.toBeNull() expect(frames[0].error!.category).toBe('RuntimeError') expect(frames[0].error!.type).toBe('CouldNotFindFunctionWithName') + expect(frames[0].error!.message).toBe( + 'CouldNotFindFunctionWithName: name: foo' + ) expect(error).toBeNull() }) @@ -1272,7 +1290,7 @@ describe('errors', () => { expect(frames[0].code).toBe('foobor()') expect(frames[0].error).not.toBeNull() expect(frames[0].error!.message).toBe( - "Jiki couldn't find a function with the name `foobor`. Maybe you meant to use the `foobar` function instead?" + 'CouldNotFindFunctionWithNameSuggestion: name: foobor, suggestion: foobar' ) expect(frames[0].error!.category).toBe('RuntimeError') expect(frames[0].error!.type).toBe( @@ -1295,11 +1313,11 @@ describe('errors', () => { expect(frames[0].status).toBe('ERROR') expect(frames[0].code).toBe('foo') expect(frames[0].error).not.toBeNull() - expect(frames[0].error!.message).toBe( - 'Did you forget the parenthesis when trying to use this function?\n\nDid you mean:\n\n```foo()```' - ) expect(frames[0].error!.category).toBe('RuntimeError') expect(frames[0].error!.type).toBe('MissingParenthesesForFunctionCall') + expect(frames[0].error!.message).toBe( + 'MissingParenthesesForFunctionCall: name: foo' + ) expect(error).toBeNull() }) @@ -1315,11 +1333,12 @@ describe('errors', () => { expect(frames[0].status).toBe('ERROR') expect(frames[0].code).toBe('set x to y') expect(frames[0].error).not.toBeNull() - expect(frames[0].error!.message).toBe( - 'Did you forget the parenthesis when trying to use this function?\n\nDid you mean:\n\n```y()```' - ) expect(frames[0].error!.category).toBe('RuntimeError') expect(frames[0].error!.type).toBe('MissingParenthesesForFunctionCall') + expect(frames[0].error!.message).toBe( + 'MissingParenthesesForFunctionCall: name: y' + ) + expect(error).toBeNull() }) @@ -1339,6 +1358,9 @@ describe('errors', () => { expect(frames[1].error).not.toBeNull() expect(frames[1].error!.category).toBe('RuntimeError') expect(frames[1].error!.type).toBe('CouldNotFindFunctionWithName') + expect(frames[1].error!.message).toBe( + 'CouldNotFindFunctionWithName: name: foo' + ) expect(error).toBeNull() }) @@ -1354,6 +1376,9 @@ describe('errors', () => { expect(frames[0].error).not.toBeNull() expect(frames[0].error!.category).toBe('RuntimeError') expect(frames[0].error!.type).toBe('CouldNotFindFunctionWithName') + expect(frames[0].error!.message).toBe( + 'CouldNotFindFunctionWithName: name: foo' + ) expect(error).toBeNull() }) }) diff --git a/test/system/flows/student/exercise/views_exercise_mentoring_test.rb b/test/system/flows/student/exercise/views_exercise_mentoring_test.rb index 1a3d6d921e..352eb23b84 100644 --- a/test/system/flows/student/exercise/views_exercise_mentoring_test.rb +++ b/test/system/flows/student/exercise/views_exercise_mentoring_test.rb @@ -110,7 +110,7 @@ class ViewsExerciseMentoringTest < ApplicationSystemTestCase within(".mentoring-in-progress") { assert_text "yamikani" } - Mentor::Discussion::FinishByStudent.(discussion, 5) + ::Mentor::Discussion::FinishByStudent.(discussion, 5) # Reload page visit track_exercise_mentor_discussions_path(track, exercise)