@lvce-editor/test-worker 14.15.0 → 14.17.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.
@@ -533,7 +533,7 @@ const execute$2 = (command, ...args) => {
533
533
 
534
534
  const Two$1 = '2.0';
535
535
  const callbacks$1 = Object.create(null);
536
- const get$2 = id => {
536
+ const get$3 = id => {
537
537
  return callbacks$1[id];
538
538
  };
539
539
  const remove$2 = id => {
@@ -682,7 +682,7 @@ const warn = (...args) => {
682
682
  console.warn(...args);
683
683
  };
684
684
  const resolve$1 = (id, response) => {
685
- const fn = get$2(id);
685
+ const fn = get$3(id);
686
686
  if (!fn) {
687
687
  console.log(response);
688
688
  warn(`callback ${id} may already be disposed`);
@@ -1091,10 +1091,10 @@ const createMockRpc = ({
1091
1091
  };
1092
1092
 
1093
1093
  const rpcs = Object.create(null);
1094
- const set$4 = (id, rpc) => {
1094
+ const set$5 = (id, rpc) => {
1095
1095
  rpcs[id] = rpc;
1096
1096
  };
1097
- const get$1 = id => {
1097
+ const get$2 = id => {
1098
1098
  return rpcs[id];
1099
1099
  };
1100
1100
  const remove$1 = id => {
@@ -1105,18 +1105,18 @@ const remove$1 = id => {
1105
1105
  const create = rpcId => {
1106
1106
  return {
1107
1107
  async dispose() {
1108
- const rpc = get$1(rpcId);
1108
+ const rpc = get$2(rpcId);
1109
1109
  await rpc.dispose();
1110
1110
  },
1111
1111
  // @ts-ignore
1112
1112
  invoke(method, ...params) {
1113
- const rpc = get$1(rpcId);
1113
+ const rpc = get$2(rpcId);
1114
1114
  // @ts-ignore
1115
1115
  return rpc.invoke(method, ...params);
1116
1116
  },
1117
1117
  // @ts-ignore
1118
1118
  invokeAndTransfer(method, ...params) {
1119
- const rpc = get$1(rpcId);
1119
+ const rpc = get$2(rpcId);
1120
1120
  // @ts-ignore
1121
1121
  return rpc.invokeAndTransfer(method, ...params);
1122
1122
  },
@@ -1124,7 +1124,7 @@ const create = rpcId => {
1124
1124
  const mockRpc = createMockRpc({
1125
1125
  commandMap
1126
1126
  });
1127
- set$4(rpcId, mockRpc);
1127
+ set$5(rpcId, mockRpc);
1128
1128
  // @ts-ignore
1129
1129
  mockRpc[Symbol.dispose] = () => {
1130
1130
  remove$1(rpcId);
@@ -1133,7 +1133,7 @@ const create = rpcId => {
1133
1133
  return mockRpc;
1134
1134
  },
1135
1135
  set(rpc) {
1136
- set$4(rpcId, rpc);
1136
+ set$5(rpcId, rpc);
1137
1137
  }
1138
1138
  };
1139
1139
  };
@@ -1152,18 +1152,18 @@ const TestWorker = 9001;
1152
1152
 
1153
1153
  const {
1154
1154
  invoke: invoke$2,
1155
- set: set$3
1155
+ set: set$4
1156
1156
  } = create(EditorWorker);
1157
1157
 
1158
1158
  const {
1159
1159
  invoke: invoke$1,
1160
- set: set$2
1160
+ set: set$3
1161
1161
  } = create(OpenerWorker);
1162
1162
 
1163
1163
  const {
1164
1164
  invoke,
1165
1165
  invokeAndTransfer,
1166
- set: set$1
1166
+ set: set$2
1167
1167
  } = create(RendererWorker);
1168
1168
  const sendMessagePortToEditorWorker = async (port, rpcId) => {
1169
1169
  const command = 'HandleMessagePort.handleMessagePort';
@@ -1188,7 +1188,7 @@ const initializeEditorWorker = async () => {
1188
1188
  commandMap: {},
1189
1189
  send: send$1
1190
1190
  });
1191
- set$3(rpc);
1191
+ set$4(rpc);
1192
1192
  };
1193
1193
 
1194
1194
  const send = async port => {
@@ -1199,7 +1199,18 @@ const initializeOpenerWorker = async () => {
1199
1199
  commandMap: {},
1200
1200
  send
1201
1201
  });
1202
- set$2(rpc);
1202
+ set$3(rpc);
1203
+ };
1204
+
1205
+ let autoFixError;
1206
+ const get$1 = () => {
1207
+ return autoFixError;
1208
+ };
1209
+ const set$1 = value => {
1210
+ autoFixError = value;
1211
+ };
1212
+ const clear$3 = () => {
1213
+ autoFixError = undefined;
1203
1214
  };
1204
1215
 
1205
1216
  class AssertionError extends Error {
@@ -3527,7 +3538,7 @@ const ExtensionSearch = {
3527
3538
 
3528
3539
  const Memfs = 'memfs';
3529
3540
 
3530
- const toFileUrl = url => {
3541
+ const toFileUrl$1 = url => {
3531
3542
  const urlObject = new URL(url);
3532
3543
  const pathName = urlObject.pathname;
3533
3544
  if (!pathName.startsWith('/remote')) {
@@ -3551,7 +3562,7 @@ const getDirents = async fileUrl => {
3551
3562
  return allDirents;
3552
3563
  };
3553
3564
  const getFileMapNode = async url => {
3554
- const fileUrl = toFileUrl(url);
3565
+ const fileUrl = toFileUrl$1(url);
3555
3566
  const allFiles = await getDirents(fileUrl);
3556
3567
  const fileMap = Object.create(null);
3557
3568
  const contents = await Promise.all(allFiles.map(filePath => {
@@ -4879,6 +4890,22 @@ const formatDuration = duration => {
4879
4890
  const Fail = 'fail';
4880
4891
  const Pass = 'pass';
4881
4892
 
4893
+ const getAutoFixProperties = error => {
4894
+ const isChatDebugPayloadError = error instanceof ChatDebugShouldHavePayloadError && error.actualPayload !== undefined;
4895
+ const autoFixProperties = isChatDebugPayloadError ? {
4896
+ autoFixError: {
4897
+ actualPayload: error.actualPayload,
4898
+ code: error.code,
4899
+ expectedPayload: error.expectedPayload
4900
+ },
4901
+ overlayActions: [{
4902
+ command: 'Test.tryAutoFix',
4903
+ id: 'chat-debug-should-have-payload-autofix',
4904
+ label: 'Autofix'
4905
+ }]
4906
+ } : {};
4907
+ return autoFixProperties;
4908
+ };
4882
4909
  const executeTest2 = async (name, fn, globals, timestampGenerator) => {
4883
4910
  const getTimestamp = timestampGenerator;
4884
4911
  const start = getTimestamp();
@@ -4887,6 +4914,7 @@ const executeTest2 = async (name, fn, globals, timestampGenerator) => {
4887
4914
  const duration = end - start;
4888
4915
  const formattedDuration = formatDuration(duration);
4889
4916
  if (error) {
4917
+ const autoFixProperties = getAutoFixProperties(error);
4890
4918
  return {
4891
4919
  background: 'red',
4892
4920
  duration,
@@ -4894,6 +4922,7 @@ const executeTest2 = async (name, fn, globals, timestampGenerator) => {
4894
4922
  error,
4895
4923
  formattedDuration,
4896
4924
  name,
4925
+ ...autoFixProperties,
4897
4926
  start,
4898
4927
  text: `test failed: ${error}`,
4899
4928
  type: Fail
@@ -4931,18 +4960,25 @@ const now = () => {
4931
4960
 
4932
4961
  const executeTest = async (name, fn, globals = {}) => {
4933
4962
  const {
4963
+ autoFixError,
4934
4964
  background,
4935
4965
  error,
4936
4966
  formattedDuration,
4967
+ overlayActions,
4937
4968
  text,
4938
4969
  type
4939
4970
  } = await executeTest2(name, fn, globals, now);
4971
+ set$1(autoFixError);
4940
4972
  if (error) {
4941
4973
  await printTestError(error);
4942
4974
  } else {
4943
4975
  // eslint-disable-next-line no-console
4944
4976
  console.info(`PASS ${name} in ${formattedDuration}`);
4945
4977
  }
4978
+ if (overlayActions && overlayActions.length > 0) {
4979
+ await invoke('TestFrameWork.showOverlay', type, background, text, overlayActions);
4980
+ return;
4981
+ }
4946
4982
  await invoke('TestFrameWork.showOverlay', type, background, text);
4947
4983
  };
4948
4984
 
@@ -5034,6 +5070,7 @@ const execute = async (href, platform, assetDir) => {
5034
5070
  }
5035
5071
  // TODO maybe setup file watcher earlier, to not miss events?
5036
5072
  } catch (error) {
5073
+ clear$3();
5037
5074
  await printTestError(error);
5038
5075
  await invoke('TestFrameWork.showOverlay', Fail, 'red', `test failed: ${error}`);
5039
5076
  return;
@@ -5118,17 +5155,152 @@ const handleFileWatcherEvent = async event => {
5118
5155
  await hotReloadTest(lastItem, locationHref, time);
5119
5156
  };
5120
5157
 
5158
+ const whitespaceRegex = /\s+/g;
5159
+ const shouldHavePayloadRegex = /shouldHavePayload\(([^)]*)\)/gs;
5160
+ const normalizeWhitespace = value => {
5161
+ return value.replaceAll(whitespaceRegex, '');
5162
+ };
5163
+ const trySerialize = value => {
5164
+ try {
5165
+ return JSON.stringify(value, null, 2);
5166
+ } catch {
5167
+ return undefined;
5168
+ }
5169
+ };
5170
+ const replaceMatch = (fileContent, index, length, replacement) => {
5171
+ const before = fileContent.slice(0, index);
5172
+ const after = fileContent.slice(index + length);
5173
+ return `${before}${replacement}${after}`;
5174
+ };
5175
+ const replaceShouldHavePayload = (fileContent, expectedPayload, actualPayload) => {
5176
+ const serializedActual = trySerialize(actualPayload);
5177
+ if (!serializedActual) {
5178
+ return undefined;
5179
+ }
5180
+ const matches = [...fileContent.matchAll(shouldHavePayloadRegex)];
5181
+ if (matches.length === 0) {
5182
+ return undefined;
5183
+ }
5184
+ if (matches.length === 1) {
5185
+ const [match] = matches;
5186
+ if (typeof match.index !== 'number') {
5187
+ return undefined;
5188
+ }
5189
+ return replaceMatch(fileContent, match.index, match[0].length, `shouldHavePayload(${serializedActual})`);
5190
+ }
5191
+ const serializedExpected = trySerialize(expectedPayload);
5192
+ if (!serializedExpected) {
5193
+ return undefined;
5194
+ }
5195
+ const normalizedExpected = normalizeWhitespace(serializedExpected);
5196
+ const matchingCandidates = [];
5197
+ for (const match of matches) {
5198
+ const currentArgument = match[1];
5199
+ if (normalizeWhitespace(currentArgument) === normalizedExpected) {
5200
+ matchingCandidates.push(match);
5201
+ }
5202
+ }
5203
+ if (matchingCandidates.length !== 1) {
5204
+ return undefined;
5205
+ }
5206
+ const [candidate] = matchingCandidates;
5207
+ if (typeof candidate.index !== 'number') {
5208
+ return undefined;
5209
+ }
5210
+ return replaceMatch(fileContent, candidate.index, candidate[0].length, `shouldHavePayload(${serializedActual})`);
5211
+ };
5212
+ const getFileUrlFromRemotePath = rawPathName => {
5213
+ if (!rawPathName.startsWith('/remote')) {
5214
+ return undefined;
5215
+ }
5216
+ const rest = rawPathName.slice('/remote'.length);
5217
+ return `file://${rest}`;
5218
+ };
5219
+ const toFileUrl = (url, locationHref) => {
5220
+ const parsedUrl = new URL(url, locationHref);
5221
+ if (parsedUrl.protocol === 'file:') {
5222
+ parsedUrl.hash = '';
5223
+ parsedUrl.search = '';
5224
+ return parsedUrl.toString();
5225
+ }
5226
+ return getFileUrlFromRemotePath(parsedUrl.pathname);
5227
+ };
5228
+ const isAutoFixError = value => {
5229
+ if (!value) {
5230
+ return false;
5231
+ }
5232
+ return value.code === 'chat-debug.should-have-payload';
5233
+ };
5234
+ const defaultDependencies = {
5235
+ getAutoFixError() {
5236
+ return get$1();
5237
+ },
5238
+ getLatestTestInfo() {
5239
+ return maybeLast();
5240
+ },
5241
+ getLocationHref() {
5242
+ return location.href;
5243
+ },
5244
+ now: Date.now,
5245
+ readFile(uri) {
5246
+ return readFile(uri);
5247
+ },
5248
+ rerun(url, platform, assetDir) {
5249
+ return execute(url, platform, assetDir);
5250
+ },
5251
+ setAutoFixError(value) {
5252
+ set$1(value);
5253
+ },
5254
+ writeFile(uri, content) {
5255
+ return writeFile(uri, content);
5256
+ }
5257
+ };
5258
+ const tryAutoFixWith = async dependencies => {
5259
+ const latestTestInfo = dependencies.getLatestTestInfo();
5260
+ if (!latestTestInfo) {
5261
+ return;
5262
+ }
5263
+ if (latestTestInfo.inProgress) {
5264
+ return;
5265
+ }
5266
+ const autoFixError = dependencies.getAutoFixError();
5267
+ if (!isAutoFixError(autoFixError)) {
5268
+ return;
5269
+ }
5270
+ if (autoFixError.actualPayload === undefined) {
5271
+ return;
5272
+ }
5273
+ const locationHref = dependencies.getLocationHref();
5274
+ const fileUrl = toFileUrl(latestTestInfo.url, locationHref);
5275
+ if (!fileUrl) {
5276
+ return;
5277
+ }
5278
+ const fileContent = await dependencies.readFile(fileUrl);
5279
+ const updatedFileContent = replaceShouldHavePayload(fileContent, autoFixError.expectedPayload, autoFixError.actualPayload);
5280
+ if (!updatedFileContent || updatedFileContent === fileContent) {
5281
+ return;
5282
+ }
5283
+ await dependencies.writeFile(fileUrl, updatedFileContent);
5284
+ dependencies.setAutoFixError(undefined);
5285
+ const rerunUrl = createUrlWithQueryParameter(latestTestInfo.url, locationHref, dependencies.now());
5286
+ await dependencies.rerun(rerunUrl, latestTestInfo.platform, latestTestInfo.assetDir);
5287
+ };
5288
+ const tryAutoFix = async () => {
5289
+ await tryAutoFixWith(defaultDependencies);
5290
+ };
5291
+
5121
5292
  const commandMap = {
5122
5293
  'FileWatcher.handleEvent': handleFileWatcherEvent,
5123
5294
  'Test.execute': execute,
5124
- 'Test.executeMock': executeMock
5295
+ 'Test.executeMock': executeMock,
5296
+ 'Test.tryAutoFix': tryAutoFix
5125
5297
  };
5126
5298
 
5127
5299
  const initializeRendererWorker = async () => {
5128
5300
  const rpc = await create$1({
5129
5301
  commandMap: commandMap
5130
5302
  });
5131
- set$1(rpc);
5303
+ set$2(rpc);
5132
5304
  };
5133
5305
 
5134
5306
  const listen = async () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/test-worker",
3
- "version": "14.15.0",
3
+ "version": "14.17.0",
4
4
  "description": "Test Worker",
5
5
  "repository": {
6
6
  "type": "git",