From a7664d6b0dca324a69ca97ddd796dd29692392ec Mon Sep 17 00:00:00 2001 From: hond Date: Mon, 12 Oct 2020 13:36:59 +0800 Subject: [PATCH 1/2] add reverse prebuilt function --- .../src/builtinFunctions/index.ts | 1 + .../src/builtinFunctions/reverse.ts | 51 +++++++++++++++++++ .../src/expressionFunctions.ts | 1 + .../src/expressionType.ts | 1 + .../tests/badExpression.test.js | 2 + .../tests/expressionParser.test.js | 6 +++ 6 files changed, 62 insertions(+) create mode 100644 libraries/adaptive-expressions/src/builtinFunctions/reverse.ts diff --git a/libraries/adaptive-expressions/src/builtinFunctions/index.ts b/libraries/adaptive-expressions/src/builtinFunctions/index.ts index 67daf425b7..69a8a14425 100644 --- a/libraries/adaptive-expressions/src/builtinFunctions/index.ts +++ b/libraries/adaptive-expressions/src/builtinFunctions/index.ts @@ -117,6 +117,7 @@ export * from './range'; export * from './removeProperty'; export * from './replace'; export * from './replaceIgnoreCase'; +export * from './reverse'; export * from './round'; export * from './select'; export * from './sentenceCase'; diff --git a/libraries/adaptive-expressions/src/builtinFunctions/reverse.ts b/libraries/adaptive-expressions/src/builtinFunctions/reverse.ts new file mode 100644 index 0000000000..f42a53f501 --- /dev/null +++ b/libraries/adaptive-expressions/src/builtinFunctions/reverse.ts @@ -0,0 +1,51 @@ +/** + * @module adaptive-expressions + */ +/** + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. + */ + +import { Expression } from '../expression'; +import { EvaluateExpressionDelegate, ExpressionEvaluator } from '../expressionEvaluator'; +import { ExpressionType } from '../expressionType'; +import { FunctionUtils } from '../functionUtils'; +import { ReturnType } from '../returnType'; + +/** + * Reverses the order of the elements in a String or Array. + */ +export class Reverse extends ExpressionEvaluator { + /** + * Initializes a new instance of the `Reverse` class. + */ + public constructor() { + super(ExpressionType.Reverse, Reverse.evaluator(), ReturnType.String | ReturnType.Array, Reverse.validator); + } + + /** + * @private + */ + private static evaluator(): EvaluateExpressionDelegate { + return FunctionUtils.applyWithError((args: any[]): any => { + let value = undefined; + let error = undefined; + if (typeof args[0] === 'string') { + value = args[0].split('').reverse().join(''); + } else if (Array.isArray(args[0])) { + value = args[0].reverse(); + } else { + error = `${args[0]} is not a string or list.`; + } + + return { value, error }; + }, FunctionUtils.verifyContainer); + } + + /** + * @private + */ + private static validator(expression: Expression): void { + FunctionUtils.validateOrder(expression, [], ReturnType.String | ReturnType.Array); + } +} diff --git a/libraries/adaptive-expressions/src/expressionFunctions.ts b/libraries/adaptive-expressions/src/expressionFunctions.ts index 9cf7d26fd5..30e8e22c34 100644 --- a/libraries/adaptive-expressions/src/expressionFunctions.ts +++ b/libraries/adaptive-expressions/src/expressionFunctions.ts @@ -142,6 +142,7 @@ export class ExpressionFunctions { new BuiltinFunctions.RemoveProperty(), new BuiltinFunctions.Replace(), new BuiltinFunctions.ReplaceIgnoreCase(), + new BuiltinFunctions.Reverse(), new BuiltinFunctions.Round(), new BuiltinFunctions.Select(), new BuiltinFunctions.SentenceCase(), diff --git a/libraries/adaptive-expressions/src/expressionType.ts b/libraries/adaptive-expressions/src/expressionType.ts index d92647c5d3..0bf8ad0c9e 100644 --- a/libraries/adaptive-expressions/src/expressionType.ts +++ b/libraries/adaptive-expressions/src/expressionType.ts @@ -148,6 +148,7 @@ export class ExpressionType { public static readonly IndicesAndValues: string = 'indicesAndValues'; public static readonly Flatten: string = 'flatten'; public static readonly Unique: string = 'unique'; + public static readonly Reverse: string = 'reverse'; // Misc public static readonly Constant: string = 'Constant'; diff --git a/libraries/adaptive-expressions/tests/badExpression.test.js b/libraries/adaptive-expressions/tests/badExpression.test.js index c0fcdb97df..8fc8326bfa 100644 --- a/libraries/adaptive-expressions/tests/badExpression.test.js +++ b/libraries/adaptive-expressions/tests/badExpression.test.js @@ -391,6 +391,8 @@ const badExpressions = [ ['contains(\'hello world\', \'hello\', \'new\')', 'should have 2 parameter'], ['count(items, 1)', 'should have 1 parameter'], ['count(1)', 'first param should be string, array or map'], + ['reverse(items, 1)', 'should have 1 parameter'], + ['reverse(1)', 'first param should be string or array'], ['empty(1,2)', 'should have two params'], ['first(items,2)', 'should have 1 param'], ['last(items,2)', 'should have 1 param'], diff --git a/libraries/adaptive-expressions/tests/expressionParser.test.js b/libraries/adaptive-expressions/tests/expressionParser.test.js index 495ae2a85e..e279a032c7 100644 --- a/libraries/adaptive-expressions/tests/expressionParser.test.js +++ b/libraries/adaptive-expressions/tests/expressionParser.test.js @@ -189,6 +189,10 @@ const testCases = [ ['count(\'hello\')', 5], ['count("hello")', 5], ['count(concat(hello,\r\nworld))', 10], + ['reverse("hello")', 'olleh'], + ['reverse(reverse("hello"))', 'hello'], + ['reverse(\'hello\')', 'olleh'], + ['reverse(concat(hello,world))', 'dlrowolleh'], ['replace(\'hello\', \'l\', \'k\')', 'hekko'], ['replace(\'hello\', \'L\', \'k\')', 'hello'], ['replace(nullObj, \'L\', \'k\')', ''], @@ -596,6 +600,8 @@ const testCases = [ ['count(split(hello,\'e\'))', 2], ['count(createArray(\'h\', \'e\', \'l\', \'l\', \'o\'))', 5], ['empty(\'\')', true], + ['reverse(split(hello,"e"))', ['llo', 'h']], + ['reverse(createArray("h", "e", "l", "l", "o"))', ['o', 'l', 'l', 'e', 'h']], ['empty(\'a\')', false], ['empty(bag)', false], ['empty(items)', false], From a71e106be173c741e36ec08b478ebf21ba79a771 Mon Sep 17 00:00:00 2001 From: hond Date: Mon, 12 Oct 2020 15:16:41 +0800 Subject: [PATCH 2/2] retrigger