Skip to content

Commit

Permalink
fix(formula): leftb byte length
Browse files Browse the repository at this point in the history
  • Loading branch information
Dushusir committed Sep 13, 2024
1 parent bf5cd9c commit 5530361
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@

import { describe, expect, it } from 'vitest';

import { ErrorType } from '../../../../basics/error-type';
import { ArrayValueObject, transformToValue, transformToValueObject } from '../../../../engine/value-object/array-value-object';
import { NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object';
import { FUNCTION_NAMES_TEXT } from '../../function-names';
import { Leftb } from '../index';
import { NumberValueObject, StringValueObject } from '../../../../engine/value-object/primitive-object';
import { ArrayValueObject, transformToValue, transformToValueObject } from '../../../../engine/value-object/array-value-object';
import { ErrorType } from '../../../../basics/error-type';

describe('Test LEFT function', () => {
describe('Test LEFTB function', () => {
const leftbFunction = new Leftb(FUNCTION_NAMES_TEXT.LEFTB);

describe('Left', () => {
describe('Leftb', () => {
describe('Single Value Tests', () => {
it('Should return leftmost bytes of a single text', () => {
const text = StringValueObject.create('Hello World');
Expand Down Expand Up @@ -161,5 +161,72 @@ describe('Test LEFT function', () => {
const result = leftbFunction.calculate(text, numChars);
expect(transformToValue(result.getArrayValue())).toStrictEqual([['']]);
});

it('Handles extracting CJK, first byte', () => {
const textArray = new ArrayValueObject({
calculateValueList: transformToValueObject([
['销售额'],
['から'],
['이트'],
]),
rowCount: 3,
columnCount: 1,
unitId: '',
sheetId: '',
row: 0,
column: 0,
});
const result = leftbFunction.calculate(textArray);
expect(transformToValue(result.getArrayValue())).toStrictEqual([
[''],
[''],
[''],
]);
});

it('Handles extracting CJK, first character', () => {
const textArray = new ArrayValueObject({
calculateValueList: transformToValueObject([
['销售额'],
['から'],
['이트'],
]),
rowCount: 3,
columnCount: 1,
unitId: '',
sheetId: '',
row: 0,
column: 0,
});
const result = leftbFunction.calculate(textArray, NumberValueObject.create(2));
expect(transformToValue(result.getArrayValue())).toStrictEqual([
['销'],
['か'],
['이'],
]);
});
it('Handles extracting multiple languages', () => {
const textArray = new ArrayValueObject({
calculateValueList: transformToValueObject([
['销售额'],
['uから'],
['이u트'],
['이트u'],
]),
rowCount: 4,
columnCount: 1,
unitId: '',
sheetId: '',
row: 0,
column: 0,
});
const result = leftbFunction.calculate(textArray, NumberValueObject.create(3));
expect(transformToValue(result.getArrayValue())).toStrictEqual([
['销'],
['uか'],
['이u'],
['이'],
]);
});
});
});
31 changes: 20 additions & 11 deletions packages/engine-formula/src/functions/text/leftb/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@

import { ErrorType } from '../../../basics/error-type';
import { expandArrayValueObject } from '../../../engine/utils/array-object';
import { charLenByte } from '../../../engine/utils/char-kit';
import { ArrayValueObject } from '../../../engine/value-object/array-value-object';
import type { BaseValueObject } from '../../../engine/value-object/base-value-object';
import { NumberValueObject, StringValueObject } from '../../../engine/value-object/primitive-object';
import { BaseFunction } from '../../base-function';
import { charLenByte } from '../../../engine/utils/char-kit';
import type { BaseValueObject } from '../../../engine/value-object/base-value-object';

export class Leftb extends BaseFunction {
override minParams = 1;
Expand Down Expand Up @@ -68,11 +68,7 @@ export class Leftb extends BaseFunction {
}

const textValueString = `${textValue.getValue()}`;
const byteLength = charLenByte(textValueString);
if (numBytesValueNumber >= byteLength) {
return ArrayValueObject.createByArray([[textValueString]]); // Return original string if numBytes >= byteLength
}
return StringValueObject.create(Array.from(textValueString).slice(0, numBytesValueNumber).join(''));
return StringValueObject.create(this._sliceByBytes(textValueString, numBytesValueNumber));
});
}

Expand All @@ -90,12 +86,25 @@ export class Leftb extends BaseFunction {
if (typeof numBytesValueNumber !== 'number' || numBytesValueNumber < 0) {
return ArrayValueObject.createByArray([[ErrorType.VALUE]]);
}
const byteLength = charLenByte(textValueString);

if (numBytesValueNumber >= byteLength) {
return ArrayValueObject.createByArray([[textValueString]]); // Return original string if numBytes >= byteLength
return ArrayValueObject.createByArray([[this._sliceByBytes(textValueString, numBytesValueNumber)]]);
}

private _sliceByBytes(text: string, numBytes: number) {
let byteCount = 0;
let sliceIndex = 0;

// Iterate over each Unicode character (correctly handling multi-byte characters and emoji)
for (let i = 0; i < text.length; i++) {
const char = text[i];
const charByteLength = charLenByte(char);
if (byteCount + charByteLength > numBytes) {
break;
}
byteCount += charByteLength;
sliceIndex++;
}

return ArrayValueObject.createByArray([[Array.from(textValueString).slice(0, numBytesValueNumber).join('')]]);
return [...text].slice(0, sliceIndex).join('');
}
}

0 comments on commit 5530361

Please sign in to comment.