@iamsergio/qttest-utils 2.1.1 โ†’ 2.2.1

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/Changelog CHANGED
@@ -2,6 +2,33 @@
2
2
 
3
3
 
4
4
 
5
+ ## [2.2.1] - 2024-05-02
6
+
7
+ ### ๐Ÿ› Bug Fixes
8
+
9
+ - Fix running non-Qt tests
10
+ - Harden code against exception when reading .tap file
11
+
12
+ ### ๐Ÿงช Testing
13
+
14
+ - Try fixing tests on macOS/Windows
15
+ - Try harder to fix macOS/Windows tests
16
+
17
+ ### โš™๏ธ Miscellaneous Tasks
18
+
19
+ - Ran code format on tests
20
+ - Run codeformat on qttest.ts
21
+
22
+ ## [2.2.0] - 2024-04-25
23
+
24
+ ### ๐Ÿš€ Features
25
+
26
+ - Allow to workaround microsoft/vscode-cmake-tools-api/issues/7
27
+
28
+ ### โš™๏ธ Miscellaneous Tasks
29
+
30
+ - Bump version
31
+
5
32
  ## [2.1.1] - 2024-04-25
6
33
 
7
34
  ### ๐Ÿ› Bug Fixes
@@ -11,6 +38,7 @@
11
38
  ### โš™๏ธ Miscellaneous Tasks
12
39
 
13
40
  - Improve CONTRIBUTING.md
41
+ - Bump version
14
42
 
15
43
  ## [2.1.0] - 2024-04-25
16
44
 
package/out/cmake.d.ts CHANGED
@@ -13,8 +13,9 @@ export declare class CMakeTests {
13
13
  */
14
14
  tests(): Promise<CMakeTest[] | undefined>;
15
15
  private ctestJsonToList;
16
- targetNameForExecutable(executable: string, codemodel: any): string | undefined;
17
- cppFilesForExecutable(executable: string, codemodel: any): string[];
16
+ targetNameForExecutable(executable: string, codemodel: any, workaround?: boolean): string | undefined;
17
+ filenamesAreEqual(file1: string, file2: string, workaround?: boolean): boolean;
18
+ cppFilesForExecutable(executable: string, codemodel: any, workaround?: boolean): string[];
18
19
  }
