Skip to content

Commit 2386497

Browse files
committed
Fix variable uses list which wasn't including variable "0"'s uses in text fields
1 parent 1197d90 commit 2386497

File tree

5 files changed

+153
-17
lines changed

5 files changed

+153
-17
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
4949
- Fix issue where instanced prefabs were showing incorrect icons in actor select inputs
5050
- Fix issue preventing engine plugins stored in subfolders from being included in project
5151
- Fix bottom margins when using GB Printer [@untoxa](https://github.com/untoxa)
52+
- Fix variable uses list which wasn't including variable "0"'s uses in text fields
5253

5354
## [4.1.3] - 2024-09-16
5455

src/components/editors/VariableUses.worker.ts

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ import {
2828
} from "shared/lib/scripts/walk";
2929
import { variableInScriptValue } from "shared/lib/scriptValue/helpers";
3030
import { isScriptValue } from "shared/lib/scriptValue/types";
31+
import {
32+
variableInDialogueText,
33+
variableInExpressionText,
34+
} from "shared/lib/variables/variablesInText";
3135

3236
export type VariableUse = {
3337
id: string;
@@ -132,25 +136,11 @@ workerCtx.onmessage = async (evt) => {
132136
const allText = String(
133137
Array.isArray(argValue) ? argValue.join("|") : argValue
134138
);
135-
const textTokens = lexText(allText);
136-
if (
137-
textTokens.some(
138-
(token) =>
139-
token.type === "variable" &&
140-
token.variableId.replace(/^0+/, "") === variableId
141-
)
142-
) {
139+
if (variableInDialogueText(variableId, allText)) {
143140
return true;
144141
}
145142
} else if (field.type === "matharea" && typeof argValue === "string") {
146-
const expressionTokens = tokenizer(argValue);
147-
if (
148-
expressionTokens.some(
149-
(token) =>
150-
token.type === "VAR" &&
151-
token.symbol.replace(/\$/g, "").replace(/^0/g, "") === variableId
152-
)
153-
) {
143+
if (variableInExpressionText(variableId, argValue)) {
154144
return true;
155145
}
156146
}

src/shared/lib/compiler/lexText.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { fromSigned8Bit } from "shared/lib/helpers/8bit";
22

3-
type Token =
3+
export type Token =
44
| {
55
type: "text";
66
value: string;
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { lexText, Token as TextToken } from "shared/lib/compiler/lexText";
2+
import { Token as ExpressionToken } from "shared/lib/rpn/types";
3+
import tokenizer from "shared/lib/rpn/tokenizer";
4+
5+
/**
6+
* Extracts a variable ID from a dialogue token by removing any leading zeros.
7+
* @param {TextToken} token - The token to process, expected to be of type 'variable'.
8+
* @returns {string | undefined} - The variable ID without leading zeros, or undefined if the token is not of type 'variable'.
9+
*/
10+
export const dialogueTokenToVariableId = (token: TextToken) =>
11+
token.type === "variable" ? token.variableId.replace(/^0/, "") : undefined;
12+
13+
/**
14+
* Extracts a variable ID from an expression token by removing dollar signs and any leading zeros.
15+
* @param {ExpressionToken} token - The token to process, expected to be of type 'VAR'.
16+
* @returns {string | undefined} - The variable ID without '$' symbols or leading zeros, or undefined if the token is not of type 'VAR'.
17+
*/
18+
export const expressionTokenToVariableId = (token: ExpressionToken) =>
19+
token.type === "VAR" && token.symbol.replace(/\$/g, "").replace(/^0/g, "");
20+
21+
/**
22+
* Checks if a given variable ID exists in a dialogue text input.
23+
* @param {string} variableId - The ID of the variable to search for in the text (without leading zeros).
24+
* @param {string} input - The dialogue text input to search within.
25+
* @returns {boolean} - True if the variable ID is found in the text, false otherwise.
26+
*/
27+
export const variableInDialogueText = (
28+
variableId: string,
29+
input: string
30+
): boolean => {
31+
const textTokens = lexText(input);
32+
const isMatch = (token: TextToken) =>
33+
dialogueTokenToVariableId(token) === variableId;
34+
return textTokens.some(isMatch);
35+
};
36+
37+
/**
38+
* Checks if a given variable ID exists in an expression text input.
39+
* @param {string} variableId - The ID of the variable to search for in the expression (without leading zeros).
40+
* @param {string} input - The expression text input to search within.
41+
* @returns {boolean} - True if the variable ID is found in the expression, false otherwise.
42+
*/
43+
export const variableInExpressionText = (
44+
variableId: string,
45+
input: string
46+
): boolean => {
47+
const expressionTokens = tokenizer(input);
48+
const isMatch = (token: ExpressionToken) =>
49+
expressionTokenToVariableId(token) === variableId;
50+
return expressionTokens.some(isMatch);
51+
};
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import {
2+
dialogueTokenToVariableId,
3+
expressionTokenToVariableId,
4+
variableInDialogueText,
5+
variableInExpressionText,
6+
} from "shared/lib/variables/variablesInText";
7+
8+
describe("dialogueTokenToVariableId", () => {
9+
test("should return variable id without leading zero", () => {
10+
const token = { type: "variable", variableId: "01" } as const;
11+
expect(dialogueTokenToVariableId(token)).toBe("1");
12+
});
13+
14+
test("should return zero first first variable", () => {
15+
const token = { type: "variable", variableId: "00" } as const;
16+
expect(dialogueTokenToVariableId(token)).toBe("0");
17+
});
18+
19+
test("should not remove trailing zeros", () => {
20+
const token = { type: "variable", variableId: "500" } as const;
21+
expect(dialogueTokenToVariableId(token)).toBe("500");
22+
});
23+
});
24+
25+
describe("expressionTokenToVariableId", () => {
26+
test("should return variable id without leading zero", () => {
27+
const token = { type: "VAR", symbol: "$01$" } as const;
28+
expect(expressionTokenToVariableId(token)).toBe("1");
29+
});
30+
31+
test("should return zero first first variable", () => {
32+
const token = { type: "VAR", symbol: "$00$" } as const;
33+
expect(expressionTokenToVariableId(token)).toBe("0");
34+
});
35+
36+
test("should not remove trailing zeros", () => {
37+
const token = { type: "VAR", symbol: "$500$" } as const;
38+
expect(expressionTokenToVariableId(token)).toBe("500");
39+
});
40+
});
41+
42+
describe("variableInDialogueText", () => {
43+
test("should match when variable contains leading zero", () => {
44+
const text = "Value is $01$";
45+
expect(variableInDialogueText("1", text)).toBeTruthy();
46+
});
47+
48+
test("should match when variable contains is zero", () => {
49+
const text = "Value is $00$";
50+
expect(variableInDialogueText("0", text)).toBeTruthy();
51+
});
52+
53+
test("should match when variable contains trailing zeros", () => {
54+
const text = "Value is $500$";
55+
expect(variableInDialogueText("500", text)).toBeTruthy();
56+
});
57+
58+
test("should match when multiple variables are found", () => {
59+
const text = "Value is $01$ $02$ $03$";
60+
expect(variableInDialogueText("3", text)).toBeTruthy();
61+
});
62+
63+
test("should not match when variable isn't in text", () => {
64+
const text = "Value is $02$";
65+
expect(variableInDialogueText("3", text)).toBeFalsy();
66+
});
67+
});
68+
69+
describe("variableInExpressionText", () => {
70+
test("should match when variable contains leading zero", () => {
71+
const text = "5 + $01$";
72+
expect(variableInExpressionText("1", text)).toBeTruthy();
73+
});
74+
75+
test("should match when variable contains is zero", () => {
76+
const text = "5 + $00$";
77+
expect(variableInExpressionText("0", text)).toBeTruthy();
78+
});
79+
80+
test("should match when variable contains trailing zeros", () => {
81+
const text = "5 + $500$";
82+
expect(variableInExpressionText("500", text)).toBeTruthy();
83+
});
84+
85+
test("should match when multiple variables are found", () => {
86+
const text = "$01$ + $02$ - $03$";
87+
expect(variableInExpressionText("3", text)).toBeTruthy();
88+
});
89+
90+
test("should not match when variable isn't in text", () => {
91+
const text = "5 + $02$";
92+
expect(variableInExpressionText("3", text)).toBeFalsy();
93+
});
94+
});

0 commit comments

Comments
 (0)