From c72cdcded38d40c8a7dc9c8cd56584cc9e602fb2 Mon Sep 17 00:00:00 2001 From: Clare Macrae Date: Sat, 28 Oct 2023 15:42:58 +0100 Subject: [PATCH] refactor: . Move constructArguments() & parseAndEvaluateExpression() to TaskExpression.ts --- src/Query/Filter/FunctionField.ts | 3 +- src/Scripting/Expression.ts | 38 ---------------------- src/Scripting/TaskExpression.ts | 44 ++++++++++++++++++++++---- tests/Scripting/Expression.test.ts | 9 ++---- tests/Scripting/TaskProperties.test.ts | 2 +- 5 files changed, 41 insertions(+), 55 deletions(-) diff --git a/src/Query/Filter/FunctionField.ts b/src/Query/Filter/FunctionField.ts index 73b55d882d..374dc2b6c2 100644 --- a/src/Query/Filter/FunctionField.ts +++ b/src/Query/Filter/FunctionField.ts @@ -1,9 +1,8 @@ -import { parseAndEvaluateExpression } from '../../Scripting/Expression'; import type { Task } from '../../Task'; import type { GrouperFunction } from '../Grouper'; import { Grouper } from '../Grouper'; import { Explanation } from '../Explain/Explanation'; -import { TaskExpression } from '../../Scripting/TaskExpression'; +import { TaskExpression, parseAndEvaluateExpression } from '../../Scripting/TaskExpression'; import { Field } from './Field'; import { Filter, type FilterFunction } from './Filter'; import { FilterOrErrorMessage } from './FilterOrErrorMessage'; diff --git a/src/Scripting/Expression.ts b/src/Scripting/Expression.ts index b9e612dc83..004b263547 100644 --- a/src/Scripting/Expression.ts +++ b/src/Scripting/Expression.ts @@ -1,24 +1,8 @@ -import type { Task } from '../Task'; import { QueryComponentOrError } from '../Query/QueryComponentOrError'; import { errorMessageForException } from '../lib/ExceptionTools'; export class FunctionOrError extends QueryComponentOrError {} -/** - * From: https://www.educative.io/answers/parameter-vs-argument - * A parameter is a variable in a function definition. It is a placeholder and hence does not have a concrete value. - * An argument is a value passed during function invocation. - * @param task - during parsing, this can be null. During evaluation, it must be a Task - */ -export function constructArguments(task: Task | null) { - // TODO Move this to TaskExpression - const paramsArgs: [string, any][] = [ - // TODO Later, pass in the Query too, for access to file properties - ['task', task], - ]; - return paramsArgs; -} - /** * Parse a JavaScript expression, and return either a Function or an error message in a string. * @param paramsArgs @@ -71,25 +55,3 @@ export function evaluateExpressionOrCatch(expression: Function, paramsArgs: [str return errorMessageForException(`Failed calculating expression "${arg}"`, e); } } - -/** - * Evaluate an arbitrary JavaScript expression on a Task object - * @param task - a {@link Task} object - * @param arg - a string, such as `task.path.startsWith("journal/") ? "journal/" : task.path` - * - * Currently any errors are returned as string error messages, starting with the word 'Error'. - * - * @todo Implement a type-safe mechanism to report error messages distinct from expression results. - * - * See also {@link FunctionField} which exposes this facility to users. - */ -export function parseAndEvaluateExpression(task: Task, arg: string) { - const paramsArgs = constructArguments(task); - - const functionOrError = parseExpression(paramsArgs, arg); - if (functionOrError.error) { - return functionOrError.error; - } - - return evaluateExpressionOrCatch(functionOrError.queryComponent!, paramsArgs, arg); -} diff --git a/src/Scripting/TaskExpression.ts b/src/Scripting/TaskExpression.ts index d9525e5668..6cf53d9b13 100644 --- a/src/Scripting/TaskExpression.ts +++ b/src/Scripting/TaskExpression.ts @@ -1,11 +1,41 @@ import type { Task } from '../Task'; -import { - FunctionOrError, - constructArguments, - evaluateExpression, - evaluateExpressionOrCatch, - parseExpression, -} from './Expression'; +import { FunctionOrError, evaluateExpression, evaluateExpressionOrCatch, parseExpression } from './Expression'; + +/** + * From: https://www.educative.io/answers/parameter-vs-argument + * A parameter is a variable in a function definition. It is a placeholder and hence does not have a concrete value. + * An argument is a value passed during function invocation. + * @param task - during parsing, this can be null. During evaluation, it must be a Task + */ +export function constructArguments(task: Task | null) { + const paramsArgs: [string, any][] = [ + // TODO Later, pass in the Query too, for access to file properties + ['task', task], + ]; + return paramsArgs; +} + +/** + * Evaluate an arbitrary JavaScript expression on a Task object + * @param task - a {@link Task} object + * @param arg - a string, such as `task.path.startsWith("journal/") ? "journal/" : task.path` + * + * Currently any errors are returned as string error messages, starting with the word 'Error'. + * + * @todo Implement a type-safe mechanism to report error messages distinct from expression results. + * + * See also {@link FunctionField} which exposes this facility to users. + */ +export function parseAndEvaluateExpression(task: Task, arg: string) { + const paramsArgs = constructArguments(task); + + const functionOrError = parseExpression(paramsArgs, arg); + if (functionOrError.error) { + return functionOrError.error; + } + + return evaluateExpressionOrCatch(functionOrError.queryComponent!, paramsArgs, arg); +} /** * Encapsulate an expression that can be calculated from a {@link Task} object diff --git a/tests/Scripting/Expression.test.ts b/tests/Scripting/Expression.test.ts index 492d1c4a75..857a794315 100644 --- a/tests/Scripting/Expression.test.ts +++ b/tests/Scripting/Expression.test.ts @@ -3,16 +3,11 @@ */ import moment from 'moment'; -import { - constructArguments, - evaluateExpression, - evaluateExpressionOrCatch, - parseAndEvaluateExpression, - parseExpression, -} from '../../src/Scripting/Expression'; +import { evaluateExpression, evaluateExpressionOrCatch, parseExpression } from '../../src/Scripting/Expression'; import { TaskBuilder } from '../TestingTools/TaskBuilder'; import { verifyMarkdownForDocs } from '../TestingTools/VerifyMarkdownTable'; import { continue_lines } from '../../src/Query/Scanner'; +import { constructArguments, parseAndEvaluateExpression } from '../../src/Scripting/TaskExpression'; import { formatToRepresentType } from './ScriptingTestHelpers'; window.moment = moment; diff --git a/tests/Scripting/TaskProperties.test.ts b/tests/Scripting/TaskProperties.test.ts index b0ed678118..bcc6920c65 100644 --- a/tests/Scripting/TaskProperties.test.ts +++ b/tests/Scripting/TaskProperties.test.ts @@ -3,11 +3,11 @@ */ import moment from 'moment'; -import { parseAndEvaluateExpression } from '../../src/Scripting/Expression'; import { Status } from '../../src/Status'; import { TaskBuilder } from '../TestingTools/TaskBuilder'; import { MarkdownTable } from '../TestingTools/VerifyMarkdownTable'; +import { parseAndEvaluateExpression } from '../../src/Scripting/TaskExpression'; import { addBackticks, determineExpressionType, formatToRepresentType } from './ScriptingTestHelpers'; window.moment = moment;