@lvce-editor/test-worker 15.1.0 → 15.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api.d.ts +1 -0
- package/dist/testWorkerMain.js +141 -130
- package/package.json +1 -1
package/dist/api.d.ts
CHANGED
|
@@ -672,6 +672,7 @@ interface Git {
|
|
|
672
672
|
readonly pull: (remote: string, branch: string) => Promise<void>;
|
|
673
673
|
readonly push: (remote: string, branch: string) => Promise<void>;
|
|
674
674
|
readonly setConfig: (key: string, value: string) => Promise<void>;
|
|
675
|
+
readonly shouldHaveCommit: (message: string) => Promise<void>;
|
|
675
676
|
readonly shouldHaveInvocations: (invocations: readonly GitInvocation[]) => Promise<void>;
|
|
676
677
|
readonly status: () => Promise<unknown>;
|
|
677
678
|
}
|
package/dist/testWorkerMain.js
CHANGED
|
@@ -3801,7 +3801,9 @@ const remove = async uri => {
|
|
|
3801
3801
|
const getTmpDirFileScheme = async () => {
|
|
3802
3802
|
const tmpFolder = await invoke('PlatformPaths.getTmpDir');
|
|
3803
3803
|
const tmpUri = tmpFolder.startsWith('file://') ? tmpFolder : `file://${tmpFolder}`;
|
|
3804
|
-
|
|
3804
|
+
const uri = `${tmpUri}/test-${Date.now()}`;
|
|
3805
|
+
await mkdir(uri);
|
|
3806
|
+
return uri;
|
|
3805
3807
|
};
|
|
3806
3808
|
const getTmpDir = async ({
|
|
3807
3809
|
scheme = Memfs
|
|
@@ -3979,6 +3981,21 @@ const addRemote = async (name, remoteUrl) => {
|
|
|
3979
3981
|
const setConfig = async (key, value) => {
|
|
3980
3982
|
await invoke('ExtensionHost.executeCommand', 'git.setConfig', key, value);
|
|
3981
3983
|
};
|
|
3984
|
+
const shouldHaveCommit = async message => {
|
|
3985
|
+
const commits = await invoke('ExtensionHost.executeCommand', 'git.getCommits');
|
|
3986
|
+
if (!Array.isArray(commits)) {
|
|
3987
|
+
throw new TypeError(`Expected commits to be an array, but got ${commits}`);
|
|
3988
|
+
}
|
|
3989
|
+
if (commits.length !== 1) {
|
|
3990
|
+
throw new Error(`Expected 1 commit, but got ${commits.length}`);
|
|
3991
|
+
}
|
|
3992
|
+
if (!commits[0].hash) {
|
|
3993
|
+
throw new Error('Expected commit hash to be defined');
|
|
3994
|
+
}
|
|
3995
|
+
if (commits[0].message !== message) {
|
|
3996
|
+
throw new Error(`Expected commit message to be "${message}", but got "${commits[0].message}"`);
|
|
3997
|
+
}
|
|
3998
|
+
};
|
|
3982
3999
|
const shouldHaveInvocations = async invocations => {
|
|
3983
4000
|
// TODO
|
|
3984
4001
|
};
|
|
@@ -3995,6 +4012,7 @@ const Git = {
|
|
|
3995
4012
|
pull,
|
|
3996
4013
|
push: push$1,
|
|
3997
4014
|
setConfig,
|
|
4015
|
+
shouldHaveCommit,
|
|
3998
4016
|
shouldHaveInvocations,
|
|
3999
4017
|
status
|
|
4000
4018
|
};
|
|
@@ -5354,96 +5372,13 @@ const handleFileWatcherEvent = async event => {
|
|
|
5354
5372
|
await hotReloadTest(lastItem, locationHref, time);
|
|
5355
5373
|
};
|
|
5356
5374
|
|
|
5357
|
-
const
|
|
5358
|
-
|
|
5359
|
-
|
|
5360
|
-
const normalizeWhitespace = value => {
|
|
5361
|
-
return value.replaceAll(whitespaceRegex, '');
|
|
5362
|
-
};
|
|
5363
|
-
const isObject = value => {
|
|
5364
|
-
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
5365
|
-
};
|
|
5366
|
-
const projectActualOntoExpected = (actualValue, expectedValue) => {
|
|
5367
|
-
if (Array.isArray(expectedValue)) {
|
|
5368
|
-
if (!Array.isArray(actualValue)) {
|
|
5369
|
-
return actualValue;
|
|
5370
|
-
}
|
|
5371
|
-
const length = Math.min(expectedValue.length, actualValue.length);
|
|
5372
|
-
return actualValue.slice(0, length).map((item, index) => projectActualOntoExpected(item, expectedValue[index]));
|
|
5373
|
-
}
|
|
5374
|
-
if (isObject(expectedValue)) {
|
|
5375
|
-
if (!isObject(actualValue)) {
|
|
5376
|
-
return actualValue;
|
|
5377
|
-
}
|
|
5378
|
-
const result = {};
|
|
5379
|
-
for (const key of Object.keys(expectedValue)) {
|
|
5380
|
-
if (!Object.hasOwn(actualValue, key)) {
|
|
5381
|
-
continue;
|
|
5382
|
-
}
|
|
5383
|
-
result[key] = projectActualOntoExpected(actualValue[key], expectedValue[key]);
|
|
5384
|
-
}
|
|
5385
|
-
return result;
|
|
5386
|
-
}
|
|
5387
|
-
return actualValue;
|
|
5388
|
-
};
|
|
5389
|
-
const quoteString = value => {
|
|
5390
|
-
return `'${value.replaceAll('\\', '\\\\').replaceAll("'", "\\'").replaceAll('\n', '\\n').replaceAll('\r', '\\r').replaceAll('\t', '\\t')}'`;
|
|
5391
|
-
};
|
|
5392
|
-
const formatObjectKey = key => {
|
|
5393
|
-
if (validIdentifierRegex.test(key)) {
|
|
5394
|
-
return key;
|
|
5395
|
-
}
|
|
5396
|
-
return quoteString(key);
|
|
5397
|
-
};
|
|
5398
|
-
const trySerialize = (value, indent = 0) => {
|
|
5399
|
-
try {
|
|
5400
|
-
if (value === null) {
|
|
5401
|
-
return 'null';
|
|
5402
|
-
}
|
|
5403
|
-
if (typeof value === 'string') {
|
|
5404
|
-
return quoteString(value);
|
|
5405
|
-
}
|
|
5406
|
-
if (typeof value === 'number' || typeof value === 'boolean') {
|
|
5407
|
-
return JSON.stringify(value);
|
|
5408
|
-
}
|
|
5409
|
-
if (Array.isArray(value)) {
|
|
5410
|
-
if (value.length === 0) {
|
|
5411
|
-
return '[]';
|
|
5412
|
-
}
|
|
5413
|
-
const nextIndent = indent + 2;
|
|
5414
|
-
const serializedItems = value.map(item => `${' '.repeat(nextIndent)}${trySerialize(item, nextIndent)}`);
|
|
5415
|
-
return `[
|
|
5416
|
-
${serializedItems.join(',\n')}
|
|
5417
|
-
${' '.repeat(indent)}]`;
|
|
5418
|
-
}
|
|
5419
|
-
if (isObject(value)) {
|
|
5420
|
-
const entries = Object.entries(value);
|
|
5421
|
-
if (entries.length === 0) {
|
|
5422
|
-
return '{}';
|
|
5423
|
-
}
|
|
5424
|
-
const nextIndent = indent + 2;
|
|
5425
|
-
const serializedEntries = [];
|
|
5426
|
-
for (const entry of entries) {
|
|
5427
|
-
const [key, item] = entry;
|
|
5428
|
-
serializedEntries.push(`${' '.repeat(nextIndent)}${formatObjectKey(key)}: ${trySerialize(item, nextIndent)}`);
|
|
5429
|
-
}
|
|
5430
|
-
return `{
|
|
5431
|
-
${serializedEntries.join(',\n')}
|
|
5432
|
-
${' '.repeat(indent)}}`;
|
|
5433
|
-
}
|
|
5434
|
-
return undefined;
|
|
5435
|
-
} catch {
|
|
5436
|
-
return undefined;
|
|
5375
|
+
const isAutoFixError = value => {
|
|
5376
|
+
if (!value) {
|
|
5377
|
+
return false;
|
|
5437
5378
|
}
|
|
5379
|
+
return value.code === 'chat-debug.should-have-payload';
|
|
5438
5380
|
};
|
|
5439
|
-
|
|
5440
|
-
const before = fileContent.slice(0, index);
|
|
5441
|
-
const after = fileContent.slice(index + length);
|
|
5442
|
-
return `${before}${replacement}${after}`;
|
|
5443
|
-
};
|
|
5444
|
-
const isStringDelimiter = character => {
|
|
5445
|
-
return character === "'" || character === '"' || character === '`';
|
|
5446
|
-
};
|
|
5381
|
+
|
|
5447
5382
|
const consumeComment = (inBlockComment, inLineComment, character, nextCharacter) => {
|
|
5448
5383
|
if (inLineComment) {
|
|
5449
5384
|
if (character === '\n') {
|
|
@@ -5493,6 +5428,11 @@ const consumeComment = (inBlockComment, inLineComment, character, nextCharacter)
|
|
|
5493
5428
|
inLineComment
|
|
5494
5429
|
};
|
|
5495
5430
|
};
|
|
5431
|
+
|
|
5432
|
+
const isStringDelimiter = character => {
|
|
5433
|
+
return character === "'" || character === '"' || character === '`';
|
|
5434
|
+
};
|
|
5435
|
+
|
|
5496
5436
|
const consumeString = (stringDelimiter, character) => {
|
|
5497
5437
|
if (!stringDelimiter) {
|
|
5498
5438
|
if (isStringDelimiter(character)) {
|
|
@@ -5523,6 +5463,7 @@ const consumeString = (stringDelimiter, character) => {
|
|
|
5523
5463
|
stringDelimiter
|
|
5524
5464
|
};
|
|
5525
5465
|
};
|
|
5466
|
+
|
|
5526
5467
|
const findClosingParenthesis = (fileContent, startIndex) => {
|
|
5527
5468
|
let depth = 1;
|
|
5528
5469
|
let inBlockComment = false;
|
|
@@ -5568,6 +5509,8 @@ const findClosingParenthesis = (fileContent, startIndex) => {
|
|
|
5568
5509
|
}
|
|
5569
5510
|
return -1;
|
|
5570
5511
|
};
|
|
5512
|
+
|
|
5513
|
+
const shouldHavePayloadSearch = 'shouldHavePayload(';
|
|
5571
5514
|
const findShouldHavePayloadMatches = fileContent => {
|
|
5572
5515
|
const matches = [];
|
|
5573
5516
|
let searchIndex = 0;
|
|
@@ -5590,6 +5533,101 @@ const findShouldHavePayloadMatches = fileContent => {
|
|
|
5590
5533
|
}
|
|
5591
5534
|
return matches;
|
|
5592
5535
|
};
|
|
5536
|
+
|
|
5537
|
+
const whitespaceRegex = /\s+/g;
|
|
5538
|
+
const trailingCommaRegex = /,([}\]])/g;
|
|
5539
|
+
const normalizeWhitespace = value => {
|
|
5540
|
+
return value.replaceAll(whitespaceRegex, '').replaceAll(trailingCommaRegex, '$1');
|
|
5541
|
+
};
|
|
5542
|
+
|
|
5543
|
+
const isObject = value => {
|
|
5544
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
5545
|
+
};
|
|
5546
|
+
|
|
5547
|
+
const projectActualOntoExpected = (actualValue, expectedValue) => {
|
|
5548
|
+
if (Array.isArray(expectedValue)) {
|
|
5549
|
+
if (!Array.isArray(actualValue)) {
|
|
5550
|
+
return actualValue;
|
|
5551
|
+
}
|
|
5552
|
+
const length = Math.min(expectedValue.length, actualValue.length);
|
|
5553
|
+
return actualValue.slice(0, length).map((item, index) => projectActualOntoExpected(item, expectedValue[index]));
|
|
5554
|
+
}
|
|
5555
|
+
if (isObject(expectedValue)) {
|
|
5556
|
+
if (!isObject(actualValue)) {
|
|
5557
|
+
return actualValue;
|
|
5558
|
+
}
|
|
5559
|
+
const result = {};
|
|
5560
|
+
for (const key of Object.keys(expectedValue)) {
|
|
5561
|
+
if (!Object.hasOwn(actualValue, key)) {
|
|
5562
|
+
continue;
|
|
5563
|
+
}
|
|
5564
|
+
result[key] = projectActualOntoExpected(actualValue[key], expectedValue[key]);
|
|
5565
|
+
}
|
|
5566
|
+
return result;
|
|
5567
|
+
}
|
|
5568
|
+
return actualValue;
|
|
5569
|
+
};
|
|
5570
|
+
|
|
5571
|
+
const replaceMatch = (fileContent, index, length, replacement) => {
|
|
5572
|
+
const before = fileContent.slice(0, index);
|
|
5573
|
+
const after = fileContent.slice(index + length);
|
|
5574
|
+
return `${before}${replacement}${after}`;
|
|
5575
|
+
};
|
|
5576
|
+
|
|
5577
|
+
const quoteString = value => {
|
|
5578
|
+
return `'${value.replaceAll('\\', '\\\\').replaceAll("'", "\\'").replaceAll('\n', '\\n').replaceAll('\r', '\\r').replaceAll('\t', '\\t')}'`;
|
|
5579
|
+
};
|
|
5580
|
+
|
|
5581
|
+
const validIdentifierRegex = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
|
|
5582
|
+
const formatObjectKey = key => {
|
|
5583
|
+
if (validIdentifierRegex.test(key)) {
|
|
5584
|
+
return key;
|
|
5585
|
+
}
|
|
5586
|
+
return quoteString(key);
|
|
5587
|
+
};
|
|
5588
|
+
|
|
5589
|
+
const trySerialize = (value, indent = 0) => {
|
|
5590
|
+
try {
|
|
5591
|
+
if (value === null) {
|
|
5592
|
+
return 'null';
|
|
5593
|
+
}
|
|
5594
|
+
if (typeof value === 'string') {
|
|
5595
|
+
return quoteString(value);
|
|
5596
|
+
}
|
|
5597
|
+
if (typeof value === 'number' || typeof value === 'boolean') {
|
|
5598
|
+
return JSON.stringify(value);
|
|
5599
|
+
}
|
|
5600
|
+
if (Array.isArray(value)) {
|
|
5601
|
+
if (value.length === 0) {
|
|
5602
|
+
return '[]';
|
|
5603
|
+
}
|
|
5604
|
+
const nextIndent = indent + 2;
|
|
5605
|
+
const serializedItems = value.map(item => `${' '.repeat(nextIndent)}${trySerialize(item, nextIndent)}`);
|
|
5606
|
+
return `[
|
|
5607
|
+
${serializedItems.join(',\n')}
|
|
5608
|
+
${' '.repeat(indent)}]`;
|
|
5609
|
+
}
|
|
5610
|
+
if (isObject(value)) {
|
|
5611
|
+
const entries = Object.entries(value);
|
|
5612
|
+
if (entries.length === 0) {
|
|
5613
|
+
return '{}';
|
|
5614
|
+
}
|
|
5615
|
+
const nextIndent = indent + 2;
|
|
5616
|
+
const serializedEntries = [];
|
|
5617
|
+
for (const entry of entries) {
|
|
5618
|
+
const [key, item] = entry;
|
|
5619
|
+
serializedEntries.push(`${' '.repeat(nextIndent)}${formatObjectKey(key)}: ${trySerialize(item, nextIndent)}`);
|
|
5620
|
+
}
|
|
5621
|
+
return `{
|
|
5622
|
+
${serializedEntries.join(',\n')}
|
|
5623
|
+
${' '.repeat(indent)}}`;
|
|
5624
|
+
}
|
|
5625
|
+
return undefined;
|
|
5626
|
+
} catch {
|
|
5627
|
+
return undefined;
|
|
5628
|
+
}
|
|
5629
|
+
};
|
|
5630
|
+
|
|
5593
5631
|
const replaceShouldHavePayload = (fileContent, expectedPayload, actualPayload) => {
|
|
5594
5632
|
const minimalPayload = projectActualOntoExpected(actualPayload, expectedPayload);
|
|
5595
5633
|
const serializedMinimalPayload = trySerialize(minimalPayload);
|
|
@@ -5621,6 +5659,7 @@ const replaceShouldHavePayload = (fileContent, expectedPayload, actualPayload) =
|
|
|
5621
5659
|
const [candidate] = matchingCandidates;
|
|
5622
5660
|
return replaceMatch(fileContent, candidate.index, candidate.length, `shouldHavePayload(${serializedMinimalPayload})`);
|
|
5623
5661
|
};
|
|
5662
|
+
|
|
5624
5663
|
const getFileUrlFromRemotePath = rawPathName => {
|
|
5625
5664
|
if (!rawPathName.startsWith('/remote')) {
|
|
5626
5665
|
return undefined;
|
|
@@ -5628,6 +5667,7 @@ const getFileUrlFromRemotePath = rawPathName => {
|
|
|
5628
5667
|
const rest = rawPathName.slice('/remote'.length);
|
|
5629
5668
|
return `file://${rest}`;
|
|
5630
5669
|
};
|
|
5670
|
+
|
|
5631
5671
|
const toFileUrl = (url, locationHref) => {
|
|
5632
5672
|
const parsedUrl = new URL(url, locationHref);
|
|
5633
5673
|
if (parsedUrl.protocol === 'file:') {
|
|
@@ -5637,68 +5677,39 @@ const toFileUrl = (url, locationHref) => {
|
|
|
5637
5677
|
}
|
|
5638
5678
|
return getFileUrlFromRemotePath(parsedUrl.pathname);
|
|
5639
5679
|
};
|
|
5640
|
-
|
|
5641
|
-
|
|
5642
|
-
|
|
5643
|
-
}
|
|
5644
|
-
return value.code === 'chat-debug.should-have-payload';
|
|
5645
|
-
};
|
|
5646
|
-
const defaultDependencies = {
|
|
5647
|
-
getAutoFixError() {
|
|
5648
|
-
return get$1();
|
|
5649
|
-
},
|
|
5650
|
-
getLatestTestInfo() {
|
|
5651
|
-
return maybeLast();
|
|
5652
|
-
},
|
|
5653
|
-
getLocationHref() {
|
|
5654
|
-
return location.href;
|
|
5655
|
-
},
|
|
5656
|
-
now: Date.now,
|
|
5657
|
-
readFile(uri) {
|
|
5658
|
-
return readFile(uri);
|
|
5659
|
-
},
|
|
5660
|
-
rerun(url, platform, assetDir) {
|
|
5661
|
-
return execute(url, platform, assetDir);
|
|
5662
|
-
},
|
|
5663
|
-
setAutoFixError(value) {
|
|
5664
|
-
set$1(value);
|
|
5665
|
-
},
|
|
5666
|
-
writeFile(uri, content) {
|
|
5667
|
-
return writeFile(uri, content);
|
|
5668
|
-
}
|
|
5669
|
-
};
|
|
5670
|
-
const tryAutoFixWith = async dependencies => {
|
|
5671
|
-
const latestTestInfo = dependencies.getLatestTestInfo();
|
|
5680
|
+
|
|
5681
|
+
const tryAutoFixWith = async () => {
|
|
5682
|
+
const latestTestInfo = maybeLast();
|
|
5672
5683
|
if (!latestTestInfo) {
|
|
5673
5684
|
return;
|
|
5674
5685
|
}
|
|
5675
5686
|
if (latestTestInfo.inProgress) {
|
|
5676
5687
|
return;
|
|
5677
5688
|
}
|
|
5678
|
-
const autoFixError =
|
|
5689
|
+
const autoFixError = get$1();
|
|
5679
5690
|
if (!isAutoFixError(autoFixError)) {
|
|
5680
5691
|
return;
|
|
5681
5692
|
}
|
|
5682
5693
|
if (autoFixError.actualPayload === undefined) {
|
|
5683
5694
|
return;
|
|
5684
5695
|
}
|
|
5685
|
-
const
|
|
5686
|
-
const fileUrl = toFileUrl(latestTestInfo.url, locationHref);
|
|
5696
|
+
const fileUrl = toFileUrl(latestTestInfo.url, location.href);
|
|
5687
5697
|
if (!fileUrl) {
|
|
5688
5698
|
return;
|
|
5689
5699
|
}
|
|
5690
|
-
const fileContent = await
|
|
5700
|
+
const fileContent = await readFile(fileUrl);
|
|
5691
5701
|
const updatedFileContent = replaceShouldHavePayload(fileContent, autoFixError.expectedPayload, autoFixError.actualPayload);
|
|
5692
5702
|
if (!updatedFileContent || updatedFileContent === fileContent) {
|
|
5693
5703
|
return;
|
|
5694
5704
|
}
|
|
5695
|
-
await
|
|
5696
|
-
|
|
5697
|
-
const rerunUrl = createUrlWithQueryParameter(latestTestInfo.url,
|
|
5698
|
-
await
|
|
5705
|
+
await writeFile(fileUrl, updatedFileContent);
|
|
5706
|
+
set$1(undefined);
|
|
5707
|
+
const rerunUrl = createUrlWithQueryParameter(latestTestInfo.url, location.href, Date.now());
|
|
5708
|
+
await execute(rerunUrl, latestTestInfo.platform, latestTestInfo.assetDir);
|
|
5699
5709
|
};
|
|
5710
|
+
|
|
5700
5711
|
const tryAutoFix = async () => {
|
|
5701
|
-
await tryAutoFixWith(
|
|
5712
|
+
await tryAutoFixWith();
|
|
5702
5713
|
};
|
|
5703
5714
|
|
|
5704
5715
|
const commandMap = {
|