Skip to content

Commit

Permalink
Add ability to change the behavior of our converter to number fix #8634
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewtelnov committed Jul 31, 2024
1 parent a639976 commit 59d9409
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 8 deletions.
13 changes: 8 additions & 5 deletions src/expressions/expressions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ export class Const extends Operand {
return this.getCorrectValue(this.value);
}

public setVariables(variables: Array<string>) {}
public setVariables(variables: Array<string>): void {}
protected getCorrectValue(value: any): any {
if (!value || typeof value != "string") return value;
if (OperandMaker.isBooleanValue(value)) return value.toLowerCase() === "true";
Expand All @@ -270,10 +270,13 @@ export class Const extends Operand {
this.isQuote(value[value.length - 1])
)
return value.substring(1, value.length - 1);
if (Helpers.isNumber(value)) {
if (value.indexOf("0x") == 0) return parseInt(value);
if (value.length > 1 && value[0] == "0" && (value.length < 2 || (value[1] !== "." && value[1] !== ","))) return value;
return parseFloat(value);
if(Helpers.isNumber(value)) {
if(value[0] === "0" && value.indexOf("0x") != 0) {
const len = value.length;
const hasPoint = len > 1 && (value[1] === "." || value[1] === ",");
if(!hasPoint && len > 1 || hasPoint && len < 2) return value;
}
return Helpers.getNumber(value);
}
return value;
}
Expand Down
11 changes: 9 additions & 2 deletions src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,9 +195,16 @@ export class Helpers {
return !isNaN(this.getNumber(value));
}
public static getNumber(value: any): number {
const newValue = Helpers.getNumberCore(value);
return settings.convertNumber(value, newValue);
}
private static getNumberCore(value: any): number {
if (typeof value == "string") {
if(!value.replace(" ", "")) return NaN;
if(value.indexOf("0x") == 0 && value.length > 32) return NaN;
if(!value.trim()) return NaN;
if(value.indexOf("0x") == 0) {
if(value.length > 32) return NaN;
return parseInt(value);
}
if(Helpers.isStringHasOperator(value)) return NaN;
}
value = this.prepareStringToNumber(value);
Expand Down
3 changes: 2 additions & 1 deletion src/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -800,5 +800,6 @@ export var settings = {
* }
* ```
*/
storeUtcDates: false
storeUtcDates: false,
convertNumber: (originalValue: any, numberValue: number): number => { return numberValue; }
};
18 changes: 18 additions & 0 deletions tests/expressions/expressionParserTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1563,3 +1563,21 @@ QUnit.test("ExpressionRunner: substring", function(assert) {
values.s = 10;
assert.equal(runner.run(values), "", "10");
});
QUnit.test("ExpressionRunner: apply custom converter, #8634", function(assert) {
const newConvertNumber = (originValue: any, numberValue: number): number => {
if(typeof originValue !== "string" || !originValue) return numberValue;
if(originValue.indexOf(",") < 0) return numberValue;
while(originValue.indexOf(",") > -1) {
originValue = originValue.replace(",", "");
}
return Helpers.getNumber(originValue);
};
const oldCallback = settings.convertNumber;
settings.convertNumber = newConvertNumber;

var runner = new ExpressionRunner("{a} + {b}");
const values: any = { a: "100,000", b: "10,000" };
assert.equal(runner.run(values), 110000, "apply custom convertr");

settings.convertNumber = oldCallback;
});
22 changes: 22 additions & 0 deletions tests/helperstests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,28 @@ QUnit.test("Helpers.getNumber", function(assert) {
true,
"0xbe0eb53f46cd790cd13851d5eff43d12404d33e8 is not a number"
);
assert.equal(Helpers.getNumber("0"), 0, "0 is a number");
assert.equal(Helpers.getNumber("00"), 0, "0 is a number");
assert.equal(Helpers.getNumber("0001"), 1, "0001 is a number");
assert.equal(Helpers.getNumber("0.1"), 0.1, "0.1 is a number");
assert.equal(Helpers.getNumber("0,1"), 0.1, "0,1 is a number");
assert.equal(Helpers.getNumber("0x10"), 16, "0x10 is a number");
});
QUnit.test("Helpers.getNumber & settings.convertNumber, #8634", function(assert) {
const newConvertNumber = (originValue: any, numberValue: number): number => {
if(typeof originValue !== "string" || !originValue) return numberValue;
if(originValue.indexOf(",") < 0) return numberValue;
while(originValue.indexOf(",") > -1) {
originValue = originValue.replace(",", "");
}
return Helpers.getNumber(originValue);
};
const oldCallback = settings.convertNumber;

assert.equal(isNaN(Helpers.getNumber("1,234,567")), true, "standard behavior");
settings.convertNumber = newConvertNumber;
assert.equal(Helpers.getNumber("1,234,567"), 1234567, "new behavior");
settings.convertNumber = oldCallback;
});
QUnit.test("Helpers.getNumberByIndex", function(assert) {
assert.equal(Helpers.getNumberByIndex(0, "1."), "1.", "0/1.");
Expand Down

0 comments on commit 59d9409

Please sign in to comment.