-
-
Notifications
You must be signed in to change notification settings - Fork 665
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(formula): add some Text/Math/Lookup formulas (#2842)
Co-authored-by: wpxp123456 <Wpxp1223456>
- Loading branch information
1 parent
43220a1
commit 778e371
Showing
48 changed files
with
4,830 additions
and
216 deletions.
There are no files selected for viewing
41 changes: 41 additions & 0 deletions
41
packages/engine-formula/src/functions/lookup/areas/__tests__/index.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
/** | ||
* Copyright 2023-present DreamNum Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
import { describe, expect, it } from 'vitest'; | ||
|
||
import { FUNCTION_NAMES_LOOKUP } from '../../function-names'; | ||
import { Areas } from '../index'; | ||
import { StringValueObject } from '../../../../engine/value-object/primitive-object'; | ||
import { ErrorType } from '../../../../basics/error-type'; | ||
import { CellReferenceObject } from '../../../../engine/reference-object/cell-reference-object'; | ||
|
||
describe('Test areas function', () => { | ||
const testFunction = new Areas(FUNCTION_NAMES_LOOKUP.AREAS); | ||
|
||
describe('Areas', () => { | ||
it('Value is reference', async () => { | ||
const reference = new CellReferenceObject('A1'); | ||
const result = testFunction.calculate(reference); | ||
expect(result.getValue()).toBe(1); | ||
}); | ||
|
||
it('Value is not reference', async () => { | ||
const reference = StringValueObject.create('A1'); | ||
const result = testFunction.calculate(reference); | ||
expect(result.getValue()).toBe(ErrorType.VALUE); | ||
}); | ||
}); | ||
}); |
37 changes: 37 additions & 0 deletions
37
packages/engine-formula/src/functions/lookup/areas/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/** | ||
* Copyright 2023-present DreamNum Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
import { ErrorType } from '../../../basics/error-type'; | ||
import type { FunctionVariantType } from '../../../engine/reference-object/base-reference-object'; | ||
import { ErrorValueObject } from '../../../engine/value-object/base-value-object'; | ||
import { NumberValueObject } from '../../../engine/value-object/primitive-object'; | ||
import { BaseFunction } from '../../base-function'; | ||
|
||
export class Areas extends BaseFunction { | ||
override minParams = 1; | ||
|
||
override maxParams = 1; | ||
|
||
override needsReferenceObject = true; | ||
|
||
override calculate(reference: FunctionVariantType) { | ||
if (reference.isReferenceObject()) { | ||
return NumberValueObject.create(1); | ||
} | ||
|
||
return ErrorValueObject.create(ErrorType.VALUE); | ||
} | ||
} |
90 changes: 90 additions & 0 deletions
90
packages/engine-formula/src/functions/lookup/choosecols/__tests__/index.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
/** | ||
* Copyright 2023-present DreamNum Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
import { describe, expect, it } from 'vitest'; | ||
|
||
import { ArrayValueObject } from '../../../../engine/value-object/array-value-object'; | ||
import { FUNCTION_NAMES_LOOKUP } from '../../function-names'; | ||
import { Choosecols } from '../index'; | ||
import { BooleanValueObject, NullValueObject, NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object'; | ||
import { ErrorType } from '../../../../basics/error-type'; | ||
import { getObjectValue } from '../../../__tests__/create-function-test-bed'; | ||
import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; | ||
|
||
describe('Test choosecols function', () => { | ||
const testFunction = new Choosecols(FUNCTION_NAMES_LOOKUP.CHOOSECOLS); | ||
|
||
describe('Choosecols', () => { | ||
it('Value is normal', async () => { | ||
const array = ArrayValueObject.create('{1,2,3;2,3,4}'); | ||
const colNum1 = NumberValueObject.create(1); | ||
const colNum2 = NumberValueObject.create(2); | ||
const resultObject = testFunction.calculate(array, colNum1, colNum2); | ||
expect(getObjectValue(resultObject)).toStrictEqual([ | ||
[1, 2], | ||
[2, 3], | ||
]); | ||
}); | ||
|
||
it('ColNum value is zero or exceeds the number of columns in the array', async () => { | ||
const array = ArrayValueObject.create('{1,2,3;2,3,4}'); | ||
const colNum1 = NumberValueObject.create(0); | ||
const resultObject = testFunction.calculate(array, colNum1); | ||
expect(getObjectValue(resultObject)).toStrictEqual(ErrorType.VALUE); | ||
|
||
const colNum2 = NumberValueObject.create(4); | ||
const resultObject2 = testFunction.calculate(array, colNum2); | ||
expect(getObjectValue(resultObject2)).toStrictEqual(ErrorType.VALUE); | ||
}); | ||
|
||
it('Array value is error', async () => { | ||
const array = ErrorValueObject.create(ErrorType.NAME); | ||
const colNum1 = NumberValueObject.create(11); | ||
const resultObject = testFunction.calculate(array, colNum1); | ||
expect(getObjectValue(resultObject)).toStrictEqual(ErrorType.NAME); | ||
}); | ||
|
||
it('ColNum value is error or string or boolean or blank cell or multi-column array', async () => { | ||
const array = ArrayValueObject.create('{1,2,3;2,3,4}'); | ||
const colNum1 = ErrorValueObject.create(ErrorType.NAME); | ||
const resultObject = testFunction.calculate(array, colNum1); | ||
expect(getObjectValue(resultObject)).toStrictEqual(ErrorType.NAME); | ||
|
||
const colNum2 = StringValueObject.create('test'); | ||
const resultObject2 = testFunction.calculate(array, colNum2); | ||
expect(getObjectValue(resultObject2)).toStrictEqual(ErrorType.VALUE); | ||
|
||
const colNum3 = BooleanValueObject.create(true); | ||
const resultObject3 = testFunction.calculate(array, colNum3); | ||
expect(getObjectValue(resultObject3)).toStrictEqual([ | ||
[1], | ||
[2], | ||
]); | ||
|
||
const colNum4 = BooleanValueObject.create(false); | ||
const resultObject4 = testFunction.calculate(array, colNum4); | ||
expect(getObjectValue(resultObject4)).toStrictEqual(ErrorType.VALUE); | ||
|
||
const colNum5 = NullValueObject.create(); | ||
const resultObject5 = testFunction.calculate(array, colNum5); | ||
expect(getObjectValue(resultObject5)).toStrictEqual(ErrorType.VALUE); | ||
|
||
const colNum6 = ArrayValueObject.create('{1,2}'); | ||
const resultObject6 = testFunction.calculate(array, colNum6); | ||
expect(getObjectValue(resultObject6)).toStrictEqual(ErrorType.VALUE); | ||
}); | ||
}); | ||
}); |
100 changes: 100 additions & 0 deletions
100
packages/engine-formula/src/functions/lookup/choosecols/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
/** | ||
* Copyright 2023-present DreamNum Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
import { ErrorType } from '../../../basics/error-type'; | ||
import { ArrayValueObject } from '../../../engine/value-object/array-value-object'; | ||
import type { BaseValueObject } from '../../../engine/value-object/base-value-object'; | ||
import { ErrorValueObject } from '../../../engine/value-object/base-value-object'; | ||
|
||
import { BaseFunction } from '../../base-function'; | ||
|
||
export class Choosecols extends BaseFunction { | ||
override minParams = 2; | ||
|
||
override maxParams = 255; | ||
|
||
override calculate(array: BaseValueObject, ...variants: BaseValueObject[]) { | ||
if (array.isError()) { | ||
return array; | ||
} | ||
|
||
const arrayRowCount = array.isArray() ? (array as ArrayValueObject).getRowCount() : 1; | ||
const arrayColumnCount = array.isArray() ? (array as ArrayValueObject).getColumnCount() : 1; | ||
|
||
const result: BaseValueObject[][] = []; | ||
|
||
for (let i = 0; i < variants.length; i++) { | ||
let variantObject = variants[i]; | ||
|
||
if (variantObject.isArray()) { | ||
const variantRowCount = (variantObject as ArrayValueObject).getRowCount(); | ||
const variantColumnCount = (variantObject as ArrayValueObject).getColumnCount(); | ||
|
||
if (variantRowCount > 1 || variantColumnCount > 1) { | ||
return ErrorValueObject.create(ErrorType.VALUE); | ||
} | ||
|
||
variantObject = (variantObject as ArrayValueObject).get(0, 0) as BaseValueObject; | ||
} | ||
|
||
if (variantObject.isString()) { | ||
variantObject = variantObject.convertToNumberObjectValue(); | ||
} | ||
|
||
if (variantObject.isError()) { | ||
return variantObject; | ||
} | ||
|
||
const variantValue = Math.trunc(+variantObject.getValue()); | ||
|
||
if (variantValue === 0 || Math.abs(variantValue) > arrayColumnCount) { | ||
return ErrorValueObject.create(ErrorType.VALUE); | ||
} | ||
|
||
let searchColArray = array; | ||
|
||
if (arrayColumnCount > 1) { | ||
if (variantValue < 0) { | ||
searchColArray = (array as ArrayValueObject).slice(undefined, [variantValue + arrayColumnCount, variantValue + 1 + arrayColumnCount]) as BaseValueObject; | ||
} else { | ||
searchColArray = (array as ArrayValueObject).slice(undefined, [variantValue - 1, variantValue]) as BaseValueObject; | ||
} | ||
} | ||
|
||
for (let r = 0; r < arrayRowCount; r++) { | ||
if (!result[r]) { | ||
result[r] = []; | ||
} | ||
|
||
if (array.isArray()) { | ||
result[r].push((searchColArray as ArrayValueObject).get(r, 0) as BaseValueObject); | ||
} else { | ||
result[r].push(array); | ||
} | ||
} | ||
} | ||
|
||
return ArrayValueObject.create({ | ||
calculateValueList: result, | ||
rowCount: result.length, | ||
columnCount: result[0].length || 0, | ||
unitId: this.unitId as string, | ||
sheetId: this.subUnitId as string, | ||
row: this.row, | ||
column: this.column, | ||
}); | ||
} | ||
} |
89 changes: 89 additions & 0 deletions
89
packages/engine-formula/src/functions/lookup/chooserows/__tests__/index.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
/** | ||
* Copyright 2023-present DreamNum Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
import { describe, expect, it } from 'vitest'; | ||
|
||
import { ArrayValueObject } from '../../../../engine/value-object/array-value-object'; | ||
import { FUNCTION_NAMES_LOOKUP } from '../../function-names'; | ||
import { Chooserows } from '../index'; | ||
import { BooleanValueObject, NullValueObject, NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object'; | ||
import { ErrorType } from '../../../../basics/error-type'; | ||
import { getObjectValue } from '../../../__tests__/create-function-test-bed'; | ||
import { ErrorValueObject } from '../../../../engine/value-object/base-value-object'; | ||
|
||
describe('Test chooserows function', () => { | ||
const testFunction = new Chooserows(FUNCTION_NAMES_LOOKUP.CHOOSEROWS); | ||
|
||
describe('Chooserows', () => { | ||
it('Value is normal', async () => { | ||
const array = ArrayValueObject.create('{1,2,3;2,3,4}'); | ||
const rowNum1 = NumberValueObject.create(1); | ||
const rowNum2 = NumberValueObject.create(2); | ||
const resultObject = testFunction.calculate(array, rowNum1, rowNum2); | ||
expect(getObjectValue(resultObject)).toStrictEqual([ | ||
[1, 2, 3], | ||
[2, 3, 4], | ||
]); | ||
}); | ||
|
||
it('RowNum value is zero or exceeds the number of rows in the array', async () => { | ||
const array = ArrayValueObject.create('{1,2,3;2,3,4}'); | ||
const rowNum1 = NumberValueObject.create(0); | ||
const resultObject = testFunction.calculate(array, rowNum1); | ||
expect(getObjectValue(resultObject)).toStrictEqual(ErrorType.VALUE); | ||
|
||
const rowNum2 = NumberValueObject.create(4); | ||
const resultObject2 = testFunction.calculate(array, rowNum2); | ||
expect(getObjectValue(resultObject2)).toStrictEqual(ErrorType.VALUE); | ||
}); | ||
|
||
it('Array value is error', async () => { | ||
const array = ErrorValueObject.create(ErrorType.NAME); | ||
const rowNum1 = NumberValueObject.create(11); | ||
const resultObject = testFunction.calculate(array, rowNum1); | ||
expect(getObjectValue(resultObject)).toStrictEqual(ErrorType.NAME); | ||
}); | ||
|
||
it('RowNum value is error or string or boolean or blank cell or multi-row array', async () => { | ||
const array = ArrayValueObject.create('{1,2,3;2,3,4}'); | ||
const rowNum1 = ErrorValueObject.create(ErrorType.NAME); | ||
const resultObject = testFunction.calculate(array, rowNum1); | ||
expect(getObjectValue(resultObject)).toStrictEqual(ErrorType.NAME); | ||
|
||
const rowNum2 = StringValueObject.create('test'); | ||
const resultObject2 = testFunction.calculate(array, rowNum2); | ||
expect(getObjectValue(resultObject2)).toStrictEqual(ErrorType.VALUE); | ||
|
||
const rowNum3 = BooleanValueObject.create(true); | ||
const resultObject3 = testFunction.calculate(array, rowNum3); | ||
expect(getObjectValue(resultObject3)).toStrictEqual([ | ||
[1, 2, 3], | ||
]); | ||
|
||
const rowNum4 = BooleanValueObject.create(false); | ||
const resultObject4 = testFunction.calculate(array, rowNum4); | ||
expect(getObjectValue(resultObject4)).toStrictEqual(ErrorType.VALUE); | ||
|
||
const rowNum5 = NullValueObject.create(); | ||
const resultObject5 = testFunction.calculate(array, rowNum5); | ||
expect(getObjectValue(resultObject5)).toStrictEqual(ErrorType.VALUE); | ||
|
||
const rowNum6 = ArrayValueObject.create('{1;2}'); | ||
const resultObject6 = testFunction.calculate(array, rowNum6); | ||
expect(getObjectValue(resultObject6)).toStrictEqual(ErrorType.VALUE); | ||
}); | ||
}); | ||
}); |
Oops, something went wrong.