Skip to content

Commit fe24138

Browse files
committed
fix: e2e error
1 parent bc7313c commit fe24138

File tree

5 files changed

+40
-31
lines changed

5 files changed

+40
-31
lines changed

src/enum-collection.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,13 @@ export class EnumCollectionClass<
5353
* **CN:** 布尔值,表示这是一个枚举集合实例
5454
*/
5555
readonly [ENUM_COLLECTION] = true;
56-
readonly [Symbol.hasInstance] = function (this: EnumCollectionClass<T, K, V>, instance: unknown): boolean {
56+
[Symbol.hasInstance](this: EnumCollectionClass<T, K, V>, instance: unknown): boolean {
5757
// intentionally use == to support both number and string format value
5858
return this.items.some(
5959
// eslint-disable-next-line eqeqeq
6060
(i) => instance == i.value || instance === i.key
6161
);
62-
};
62+
}
6363

6464
constructor(init: T = {} as T, options?: EnumItemOptions) {
6565
super();

src/enum-item.ts

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,7 @@ export class EnumItemClass<
4242
*
4343
* @returns V | string
4444
*/
45-
readonly [Symbol.toPrimitive] = function (
46-
this: EnumItemClass<T, K, V>,
47-
hint: 'number' | 'string' | 'default'
48-
): V | string {
45+
[Symbol.toPrimitive](this: EnumItemClass<T, K, V>, hint: 'number' | 'string' | 'default'): V | string {
4946
if (hint === 'number') {
5047
// for cases like Number(value) or +value
5148
return this.valueOf();
@@ -55,7 +52,7 @@ export class EnumItemClass<
5552
}
5653
// for cases like '' + value, value == 1
5754
return this.valueOf();
58-
};
55+
}
5956

6057
private _options: EnumItemOptions | undefined;
6158
// should use function here to avoid closure. this is important for the e2e test cases.
@@ -67,12 +64,7 @@ export class EnumItemClass<
6764
return content;
6865
}
6966
private _readonlyPropMsg(name: string) {
70-
// Must use this array form, otherwise the legacy mode will break the e2e test cases after compilation
71-
return [
72-
'Cannot modify property',
73-
name,
74-
'on EnumItem. EnumItem instances are readonly and should not be mutated.',
75-
].join(' ');
67+
return `Cannot modify property "${name}" on EnumItem. EnumItem instances are readonly and should not be mutated.`;
7668
}
7769
private _localizedProxy = new Proxy(this, {
7870
get: (target, prop) => {

test/engines/playwright.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,17 @@ export class PlaywrightEngine extends TestEngineBase {
2323
): void {
2424
const serializedEvaluateParams = serializeJavascript({ ...evaluateContext, evaluateFn: evaluate });
2525

26-
test(`(es) ${name}`, async ({ page }) => {
27-
await page.goto('/modern.html', { waitUntil: 'domcontentloaded' });
28-
await page.waitForLoadState('domcontentloaded');
29-
await this.executeEvaluation({ page, assert, serializedEvaluateParams });
30-
});
31-
32-
// test(`(es-legacy) ${name}`, async ({ page }) => {
33-
// await page.goto('/legacy.html', { waitUntil: 'domcontentloaded' });
26+
// test(`(es) ${name}`, async ({ page }) => {
27+
// await page.goto('/modern.html', { waitUntil: 'domcontentloaded' });
3428
// await page.waitForLoadState('domcontentloaded');
3529
// await this.executeEvaluation({ page, assert, serializedEvaluateParams });
3630
// });
31+
32+
test(`(es-legacy) ${name}`, async ({ page }) => {
33+
await page.goto('/legacy.html', { waitUntil: 'domcontentloaded' });
34+
await page.waitForLoadState('domcontentloaded');
35+
await this.executeEvaluation({ page, assert, serializedEvaluateParams });
36+
});
3737
}
3838

3939
// eslint-disable-next-line @typescript-eslint/ban-types
@@ -86,7 +86,7 @@ export class PlaywrightEngine extends TestEngineBase {
8686
return serializedStr;
8787
}, serializedEvaluateParams);
8888

89-
const initialState = deserializeJavascript(resultStr);
89+
const initialState = deserializeJavascript(resultStr, { debug: true, prettyPrint: false });
9090
// Restore the lang to the Enum.localize
9191
setLang(initialState.lang, Enum, getLocales, defaultLocalize);
9292
if (!initialState.EnumLocalize) {

test/test-suites/enum-item.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,8 @@ const testEnumItem = (engine: TestEngineBase) => {
8686
({ localeEN, sunday, monday, tuesday, friday, saturday }) => {
8787
engine.expect(Number(sunday)).toBe(0);
8888
engine.expect(String(sunday)).toBe(localeEN.Sunday);
89-
// engine.expect(Boolean(sunday)).toBe(false);
90-
// engine.expect(Boolean(monday)).toBe(true);
89+
engine.expect(Boolean(sunday)).toBe(true);
90+
engine.expect(Boolean(monday)).toBe(true);
9191

9292
engine.expect(saturday > friday).toBeTruthy();
9393
engine.expect(monday < tuesday).toBeTruthy();

test/utils/serialize-javascript.ts

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
const TokenStart = '$SJS$';
2626
const TokenEnd = '$SJE$';
2727
const VariablePrefix = '$SJV$_';
28-
const SymbolKeyRegExps: [RegExp, RegExp] = [/\[Symbol\.\w+\]/, /\[Symbol\.for\('[^']+'\)\]/];
28+
const SymbolKeyRegExps: [RegExp, RegExp] = [/\[Symbol\.\w+\]/, /\[Symbol\.for\([\u0027\u0022].+?[\u0027\u0022]\)\]/];
2929
const SymbolKeyPrefixRegExp = /\[/;
3030
const SymbolKeySuffixRegExp = /\]/;
3131

@@ -138,7 +138,10 @@ function serializeJavascriptRecursively(obj: any, options: InternalSerializeOpti
138138
!funcStr.startsWith('async function*') &&
139139
!funcStr.replace(/\s/g, '').match(/^\(?[^)]+\)?=>/)
140140
) {
141-
funcStr = `function ${value}`;
141+
// If it's a computed property function, for example: { [Symbol.toPrimitive]() { return 1; } }
142+
// the funcStr is like: `[Symbol.toPrimitive]() { return 1; }`, so we can safely remove it.
143+
funcStr = funcStr.replace(/^\[[^\]]+\]/, '');
144+
funcStr = `function ${funcStr}`;
142145
}
143146
funcStr = funcStr.replace(/"/g, "'");
144147
return `${TS}(${funcStr})${TE}`;
@@ -224,20 +227,25 @@ export function deserializeJavascript(input: string, options?: DeserializeOption
224227
}
225228

226229
function directDeserialize(result: SerializedResult, options: InternalDeserializeOptions) {
227-
const { variablePrefix: VP, closure, get = getByPath, debug } = options ?? {};
230+
const { variablePrefix: VP, closure, get = getByPath, debug, prettyPrint = true } = options ?? {};
228231
const code = getDeserializeJavascriptCode(result, options);
229-
const printCode = getDeserializeJavascriptCode(result, { ...options, isPrint: true });
230232
if (debug) {
233+
const printSourceCode = getDeserializeJavascriptCode(result, { ...options, isPrint: true });
234+
const prettyPrintCode = `\`${printSourceCode.replace(/`/g, '\\`').replace(/\$\{/g, '\\${')}\``;
235+
const realCode = `'${printSourceCode.replace(/\n/g, '\\n').replace(/'/g, "\\'")}'`;
236+
const printCode = prettyPrint ? prettyPrintCode : realCode;
231237
console.log(
232238
'-------------- deserializeCode --------------\n',
233239
`${getByPath.toString()}
234-
new Function('${VP}context', '${VP}options', \`\n${printCode.replace(/`/g, '\\`').replace(/\$\{/g, '\\${')}\`)(${closure ? 'closure' : 'undefined'}, { get: getByPath });`,
235-
'closure=',
240+
new Function('${VP}context', '${VP}options', ${printCode})(${closure ? 'closure' : 'undefined'}, { get: getByPath });`,
241+
'closure =',
236242
closure
237243
);
238244
}
239245
try {
240-
const deserializeResult = new Function(`${VP}context`, `${VP}options`, code)(closure, { get });
246+
const deserializeResult = new Function(`${VP}context`, `${VP}options`, code)(closure, {
247+
get,
248+
});
241249
return deserializeResult;
242250
} catch (error) {
243251
console.error(error);
@@ -576,6 +584,15 @@ export type DeserializeOptions = Pick<SerializeOptions, 'tokenStart' | 'tokenEnd
576584
* functions which use some global variables or modules, it's a good idea to pass them here.
577585
*/
578586
closure?: Record<string, unknown>;
587+
/**
588+
* Whether to pretty print the deserialized object. Default is `true`.
589+
*
590+
* - `true`: Pretty print the deserialized code with indentation and new lines, which is more
591+
* readable, but may be a little different from the real execution code.
592+
* - `false` - Print the object in a single line, which is more compact and similar to the real
593+
* execution code.
594+
*/
595+
prettyPrint?: boolean;
579596
};
580597

581598
interface InternalDeserializeOptions extends DeserializeOptions {

0 commit comments

Comments
 (0)