From ae576a7703df7c9a0700d42d5f40acc0b88e2c77 Mon Sep 17 00:00:00 2001 From: wpxp123456 <2677556700@qq.com> Date: Thu, 12 Dec 2024 14:57:09 +0800 Subject: [PATCH] fix(formula): fix xlookup formula (#4263) Co-authored-by: wpxp123456 --- .../lookup/xlookup/__tests__/index.spec.ts | 73 ++++++++++++++++--- .../src/functions/lookup/xlookup/index.ts | 27 +++++-- 2 files changed, 85 insertions(+), 15 deletions(-) diff --git a/packages/engine-formula/src/functions/lookup/xlookup/__tests__/index.spec.ts b/packages/engine-formula/src/functions/lookup/xlookup/__tests__/index.spec.ts index cccf345ac87..4669225e936 100644 --- a/packages/engine-formula/src/functions/lookup/xlookup/__tests__/index.spec.ts +++ b/packages/engine-formula/src/functions/lookup/xlookup/__tests__/index.spec.ts @@ -14,11 +14,11 @@ * limitations under the License. */ -import type { BaseValueObject } from '../../../../engine/value-object/base-value-object'; - import { describe, expect, it } from 'vitest'; + import { ErrorType } from '../../../../basics/error-type'; import { ArrayValueObject } from '../../../../engine/value-object/array-value-object'; +import { type BaseValueObject, ErrorValueObject } from '../../../../engine/value-object/base-value-object'; import { NullValueObject, NumberValueObject, @@ -64,6 +64,20 @@ const arrayValueObject4 = ArrayValueObject.create(/*ts*/ `{ 801, 3500 }`); +const arrayValueObject5 = ArrayValueObject.create(/*ts*/ `{ + Red, 15; + Blue, 16; + Red, 17; + Blue, 16.5; + Gray, 28; + Blue, 29; + Black, 30; + Black, 25; + Gray, 26; + Black2, 25; + Red, 34 +}`); + describe('Test xlookup', () => { const testFunction = new Xlookup(FUNCTION_NAMES_LOOKUP.XLOOKUP); @@ -187,7 +201,7 @@ describe('Test xlookup', () => { NumberValueObject.create(0), NumberValueObject.create(2) ) as BaseValueObject; - expect(getObjectValue(resultObject).toString()).toBe('0'); + expect(getObjectValue(resultObject)).toBe(ErrorType.NA); // match_mode 0 matched resultObject = testFunction.calculate( @@ -198,7 +212,7 @@ describe('Test xlookup', () => { NumberValueObject.create(0), NumberValueObject.create(2) ) as BaseValueObject; - expect(getObjectValue(resultObject).toString()).toBe('0'); + expect(getObjectValue(resultObject)).toBe(ErrorType.NA); // match_mode -1 resultObject = testFunction.calculate( @@ -220,7 +234,7 @@ describe('Test xlookup', () => { NumberValueObject.create(-1), NumberValueObject.create(2) ) as BaseValueObject; - expect(getObjectValue(resultObject).toString()).toBe('0'); + expect(getObjectValue(resultObject)).toBe(ErrorType.NA); // match_mode 1 resultObject = testFunction.calculate( @@ -277,7 +291,7 @@ describe('Test xlookup', () => { NumberValueObject.create(0), NumberValueObject.create(-2) ) as BaseValueObject; - expect(getObjectValue(resultObject).toString()).toBe('0'); + expect(getObjectValue(resultObject)).toBe(ErrorType.NA); // match_mode 0, matched resultObject = testFunction.calculate( @@ -367,7 +381,7 @@ describe('Test xlookup', () => { NumberValueObject.create(0), NumberValueObject.create(1) ) as BaseValueObject; - expect(getObjectValue(resultObject).toString()).toBe('0'); + expect(getObjectValue(resultObject)).toBe(ErrorType.NA); // match_mode 0 matched resultObject = testFunction.calculate( @@ -433,7 +447,7 @@ describe('Test xlookup', () => { NumberValueObject.create(2), NumberValueObject.create(1) ) as BaseValueObject; - expect(getObjectValue(resultObject).toString()).toBe('0'); + expect(getObjectValue(resultObject)).toBe(ErrorType.NA); // match_mode 2 matched resultObject = testFunction.calculate( @@ -457,7 +471,7 @@ describe('Test xlookup', () => { NumberValueObject.create(0), NumberValueObject.create(-1) ) as BaseValueObject; - expect(getObjectValue(resultObject).toString()).toBe('0'); + expect(getObjectValue(resultObject)).toBe(ErrorType.NA); // match_mode 0 matched resultObject = testFunction.calculate( @@ -523,7 +537,7 @@ describe('Test xlookup', () => { NumberValueObject.create(2), NumberValueObject.create(-1) ) as BaseValueObject; - expect(getObjectValue(resultObject).toString()).toBe('0'); + expect(getObjectValue(resultObject)).toBe(ErrorType.NA); // match_mode 2 matched resultObject = testFunction.calculate( @@ -537,4 +551,43 @@ describe('Test xlookup', () => { expect(getObjectValue(resultObject).toString()).toBe('1200'); }); }); + + describe('More test', () => { + it('MatchMode and searchMode default value test', async () => { + const lookupValue = NumberValueObject.create(25); + const lookupArray = arrayValueObject5.slice(undefined, [1])!; + const returnArray = arrayValueObject5.slice(undefined, [0, 1])!; + const nullObject = NullValueObject.create(); + const matchMode = NumberValueObject.create(0); + const searchMode = NumberValueObject.create(1); + const searchMode2 = NumberValueObject.create(-1); + + const result = testFunction.calculate(lookupValue, lookupArray, returnArray); + expect(getObjectValue(result)).toBe('Black'); + + const result2 = testFunction.calculate(lookupValue, lookupArray, returnArray, nullObject, matchMode); + expect(getObjectValue(result2)).toBe('Black'); + + const result3 = testFunction.calculate(lookupValue, lookupArray, returnArray, nullObject, nullObject, searchMode); + expect(getObjectValue(result3)).toBe('Black'); + + const result4 = testFunction.calculate(lookupValue, lookupArray, returnArray, nullObject, nullObject, searchMode2); + expect(getObjectValue(result4)).toBe('Black2'); + }); + + it('MatchMode and searchMode is error', async () => { + const lookupValue = NumberValueObject.create(25); + const lookupArray = arrayValueObject5.slice(undefined, [1])!; + const returnArray = arrayValueObject5.slice(undefined, [0, 1])!; + const nullObject = NullValueObject.create(); + const matchMode = ErrorValueObject.create(ErrorType.NAME); + const searchMode = ErrorValueObject.create(ErrorType.NAME); + + const result = testFunction.calculate(lookupValue, lookupArray, returnArray, nullObject, matchMode); + expect(getObjectValue(result)).toBe(ErrorType.NAME); + + const result2 = testFunction.calculate(lookupValue, lookupArray, returnArray, nullObject, nullObject, searchMode); + expect(getObjectValue(result2)).toBe(ErrorType.NAME); + }); + }); }); diff --git a/packages/engine-formula/src/functions/lookup/xlookup/index.ts b/packages/engine-formula/src/functions/lookup/xlookup/index.ts index 7f1b8747c82..85aeec52e2b 100644 --- a/packages/engine-formula/src/functions/lookup/xlookup/index.ts +++ b/packages/engine-formula/src/functions/lookup/xlookup/index.ts @@ -38,6 +38,21 @@ export class Xlookup extends BaseFunction { matchMode?: BaseValueObject, searchMode?: BaseValueObject ) { + let _ifNotFound = ifNotFound ?? ErrorValueObject.create(ErrorType.NA); + if (ifNotFound?.isNull()) { + _ifNotFound = ErrorValueObject.create(ErrorType.NA); + } + + let _matchMode = matchMode ?? NumberValueObject.create(0); + if (matchMode?.isNull()) { + _matchMode = NumberValueObject.create(0); + } + + let _searchMode = searchMode ?? NumberValueObject.create(1); + if (searchMode?.isNull()) { + _searchMode = NumberValueObject.create(1); + } + if (lookupValue.isError()) { return lookupValue; } @@ -63,19 +78,21 @@ export class Xlookup extends BaseFunction { return ErrorValueObject.create(ErrorType.VALUE); } - if (ifNotFound?.isError() || matchMode?.isError() || searchMode?.isError()) { - return ErrorValueObject.create(ErrorType.NA); + if (_matchMode.isError()) { + return _matchMode; } - const _ifNotFound = ifNotFound ?? ErrorValueObject.create(ErrorType.NA); + if (_searchMode.isError()) { + return _searchMode; + } - const matchModeValue = this.getIndexNumValue(matchMode || NumberValueObject.create(0)); + const matchModeValue = this.getIndexNumValue(_matchMode); if (matchModeValue instanceof ErrorValueObject) { return matchModeValue; } - const searchModeValue = this.getIndexNumValue(searchMode || NumberValueObject.create(1)); + const searchModeValue = this.getIndexNumValue(_searchMode); if (searchModeValue instanceof ErrorValueObject) { return searchModeValue;