19
20
  export declare class CMakeTest {
20
21
  command: string[];
package/out/cmake.js CHANGED
@@ -74,13 +74,7 @@ class CMakeTests {
74
74
  }
75
75
  /// Returns the cmake target name for the specified executable
76
76
  /// codemodel should have a "projects" key at root.
77
- targetNameForExecutable(executable, codemodel) {
78
- // simplify:
79
- if (executable.endsWith(".exe")) {
80
- executable = executable.substring(0, executable.length - 4);
81
- }
82
- // replace backslashes with forward slashes
83
- executable = executable.replace(/\\/g, "/");
77
+ targetNameForExecutable(executable, codemodel, workaround = false) {
84
78
  let projects = codemodel["projects"];
85
79
  if (!projects)
86
80
  return undefined;
@@ -96,9 +90,7 @@ class CMakeTests {
96
90
  if (artifact.endsWith(".exe")) {
97
91
  artifact = artifact.substring(0, artifact.length - 4);
98
92
  }
99
- // replace backslashes with forward slashes
100
- artifact = artifact.replace(/\\/g, "/");
101
- if (artifact == executable) {
93
+ if (this.filenamesAreEqual(executable, artifact, workaround)) {
102
94
  let name = target["name"];
103
95
  if (name) {
104
96
  // We found the target name
@@ -110,16 +102,39 @@ class CMakeTests {
110
102
  }
111
103
  return undefined;
112
104
  }
105
+ /// Returns whether the two filenames are equal
106
+ /// If workaround is true, then we workaround microsoft/vscode-cmake-tools-api/issues/7 where
107
+ /// the basename is correct but the path is bogus, and we only compare the basenames
108
+ filenamesAreEqual(file1, file2, workaround = false) {
109
+ if (file1.endsWith(".exe"))
110
+ file1 = file1.substring(0, file1.length - 4);
111
+ if (file2.endsWith(".exe"))
112
+ file2 = file2.substring(0, file2.length - 4);
113
+ file1 = file1.replace(/\\/g, "/");
114
+ file2 = file2.replace(/\\/g, "/");
115
+ if (process.platform === "win32") {
116
+ file1 = file1.toLowerCase();
117
+ file2 = file2.toLowerCase();
118
+ }
119
+ if (file1 == file2)
120
+ return true;
121
+ if (!workaround) {
122
+ // files aren't equal!
123
+ return false;
124
+ }
125
+ const fs = require('fs');
126
+ if (fs.existsSync(file2)) {
127
+ // It's a real file, not bogus.
128
+ return false;
129
+ }
130
+ /// Compare only basename, since path is bogus
131
+ return path_1.default.basename(file1, ".exe") == path_1.default.basename(file2, ".exe");
132
+ }
113
133
  /// Returns the list of .cpp files for the specified executable
114
134
  /// codemodel is the CMake codemodel JSON object
115
135
  /// codemodel should have a "projects" key at root.
116
- cppFilesForExecutable(executable, codemodel) {
117
- // simplify:
118
- if (executable.endsWith(".exe")) {
119
- executable = executable.substring(0, executable.length - 4);
120
- }
121
- // replace backslashes with forward slashes
122
- executable = executable.replace(/\\/g, "/");
136
+ /// @param workaround If true, worksaround https://github.com/microsoft/vscode-cmake-tools-api/issues/7
137
+ cppFilesForExecutable(executable, codemodel, workaround = false) {
123
138
  let projects = codemodel["projects"];
124
139
  if (!projects)
125
140
  return [];
@@ -141,7 +156,7 @@ class CMakeTests {
141
156
  }
142
157
  // replace backslashes with forward slashes
143
158
  artifact = artifact.replace(/\\/g, "/");
144
- if (artifact == executable) {
159
+ if (this.filenamesAreEqual(executable, artifact, workaround)) {
145
160
  let fileGroups = target["fileGroups"];
146
161
  if (!fileGroups)
147
162
  continue;
package/out/qttest.js CHANGED
@@ -102,7 +102,9 @@ class QtTest {
102
102
  reject(new Error("qttest: File doesn't exit: " + this.filename));
103
103
  return;
104
104
  }
105
- const child = (0, child_process_1.spawn)(this.filename, ["-functions"], { cwd: this.buildDirPath });
105
+ const child = (0, child_process_1.spawn)(this.filename, ["-functions"], {
106
+ cwd: this.buildDirPath,
107
+ });
106
108
  child.stdout.on("data", (chunk) => {
107
109
  output += chunk.toString();
108
110
  });
@@ -112,8 +114,8 @@ class QtTest {
112
114
  child.on("exit", (code) => {
113
115
  if (code === 0) {
114
116
  slotNames = slotNames.concat(output.split("\n"));
115
- slotNames = slotNames.map(entry => entry.trim().replace("()", ""));
116
- slotNames = slotNames.filter(entry => entry.length > 0);
117
+ slotNames = slotNames.map((entry) => entry.trim().replace("()", ""));
118
+ slotNames = slotNames.filter((entry) => entry.length > 0);
117
119
  if (slotNames.length > 0) {
118
120
  this.slots = [];
119
121
  for (var slotName of slotNames) {
@@ -124,7 +126,12 @@ class QtTest {
124
126
  resolve(slotNames);
125
127
  }
126
128
  else {
127
- reject(new Error("qttest: Failed to run -functions, stdout=" + output + "; stderr=" + err + "; code=" + code));
129
+ reject(new Error("qttest: Failed to run -functions, stdout=" +
130
+ output +
131
+ "; stderr=" +
132
+ err +
133
+ "; code=" +
134
+ code));
128
135
  }
129
136
  });
130
137
  });
@@ -150,7 +157,8 @@ class QtTest {
150
157
  let result = false;
151
158
  child.stdout.on("data", (chunk) => {
152
159
  if (!result) {
153
- if (chunk.toString().includes("libQt5Test.so") || chunk.toString().includes("libQt6Test.so")) {
160
+ if (chunk.toString().includes("libQt5Test.so") ||
161
+ chunk.toString().includes("libQt6Test.so")) {
154
162
  result = true;
155
163
  }
156
164
  }
@@ -219,7 +227,12 @@ class QtTest {
219
227
  args = args.concat("-o").concat("-,txt");
220
228
  return yield new Promise((resolve, reject) => {
221
229
  let cwdDir = cwd.length > 0 ? cwd : this.buildDirPath;
222
- logMessage("Running " + this.filename + " " + args.join(" ") + " with cwd=" + cwdDir);
230
+ logMessage("Running " +
231
+ this.filename +
232
+ " " +
233
+ args.join(" ") +
234
+ " with cwd=" +
235
+ cwdDir);
223
236
  const child = (0, child_process_1.spawn)(this.filename, args, { cwd: cwdDir });
224
237
  if (this.outputFunc) {
225
238
  // Callers wants the process output:
@@ -239,9 +252,11 @@ class QtTest {
239
252
  if (!slot) {
240
253
  this.lastExitCode = code;
241
254
  }
242
- /// When running a QtTest executable, let's check which sub-tests failed
243
- /// (So VSCode can show some error icon for each fail)
244
- yield this.updateSubTestStates(cwdDir, slot);
255
+ if (this.slots && this.slots.length > 0) {
256
+ /// When running a QtTest executable, let's check which sub-tests failed
257
+ /// (So VSCode can show some error icon for each fail)
258
+ yield this.updateSubTestStates(cwdDir, slot);
259
+ }
245
260
  if (code === 0) {
246
261
  resolve(true);
247
262
  }
@@ -255,11 +270,11 @@ class QtTest {
255
270
  /// Using .tap so we don't have to use a separate XML library
256
271
  /// .tap is plain text and a single regexp can catch the failing tests and line number
257
272
  tapOutputFileName(slot) {
258
- let slotName = slot ? ("_" + slot.name) : "";
273
+ let slotName = slot ? "_" + slot.name : "";
259
274
  return this.label + slotName + ".tap";
260
275
  }
261
276
  txtOutputFileName(slot) {
262
- let slotName = slot ? ("_" + slot.name) : "";
277
+ let slotName = slot ? "_" + slot.name : "";
263
278
  return this.label + slotName + ".txt";
264
279
  }
265
280
  command() {
@@ -286,7 +301,7 @@ class QtTest {
286
301
  // at: MyTest::testF() (/some/path/qttest-utils/test/qt_test/test2.cpp:13)
287
302
  const pattern = /at:\s+(.+?)::(.+?)\(\)\s+\((.+?):(\d+)\)/gm;
288
303
  const matches = Array.from(data.matchAll(pattern));
289
- const failedResults = matches.map(match => ({
304
+ const failedResults = matches.map((match) => ({
290
305
  name: match[2],
291
306
  filePath: match[3],
292
307
  lineNumber: parseInt(match[4]),
@@ -332,7 +347,11 @@ class QtTestSlot {
332
347
  });
333
348
  }
334
349
  command() {
335
- return { label: this.name, executablePath: this.absoluteFilePath, args: [this.name] };
350
+ return {
351
+ label: this.name,
352
+ executablePath: this.absoluteFilePath,
353
+ args: [this.name],
354
+ };
336
355
  }
337
356
  }
338
357
  exports.QtTestSlot = QtTestSlot;
package/out/test.js CHANGED
@@ -23,19 +23,33 @@ function runTests(buildDirPath) {
23
23
  let expected_executables = [
24
24
  "test/qt_test/build-dev/test1",
25
25
  "test/qt_test/build-dev/test2",
26
- "test/qt_test/build-dev/test3"
26
+ "test/qt_test/build-dev/test3",
27
+ "test/qt_test/build-dev/non_qttest",
27
28
  ];
28
29
  if (qt.qtTestExecutables.length != expected_executables.length) {
29
30
  console.error("Expected 3 executables, got " + qt.qtTestExecutables.length);
30
31
  process.exit(1);
31
32
  }
32
33
  yield qt.removeNonLinking();
34
+ /// On macOS and Windows we don't have ldd or equivalent, so we can't check if the test links to QtTest
35
+ /// Use the help way instead
36
+ yield qt.removeByRunningHelp();
37
+ /// Remove the non-qttest executable from qt.qtTestExecutables
38
+ qt.qtTestExecutables = qt.qtTestExecutables.filter((e) => !e.filenameWithoutExtension().endsWith("non_qttest"));
39
+ if (qt.qtTestExecutables.length != 3) {
40
+ console.error("Expected 3 executables, at this point got " +
41
+ qt.qtTestExecutables.length);
42
+ process.exit(1);
43
+ }
33
44
  // 1. Test that the executable test names are correct:
34
45
  var i = 0;
35
46
  for (var executable of qt.qtTestExecutables) {
36
47
  let expected = expected_executables[i];
37
48
  if (executable.relativeFilename() != expected) {
38
- console.error("Expected executable " + expected + ", got " + executable.relativeFilename());
49
+ console.error("Expected executable " +
50
+ expected +
51
+ ", got " +
52
+ executable.relativeFilename());
39
53
  process.exit(1);
40
54
  }
41
55
  i++;
@@ -112,8 +126,8 @@ function runTests(buildDirPath) {
112
126
  }
113
127
  function runCodeModelTests(codeModelFile) {
114
128
  return __awaiter(this, void 0, void 0, function* () {
115
- const fs = require('fs');
116
- let codemodelStr = fs.readFileSync(codeModelFile, 'utf8');
129
+ const fs = require("fs");
130
+ let codemodelStr = fs.readFileSync(codeModelFile, "utf8");
117
131
  let codemodelJson = JSON.parse(codemodelStr);
118
132
  let cmake = new cmake_1.CMakeTests("random");
119
133
  let files = cmake.cppFilesForExecutable("/vscode-qttest/test/qt_test/build-dev/test1", codemodelJson);
@@ -143,7 +157,51 @@ function runCodeModelTests(codeModelFile) {
143
157
  console.error("Expected test2, got " + targetName);
144
158
  process.exit(1);
145
159
  }
160
+ // test workaround for microsoft/vscode-cmake-tools-api/issues/7
161
+ files = cmake.cppFilesForExecutable("/vscode-qttest/test/qt_test/build-dev/test3", codemodelJson,
162
+ /*workaround=*/ false);
163
+ if (files.length !== 0) {
164
+ console.error("Expected 0 files, got " + files.length);
165
+ process.exit(1);
166
+ }
167
+ files = cmake.cppFilesForExecutable("/vscode-qttest/test/qt_test/build-dev/test3", codemodelJson,
168
+ /*workaround=*/ true);
169
+ if (files.length !== 1) {
170
+ console.error("Expected 0 files, got " + files.length);
171
+ process.exit(1);
172
+ }
173
+ targetName = cmake.targetNameForExecutable("/vscode-qttest/test/qt_test/build-dev/test3", codemodelJson,
174
+ /*workaround=*/ false);
175
+ if (targetName) {
176
+ console.error("Expected null, got " + targetName);
177
+ process.exit(1);
178
+ }
179
+ targetName = cmake.targetNameForExecutable("/vscode-qttest/test/qt_test/build-dev/test3", codemodelJson,
180
+ /*workaround=*/ true);
181
+ if (targetName != "test3") {
182
+ console.error("Expected null, got " + targetName);
183
+ process.exit(1);
184
+ }
185
+ });
186
+ }
187
+ function runNonQtTest(buildDirPath) {
188
+ return __awaiter(this, void 0, void 0, function* () {
189
+ let qt = new qttest_1.QtTests();
190
+ yield qt.discoverViaCMake(buildDirPath);
191
+ var nonQtExecutable = undefined;
192
+ for (let executable of qt.qtTestExecutables) {
193
+ if (executable.filenameWithoutExtension().endsWith("non_qttest")) {
194
+ nonQtExecutable = executable;
195
+ break;
196
+ }
197
+ }
198
+ if (nonQtExecutable === undefined) {
199
+ console.error("Expected to find non-Qt test executable");
200
+ process.exit(1);
201
+ }
202
+ yield nonQtExecutable.runTest();
146
203
  });
147
204
  }
148
205
  runTests("test/qt_test/build-dev/");
206
+ runNonQtTest("test/qt_test/build-dev/");
149
207
  runCodeModelTests("test/test_cmake_codemodel.json");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iamsergio/qttest-utils",
3
- "version": "2.1.1",
3
+ "version": "2.2.1",
4
4
  "description": "API for listing QtTest executables from a build directory and which individual test slots each executable contains. Useful for a Text Explorer VSCode extension.",
5
5
  "repository": {
6
6
  "type": "git",