Skip to content

Commit 5b9289d

Browse files
authored
fix(negativeNumbers): convert negative literal numbers to unary expression with minus token (#1580)
1 parent b03d1cb commit 5b9289d

File tree

8 files changed

+617
-606
lines changed

8 files changed

+617
-606
lines changed

package-lock.json

Lines changed: 560 additions & 595 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@
9292
"ts-node": "^10.9.2",
9393
"ts-patch": "^3.1.1",
9494
"tsconfig-paths": "4.2.0",
95-
"typescript": "^5.3.3",
95+
"typescript": "^5.4.5",
9696
"webpack": "^5.89.0",
9797
"webpack-cli": "^5.1.4",
9898
"webpack-merge": "^5.10.0",

src/transformer/descriptor/enum/enumDeclaration.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { RandomPropertyAccessor } from '../random/random';
44
import { IsTsAutoMockRandomEnabled } from '../../../options/random';
55
import {
66
createCall,
7-
createNumericLiteral,
7+
createExpressionForNegativeOrPositiveNumber,
88
createStringLiteral,
99
} from '../../../typescriptFactory/typescriptFactory';
1010

@@ -34,7 +34,7 @@ function getEnumMemberValue(
3434
typeChecker.getConstantValue(member) || defaultValue;
3535

3636
if (typeof value === 'number') {
37-
return createNumericLiteral(value);
37+
return createExpressionForNegativeOrPositiveNumber(value);
3838
}
3939

4040
return createStringLiteral(value);

src/transformer/descriptor/literal/literal.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import { Scope } from '../../scope/scope';
33
import { core } from '../../core/core';
44
import { GetDescriptor } from '../descriptor';
55
import {
6+
createExpressionForNegativeOrPositiveNumber,
67
createLiteral,
7-
createNumericLiteral,
88
createStringLiteral,
99
} from '../../../typescriptFactory/typescriptFactory';
1010

@@ -27,15 +27,15 @@ export function GetLiteralDescriptor(
2727

2828
function GetLiteralTokenDescriptor(
2929
node: ts.LiteralTypeNode,
30-
): ts.StringLiteral | ts.NumericLiteral {
30+
): ts.StringLiteral | ts.Expression {
3131
// eslint-disable-next-line @typescript-eslint/no-explicit-any
3232
const nodeToken: any = node as any;
3333

3434
if (nodeToken.kind === core.ts.SyntaxKind.NumericLiteral) {
35-
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
36-
return createNumericLiteral(parseInt(nodeToken.text, 10));
35+
return createExpressionForNegativeOrPositiveNumber(
36+
parseInt(nodeToken.text, 10),
37+
);
3738
}
3839

39-
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
4040
return createStringLiteral(nodeToken.text);
4141
}

src/typescriptFactory/typescriptFactory.ts

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import type {
3333
ParameterDeclaration,
3434
PostfixUnaryExpression,
3535
PostfixUnaryOperator,
36+
PrefixUnaryOperator,
3637
PrefixUnaryExpression,
3738
PrivateIdentifier,
3839
PropertyAccessExpression,
@@ -92,6 +93,26 @@ export function createNumericLiteral(
9293
return core.ts.factory.createNumericLiteral(value, numericLiteralFlags);
9394
}
9495

96+
export function createExpressionForNegativeOrPositiveNumber(
97+
value: number,
98+
): Expression {
99+
if (value < 0) {
100+
return createPrefixUnaryExpression(
101+
core.ts.SyntaxKind.MinusToken,
102+
createNumericLiteral(Math.abs(value)),
103+
);
104+
}
105+
106+
return createNumericLiteral(value);
107+
}
108+
109+
export function createPrefixUnaryExpression(
110+
unaryOperator: PrefixUnaryOperator,
111+
operand: Expression,
112+
): Expression {
113+
return core.ts.factory.createPrefixUnaryExpression(unaryOperator, operand);
114+
}
115+
95116
export function createArrowFunction(
96117
block: ts.ConciseBody,
97118
parameter: ReadonlyArray<ts.ParameterDeclaration> = [],
@@ -298,13 +319,13 @@ export function createLogicalNot(operand: Expression): PrefixUnaryExpression {
298319

299320
export function createLiteral(
300321
type: LiteralType,
301-
): StringLiteral | NumericLiteral | BigIntLiteral {
322+
): StringLiteral | Expression | BigIntLiteral {
302323
if (typeof type.value === 'string') {
303324
return createStringLiteral(type.value);
304325
}
305326

306327
if (typeof type.value === 'number') {
307-
return createNumericLiteral(type.value);
328+
return createExpressionForNegativeOrPositiveNumber(type.value);
308329
}
309330

310331
return core.ts.factory.createBigIntLiteral(type.value);

test/transformer/descriptor/enum.test.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ describe('for enum', () => {
1515
Right = 1,
1616
Left = 3,
1717
}
18+
1819
interface Interface {
1920
a: Direction;
2021
b: DirectionAssign;
@@ -55,3 +56,21 @@ describe('for enum with constant computed values', () => {
5556
expect(properties.a).toEqual(2);
5657
});
5758
});
59+
60+
describe('for enum with negative values', () => {
61+
it('should assign the values', () => {
62+
enum AssignmentWithNegatives {
63+
Negative1 = -4,
64+
Positive = 1,
65+
Negative2 = -7,
66+
}
67+
68+
interface Interface {
69+
enum: AssignmentWithNegatives;
70+
}
71+
72+
const properties: Interface = createMock<Interface>();
73+
74+
expect(properties.enum).toEqual(-4);
75+
});
76+
});

test/transformer/descriptor/literal/literal.test.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
TypeUnionTokenAllBoolean,
99
TypeUnionTokenNumber,
1010
TypeUnionTokenSameBoolean,
11+
TypeUnionWithNegatives,
1112
} from '../utils/types/typeUnion';
1213
import { getObjectKeyValues } from '../../utilities/getObjectKeyValues';
1314

@@ -26,22 +27,26 @@ describe('for literal', () => {
2627
describe('with a specific number', () => {
2728
interface Interface {
2829
a: 2;
30+
b: -3;
2931
}
3032

31-
it('should set null', () => {
33+
it('should set the number', () => {
3234
const properties: Interface = createMock<Interface>();
3335
expect(properties.a).toBe(2);
36+
expect(properties.b).toBe(-3);
3437
});
3538
});
3639

3740
describe('with import', () => {
3841
interface Interface {
3942
literal: TypeUnion;
43+
literalWithNegatives: TypeUnionWithNegatives;
4044
}
4145

4246
it('should set the first one', () => {
4347
const properties: Interface = createMock<Interface>();
4448
expect(properties.literal).toBe('1');
49+
expect(properties.literalWithNegatives).toBe(-1);
4550
});
4651
});
4752

test/transformer/descriptor/utils/types/typeUnion.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export type TypeUnion = '1' | '2' | 'a' | 'b';
2+
export type TypeUnionWithNegatives = -1 | -2 | 3 | 2;
23
export type TypeUnionToken = 'a' | 'b';
34
export type TypeUnionTokenNumber = 1 | 1;
45
export type TypeUnionTokenSameBoolean = true | true;

0 commit comments

Comments
 (0)