Skip to content

Commit

Permalink
fix(formula): concatenate calculate zero value
Browse files Browse the repository at this point in the history
  • Loading branch information
Dushusir committed Feb 3, 2024
1 parent 25fb4f6 commit 12273d0
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 119 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ describe('Test iferror function', () => {
const value = new ErrorValueObject(ErrorType.NA);
const valueIfError = new StringValueObject('error');
const result = textFunction.calculate(value, valueIfError);
expect(result.getValue()).toBe('error');
expect(result.getValue()).toBe(ErrorType.NA);
});

it('Value is array', () => {
Expand Down
137 changes: 27 additions & 110 deletions packages/engine-formula/src/functions/math/abs/__tests__/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,124 +14,41 @@
* limitations under the License.
*/

import type { IRange } from '@univerjs/core';
import { ObjectMatrix } from '@univerjs/core';
import { beforeEach, describe, expect, it } from 'vitest';
import { describe, expect, it } from 'vitest';

import type { ISheetData } from '../../../../basics/common';
import { ErrorType } from '../../../../basics/error-type';
import { RangeReferenceObject } from '../../../../engine/reference-object/range-reference-object';
import type { ArrayValueObject } from '../../../../engine/value-object/array-value-object';
import { ErrorValueObject } from '../../../../engine/value-object/base-value-object';
import { FUNCTION_NAMES_MATH } from '../../function-names';
import { Abs } from '..';
import { NumberValueObject } from '../../../../engine/value-object/primitive-object';
import { ArrayValueObject, transformToValue, transformToValueObject } from '../../../../engine/value-object/array-value-object';

const cellData = {
0: {
0: {
v: 1,
},
1: {
v: ' ',
},
2: {
v: 1.23,
},
3: {
v: true,
},
4: {
v: false,
},
},
1: {
0: {
v: 0,
},
1: {
v: '100',
},
2: {
v: '2.34',
},
3: {
v: 'test',
},
4: {
v: -3,
},
},
};
describe('Test abs function', () => {
const textFunction = new Abs(FUNCTION_NAMES_MATH.ABS);

describe('test abs', () => {
let unitId: string;
let sheetId: string;
let sheetData: ISheetData = {};
let abs: Abs;
let absCalculate: (range: IRange) => ArrayValueObject;

beforeEach(() => {
unitId = 'test';
sheetId = 'sheet1';
sheetData = {
[sheetId]: {
cellData: new ObjectMatrix(cellData),
rowCount: 4,
columnCount: 3,
},
};

// register abs
abs = new Abs(FUNCTION_NAMES_MATH.ABS);
absCalculate = (range: IRange) => {
// range

const rangeRef = new RangeReferenceObject(range, sheetId, unitId);
rangeRef.setUnitData({
[unitId]: sheetData,
});

return abs.calculate(rangeRef) as ArrayValueObject;
};
});

describe('abs', () => {
describe('correct situations', () => {
it('single cell', async () => {
// cell A1
const cell = {
startRow: 0,
startColumn: 0,
endRow: 0,
endColumn: 0,
};

const arrayValue = absCalculate(cell);
expect(arrayValue.getFirstCell().getValue()).toBe(1);
});
it('range', async () => {
// cell A1:E2
const cell = {
startRow: 0,
startColumn: 0,
endRow: 1,
endColumn: 4,
};

const arrayValue = absCalculate(cell);
expect(arrayValue.toValue()).toStrictEqual([
[1, '#VALUE!', 1.23, 1, 0],
[0, 100, 2.34, '#VALUE!', 3],
]);
});
describe('Abs', () => {
it('Value is normal', () => {
const value = new NumberValueObject(1);
const result = textFunction.calculate(value);
expect(result.getValue()).toBe(1);
});

describe('fault situations', () => {
it('value error', async () => {
const error = new ErrorValueObject(ErrorType.VALUE);
const errorValue = abs.calculate(error);
expect(errorValue.isError()).toBeTruthy();
it('Value is array', () => {
const valueArray = new ArrayValueObject({
calculateValueList: transformToValueObject([
[1, 2],
[2, 3],
[3, 4],
]),
rowCount: 3,
columnCount: 2,
unitId: '',
sheetId: '',
row: 0,
column: 0,
});
const result = textFunction.calculate(valueArray);
expect(transformToValue(result.getArrayValue())).toStrictEqual([[1, 2],
[2, 3],
[3, 4]]);
});
});
});
5 changes: 2 additions & 3 deletions packages/engine-formula/src/functions/math/abs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,12 @@
*/

import { ErrorType } from '../../../basics/error-type';
import type { FunctionVariantType } from '../../../engine/reference-object/base-reference-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 Abs extends BaseFunction {
override calculate(variant: FunctionVariantType) {
override calculate(variant: BaseValueObject) {
if (variant == null) {
return new ErrorValueObject(ErrorType.NA);
}
Expand All @@ -30,6 +29,6 @@ export class Abs extends BaseFunction {
return new ErrorValueObject(ErrorType.VALUE);
}

return (variant as BaseValueObject).abs();
return variant.abs();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ describe('Test concatenate function', () => {
const text1 = new ArrayValueObject({
calculateValueList: transformToValueObject([
['a', 'd'],
['b', 'e'],
[0, null],
]),
rowCount: 2,
columnCount: 2,
Expand All @@ -121,7 +121,7 @@ describe('Test concatenate function', () => {
const text2 = new ArrayValueObject({
calculateValueList: transformToValueObject([
[1, 2, 3],
[2, 3, 4],
[0, null, 4],
[3, 4, 5],
]),
rowCount: 3,
Expand All @@ -132,7 +132,7 @@ describe('Test concatenate function', () => {
column: 0,
});
const result = textFunction.calculate(text1, text2);
expect(transformToValue(result.getArrayValue())).toStrictEqual([['a1', 'd2', '#N/A'], ['b2', 'e3', '#N/A'], ['#N/A', '#N/A', '#N/A']]);
expect(transformToValue(result.getArrayValue())).toStrictEqual([['a1', 'd2', '#N/A'], ['00', '', '#N/A'], ['#N/A', '#N/A', '#N/A']]);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,10 @@ export class Concatenate extends BaseFunction {
return textValueObject;
}

return new StringValueObject(`${resultValueObject?.getValue() || ''}${textValueObject.getValue()}`);
const resultValueObjectString = resultValueObject?.isNull() ? '' : resultValueObject?.getValue() ?? '';
const textValueObjectString = textValueObject?.isNull() ? '' : textValueObject?.getValue() ?? '';

return new StringValueObject(`${resultValueObjectString}${textValueObjectString}`);
});
}

Expand Down
9 changes: 8 additions & 1 deletion packages/engine-formula/src/services/runtime.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/

import type { ICellData, IRange, Nullable } from '@univerjs/core';
import { CellValueType, Disposable, isNullCell, ObjectMatrix } from '@univerjs/core';
import { CellValueType, Disposable, isNullCell, isRealNum, ObjectMatrix } from '@univerjs/core';
import { createIdentifier } from '@wendellhu/redi';

import type {
Expand Down Expand Up @@ -644,6 +644,13 @@ export class FormulaRuntimeService extends Disposable implements IFormulaRuntime
t: CellValueType.BOOLEAN,
};
}
// String "00"
if (vo.isString() && isRealNum(v as string)) {
return {
v,
t: CellValueType.FORCE_STRING,
};
}
return {
v,
t: CellValueType.STRING,
Expand Down

0 comments on commit 12273d0

Please sign in to comment.