@iamsergio/qttest-utils 0.4.3 → 0.4.5

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/out/cmake.d.ts ADDED
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Represents tests added in cmake (Via add_test())
3
+ *
4
+ * Contains methods to discover Qt Tests via CMake
5
+ */
6
+ export declare class CMakeTests {
7
+ readonly buildDirPath: string;
8
+ constructor(buildDirPath: string);
9
+ /**
10
+ * Invokes ctest.exe --show-only=json-v1
11
+ *
12
+ * @returns a promise with the list of tests
13
+ */
14
+ tests(): Promise<CMakeTest[] | undefined>;
15
+ private ctestJsonToList;
16
+ }
17
+ export declare class CMakeTest {
18
+ command: string[];
19
+ cwd: string;
20
+ id(): string;
21
+ label(): string;
22
+ executablePath(): string;
23
+ }
package/out/cmake.js ADDED
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ // SPDX-FileCopyrightText: 2023 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
3
+ // Author: Sergio Martins <sergio.martins@kdab.com>
4
+ // SPDX-License-Identifier: MIT
5
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
6
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
7
+ return new (P || (P = Promise))(function (resolve, reject) {
8
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
9
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
10
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
11
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
12
+ });
13
+ };
14
+ var __importDefault = (this && this.__importDefault) || function (mod) {
15
+ return (mod && mod.__esModule) ? mod : { "default": mod };
16
+ };
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.CMakeTest = exports.CMakeTests = void 0;
19
+ const child_process_1 = require("child_process");
20
+ const path_1 = __importDefault(require("path"));
21
+ /**
22
+ * Represents tests added in cmake (Via add_test())
23
+ *
24
+ * Contains methods to discover Qt Tests via CMake
25
+ */
26
+ class CMakeTests {
27
+ constructor(buildDirPath) {
28
+ this.buildDirPath = buildDirPath;
29
+ }
30
+ /**
31
+ * Invokes ctest.exe --show-only=json-v1
32
+ *
33
+ * @returns a promise with the list of tests
34
+ */
35
+ tests() {
36
+ return __awaiter(this, void 0, void 0, function* () {
37
+ // TODO: Check if folder exists
38
+ if (this.buildDirPath.length == 0) {
39
+ console.error("Could not find out cmake build dir");
40
+ return undefined;
41
+ }
42
+ return new Promise((resolve, reject) => {
43
+ const child = (0, child_process_1.spawn)("ctest", ["--show-only=json-v1"], { "cwd": this.buildDirPath });
44
+ let output = "";
45
+ child.stdout.on("data", (chunk) => {
46
+ output += chunk.toString();
47
+ });
48
+ child.on("exit", (code) => {
49
+ if (code === 0) {
50
+ resolve(this.ctestJsonToList(output));
51
+ }
52
+ else {
53
+ reject(new Error("Failed to run ctest"));
54
+ }
55
+ });
56
+ return undefined;
57
+ });
58
+ });
59
+ }
60
+ ctestJsonToList(json) {
61
+ let allJSON = JSON.parse(json);
62
+ if (!("tests" in allJSON)) {
63
+ return [];
64
+ }
65
+ let tests = allJSON.tests.map((testJSON) => {
66
+ let test = new CMakeTest();
67
+ test.command = testJSON.command;
68
+ test.cwd = testJSON.cwd;
69
+ return test;
70
+ });
71
+ return tests;
72
+ }
73
+ }
74
+ exports.CMakeTests = CMakeTests;
75
+ /// Represents an inividual CTest test
76
+ class CMakeTest {
77
+ constructor() {
78
+ this.command = [];
79
+ this.cwd = "";
80
+ }
81
+ id() {
82
+ return this.command.join(",");
83
+ }
84
+ label() {
85
+ return path_1.default.basename(this.executablePath());
86
+ }
87
+ executablePath() {
88
+ return this.command[0];
89
+ }
90
+ }
91
+ exports.CMakeTest = CMakeTest;
@@ -0,0 +1 @@
1
+ export {};
package/out/example.js ADDED
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ // SPDX-FileCopyrightText: 2023 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
3
+ // Author: Sergio Martins <sergio.martins@kdab.com>
4
+ // SPDX-License-Identifier: MIT
5
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
6
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
7
+ return new (P || (P = Promise))(function (resolve, reject) {
8
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
9
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
10
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
11
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
12
+ });
13
+ };
14
+ var __importDefault = (this && this.__importDefault) || function (mod) {
15
+ return (mod && mod.__esModule) ? mod : { "default": mod };
16
+ };
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ const qttest_1 = require("./qttest");
19
+ const fs_1 = __importDefault(require("fs"));
20
+ function example() {
21
+ return __awaiter(this, void 0, void 0, function* () {
22
+ const args = process.argv.slice(2);
23
+ if (args.length != 1) {
24
+ console.error("ERROR: Expected a single argument with the build-dir with cmake tests!");
25
+ process.exit(2);
26
+ }
27
+ let buildDirPath = args[0];
28
+ if (!fs_1.default.existsSync(buildDirPath)) {
29
+ console.error('Directory does not exist!');
30
+ process.exit(1);
31
+ }
32
+ let qt = new qttest_1.QtTests();
33
+ // Gather all tests that would be executed by CTest:
34
+ yield qt.discoverViaCMake(buildDirPath);
35
+ // Filter-out the ones that don't link to QtTest (doctests and such)
36
+ yield qt.removeNonLinking();
37
+ // Example of filtering out by regexp:
38
+ qt.removeMatching(/(tst_view|tst_window)/);
39
+ // Example of filtering out by regexp (inverted):
40
+ qt.maintainMatching(/(tst_docks|tst_qtwidgets|tst_multisplitter)/);
41
+ qt.dumpExecutablePaths();
42
+ qt.dumpTestSlots();
43
+ });
44
+ }
45
+ example();
package/out/index.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ import { CMakeTests, CMakeTest } from "./cmake";
2
+ import { QtTests, QtTest, QtTestSlot } from "./qttest";
3
+ declare const qttest: {
4
+ QtTests: typeof QtTests;
5
+ QtTest: typeof QtTest;
6
+ QtTestSlot: typeof QtTestSlot;
7
+ CMakeTests: typeof CMakeTests;
8
+ CMakeTest: typeof CMakeTest;
9
+ };
10
+ export default qttest;
package/out/index.js ADDED
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ // SPDX-FileCopyrightText: 2023 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
3
+ // Author: Sergio Martins <sergio.martins@kdab.com>
4
+ // SPDX-License-Identifier: MIT
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const cmake_1 = require("./cmake");
7
+ const qttest_1 = require("./qttest");
8
+ const qttest = {
9
+ QtTests: qttest_1.QtTests, QtTest: qttest_1.QtTest, QtTestSlot: qttest_1.QtTestSlot, CMakeTests: cmake_1.CMakeTests, CMakeTest: cmake_1.CMakeTest
10
+ };
11
+ exports.default = qttest;
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Represents a single QtTest executable.
3
+ * Supports listing the individual test slots
4
+ */
5
+ export declare class QtTest {
6
+ readonly filename: string;
7
+ readonly buildDirPath: string;
8
+ vscodeTestItem: any | undefined;
9
+ slots: QtTestSlot[] | null;
10
+ constructor(filename: string, buildDirPath: string);
11
+ get id(): string;
12
+ get label(): string;
13
+ /**
14
+ * Calls "./yourqttest -functions" and stores the results in the slots property.
15
+ */
16
+ parseAvailableSlots(): Promise<void>;
17
+ /**
18
+ * Returns whether this executable links to libQtTest.so.
19
+ *
20
+ * Useful for Qt autodetection, as some tests are doctest or so.
21
+ *
22
+ * Only implemented for Linux. Returns undefined on other platforms.
23
+ */
24
+ linksToQtTestLib(): Promise<boolean> | undefined;
25
+ isQtTestViaHelp(): Promise<boolean | undefined>;
26
+ runTest(slotName?: string, cwd?: string): Promise<boolean>;
27
+ command(): {
28
+ label: string;
29
+ executablePath: string;
30
+ args: string[];
31
+ };
32
+ }
33
+ /**
34
+ * Represents a single Qt test slot
35
+ */
36
+ export declare class QtTestSlot {
37
+ name: string;
38
+ parentQTest: QtTest;
39
+ vscodeTestItem: any | undefined;
40
+ constructor(name: string, parent: QtTest);
41
+ get id(): string;
42
+ get absoluteFilePath(): string;
43
+ runTest(): Promise<boolean>;
44
+ command(): {
45
+ label: string;
46
+ executablePath: string;
47
+ args: string[];
48
+ };
49
+ }
50
+ /**
51
+ * Represents the list of all QtTest executables in your project
52
+ */
53
+ export declare class QtTests {
54
+ qtTestExecutables: QtTest[];
55
+ discoverViaCMake(buildDirPath: string): Promise<void>;
56
+ removeNonLinking(): Promise<void>;
57
+ removeByRunningHelp(): Promise<void>;
58
+ removeMatching(regex: RegExp): void;
59
+ maintainMatching(regex: RegExp): void;
60
+ dumpExecutablePaths(): void;
61
+ dumpTestSlots(): Promise<void>;
62
+ }
package/out/qttest.js ADDED
@@ -0,0 +1,291 @@
1
+ "use strict";
2
+ // SPDX-FileCopyrightText: 2023 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
3
+ // Author: Sergio Martins <sergio.martins@kdab.com>
4
+ // SPDX-License-Identifier: MIT
5
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ var desc = Object.getOwnPropertyDescriptor(m, k);
8
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
+ desc = { enumerable: true, get: function() { return m[k]; } };
10
+ }
11
+ Object.defineProperty(o, k2, desc);
12
+ }) : (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ o[k2] = m[k];
15
+ }));
16
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
17
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
18
+ }) : function(o, v) {
19
+ o["default"] = v;
20
+ });
21
+ var __importStar = (this && this.__importStar) || function (mod) {
22
+ if (mod && mod.__esModule) return mod;
23
+ var result = {};
24
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
25
+ __setModuleDefault(result, mod);
26
+ return result;
27
+ };
28
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
29
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
30
+ return new (P || (P = Promise))(function (resolve, reject) {
31
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
32
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
33
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
34
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
35
+ });
36
+ };
37
+ var __importDefault = (this && this.__importDefault) || function (mod) {
38
+ return (mod && mod.__esModule) ? mod : { "default": mod };
39
+ };
40
+ Object.defineProperty(exports, "__esModule", { value: true });
41
+ exports.QtTests = exports.QtTestSlot = exports.QtTest = void 0;
42
+ const child_process_1 = require("child_process");
43
+ const path_1 = __importDefault(require("path"));
44
+ const fs = __importStar(require("fs"));
45
+ const cmake_1 = require("./cmake");
46
+ /**
47
+ * Represents a single QtTest executable.
48
+ * Supports listing the individual test slots
49
+ */
50
+ class QtTest {
51
+ constructor(filename, buildDirPath) {
52
+ this.slots = null;
53
+ this.filename = filename;
54
+ this.buildDirPath = buildDirPath;
55
+ }
56
+ get id() {
57
+ return this.filename;
58
+ }
59
+ get label() {
60
+ return path_1.default.basename(this.filename);
61
+ }
62
+ /**
63
+ * Calls "./yourqttest -functions" and stores the results in the slots property.
64
+ */
65
+ parseAvailableSlots() {
66
+ return __awaiter(this, void 0, void 0, function* () {
67
+ let slotNames = [];
68
+ let output = "";
69
+ let err = "";
70
+ yield new Promise((resolve, reject) => {
71
+ if (!fs.existsSync(this.filename)) {
72
+ reject(new Error("File doesn't exit: " + this.filename));
73
+ return;
74
+ }
75
+ const child = (0, child_process_1.spawn)(this.filename, ["-functions"], { cwd: this.buildDirPath });
76
+ child.stdout.on("data", (chunk) => {
77
+ output += chunk.toString();
78
+ });
79
+ child.stderr.on("data", (chunk) => {
80
+ err += chunk.toString();
81
+ });
82
+ child.on("exit", (code) => {
83
+ if (code === 0) {
84
+ slotNames = slotNames.concat(output.split("\n"));
85
+ slotNames = slotNames.map(entry => entry.trim().replace("()", ""));
86
+ slotNames = slotNames.filter(entry => entry.length > 0);
87
+ if (slotNames.length > 0) {
88
+ this.slots = [];
89
+ for (var slotName of slotNames) {
90
+ var slot = new QtTestSlot(slotName, this);
91
+ this.slots.push(slot);
92
+ }
93
+ }
94
+ resolve(slotNames);
95
+ }
96
+ else {
97
+ reject(new Error("Failed to run -functions, stdout=" + output + "; stderr=" + err + "; code=" + code));
98
+ }
99
+ });
100
+ });
101
+ });
102
+ }
103
+ /**
104
+ * Returns whether this executable links to libQtTest.so.
105
+ *
106
+ * Useful for Qt autodetection, as some tests are doctest or so.
107
+ *
108
+ * Only implemented for Linux. Returns undefined on other platforms.
109
+ */
110
+ linksToQtTestLib() {
111
+ let isLinux = process.platform === "linux";
112
+ if (!isLinux) {
113
+ return undefined;
114
+ }
115
+ return new Promise((resolve, reject) => {
116
+ const child = (0, child_process_1.spawn)("ldd", [this.filename]);
117
+ let output = "";
118
+ let result = false;
119
+ child.stdout.on("data", (chunk) => {
120
+ if (!result) {
121
+ if (chunk.toString().includes("libQt5Test.so") || chunk.toString().includes("libQt6Test.so")) {
122
+ result = true;
123
+ }
124
+ }
125
+ });
126
+ child.on("exit", (code) => {
127
+ if (code === 0) {
128
+ resolve(result);
129
+ }
130
+ else {
131
+ reject(new Error("Failed to run ldd"));
132
+ }
133
+ });
134
+ });
135
+ }
136
+ /// Returns whether this test is a QtTest by running it with -help and checking if the help text looks familiar
137
+ /// Note that if this is not a QtTest it might not run help and instead execute the test itself
138
+ isQtTestViaHelp() {
139
+ return __awaiter(this, void 0, void 0, function* () {
140
+ return yield new Promise((resolve, reject) => {
141
+ const child = (0, child_process_1.spawn)(this.filename, ["-help"]);
142
+ let output = "";
143
+ let result = false;
144
+ child.stdout.on("data", (chunk) => {
145
+ if (!result) {
146
+ if (chunk.toString().includes("[testfunction[:testdata]]")) {
147
+ result = true;
148
+ }
149
+ }
150
+ });
151
+ child.on("exit", (code) => {
152
+ if (code === 0) {
153
+ resolve(result);
154
+ }
155
+ else {
156
+ resolve(false);
157
+ }
158
+ });
159
+ });
160
+ });
161
+ }
162
+ /// Runs this test
163
+ runTest(slotName, cwd = "") {
164
+ return __awaiter(this, void 0, void 0, function* () {
165
+ let args = [];
166
+ if (slotName) {
167
+ // Runs a single Qt test instead
168
+ args = args.concat(slotName);
169
+ }
170
+ return yield new Promise((resolve, reject) => {
171
+ let opts = cwd.length > 0 ? { cwd: cwd } : { cwd: this.buildDirPath };
172
+ const child = (0, child_process_1.spawn)(this.filename, args, opts);
173
+ child.stdout.on("data", (chunk) => {
174
+ // chunk.toString()
175
+ });
176
+ child.on("exit", (code) => {
177
+ if (code === 0) {
178
+ resolve(true);
179
+ }
180
+ else {
181
+ resolve(false);
182
+ }
183
+ });
184
+ });
185
+ });
186
+ }
187
+ command() {
188
+ return { label: this.label, executablePath: this.filename, args: [] };
189
+ }
190
+ }
191
+ exports.QtTest = QtTest;
192
+ /**
193
+ * Represents a single Qt test slot
194
+ */
195
+ class QtTestSlot {
196
+ constructor(name, parent) {
197
+ this.name = name;
198
+ this.parentQTest = parent;
199
+ }
200
+ get id() {
201
+ return this.parentQTest.filename + this.name;
202
+ }
203
+ get absoluteFilePath() {
204
+ return this.parentQTest.filename;
205
+ }
206
+ runTest() {
207
+ return __awaiter(this, void 0, void 0, function* () {
208
+ return this.parentQTest.runTest(this.name);
209
+ });
210
+ }
211
+ command() {
212
+ return { label: this.name, executablePath: this.absoluteFilePath, args: [this.name] };
213
+ }
214
+ }
215
+ exports.QtTestSlot = QtTestSlot;
216
+ /**
217
+ * Represents the list of all QtTest executables in your project
218
+ */
219
+ class QtTests {
220
+ constructor() {
221
+ this.qtTestExecutables = [];
222
+ }
223
+ discoverViaCMake(buildDirPath) {
224
+ return __awaiter(this, void 0, void 0, function* () {
225
+ var cmake = new cmake_1.CMakeTests(buildDirPath);
226
+ let ctests = yield cmake.tests();
227
+ if (ctests) {
228
+ for (let ctest of ctests) {
229
+ let qtest = new QtTest(ctest.executablePath(), buildDirPath);
230
+ this.qtTestExecutables.push(qtest);
231
+ }
232
+ }
233
+ else {
234
+ console.error("Failed to retrieve ctests!");
235
+ }
236
+ });
237
+ }
238
+ /// Removes any executable (from the list) that doesn't link to libQtTest.so
239
+ /// This heuristic tries to filter-out doctest and other non-Qt tests
240
+ /// Only implemented for linux for now
241
+ removeNonLinking() {
242
+ return __awaiter(this, void 0, void 0, function* () {
243
+ let isLinux = process.platform === "linux";
244
+ if (!isLinux) {
245
+ return;
246
+ }
247
+ let acceptedExecutables = [];
248
+ for (let ex of this.qtTestExecutables) {
249
+ let linksToQt = yield ex.linksToQtTestLib();
250
+ // undefined or true is accepted
251
+ if (linksToQt !== false) {
252
+ acceptedExecutables.push(ex);
253
+ }
254
+ this.qtTestExecutables = acceptedExecutables;
255
+ }
256
+ });
257
+ }
258
+ removeByRunningHelp() {
259
+ return __awaiter(this, void 0, void 0, function* () {
260
+ this.qtTestExecutables = this.qtTestExecutables.filter((ex) => __awaiter(this, void 0, void 0, function* () { return yield ex.isQtTestViaHelp(); }));
261
+ });
262
+ }
263
+ /// Removes any executable (from the list) that matches the specified regex
264
+ removeMatching(regex) {
265
+ this.qtTestExecutables = this.qtTestExecutables.filter((ex) => !regex.test(ex.filename));
266
+ }
267
+ /// Removes any executable (from the list) that doesn't match the specified regex
268
+ maintainMatching(regex) {
269
+ this.qtTestExecutables = this.qtTestExecutables.filter((ex) => regex.test(ex.filename));
270
+ }
271
+ dumpExecutablePaths() {
272
+ for (var ex of this.qtTestExecutables) {
273
+ console.log(ex.filename);
274
+ }
275
+ }
276
+ dumpTestSlots() {
277
+ return __awaiter(this, void 0, void 0, function* () {
278
+ for (var ex of this.qtTestExecutables) {
279
+ if (!ex.slots)
280
+ yield ex.parseAvailableSlots();
281
+ console.log(ex.filename);
282
+ if (ex.slots) {
283
+ for (let slot of ex.slots) {
284
+ console.log(" - " + slot.name);
285
+ }
286
+ }
287
+ }
288
+ });
289
+ }
290
+ }
291
+ exports.QtTests = QtTests;
package/out/utils.d.ts ADDED
@@ -0,0 +1 @@
1
+ export {};
package/out/utils.js ADDED
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ // SPDX-FileCopyrightText: 2023 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
3
+ // Author: Sergio Martins <sergio.martins@kdab.com>
4
+ // SPDX-License-Identifier: MIT
5
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ var desc = Object.getOwnPropertyDescriptor(m, k);
8
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
+ desc = { enumerable: true, get: function() { return m[k]; } };
10
+ }
11
+ Object.defineProperty(o, k2, desc);
12
+ }) : (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ o[k2] = m[k];
15
+ }));
16
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
17
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
18
+ }) : function(o, v) {
19
+ o["default"] = v;
20
+ });
21
+ var __importStar = (this && this.__importStar) || function (mod) {
22
+ if (mod && mod.__esModule) return mod;
23
+ var result = {};
24
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
25
+ __setModuleDefault(result, mod);
26
+ return result;
27
+ };
28
+ var __importDefault = (this && this.__importDefault) || function (mod) {
29
+ return (mod && mod.__esModule) ? mod : { "default": mod };
30
+ };
31
+ Object.defineProperty(exports, "__esModule", { value: true });
32
+ const path_1 = __importDefault(require("path"));
33
+ const fs = __importStar(require("fs"));
34
+ /// Returns whether the specified file is an executable
35
+ function isExecutable(filePath) {
36
+ if (process.platform === "win32") {
37
+ return path_1.default.extname(filePath).toLocaleLowerCase() === ".exe";
38
+ }
39
+ else {
40
+ try {
41
+ fs.accessSync(filePath, fs.constants.X_OK);
42
+ return true;
43
+ }
44
+ catch (err) {
45
+ return false;
46
+ }
47
+ }
48
+ }
49
+ /// Returns whether the specified file is a library
50
+ function isLibrary(filename) {
51
+ const split = filename.split(".");
52
+ if (split.length <= 1) {
53
+ return false;
54
+ }
55
+ // Find the first non-numeric extension, so we ignore all the trailing numbers in libFoo.so.2.0.9
56
+ for (var i = split.length - 1; i >= 0; --i) {
57
+ const extension = split[i];
58
+ const isNumber = !isNaN(Number(extension));
59
+ if (isNumber) {
60
+ continue;
61
+ }
62
+ return ["so", "dll", "dylib"].includes(extension);
63
+ }
64
+ return false;
65
+ }
66
+ /// Recursively looks for executable files in folderPath
67
+ function executableFiles(folderPath) {
68
+ const files = fs.readdirSync(folderPath);
69
+ var executables = [];
70
+ for (var file of files) {
71
+ // Ignore CMakeFiles directory, it has some of binaries
72
+ if (path_1.default.basename(file) === "CMakeFiles") {
73
+ continue;
74
+ }
75
+ const childPath = path_1.default.join(folderPath, file);
76
+ const info = fs.statSync(childPath);
77
+ if (info.isDirectory()) {
78
+ executables = executables.concat(executableFiles(childPath));
79
+ }
80
+ else if (info.isFile() && !isLibrary(path_1.default.basename(childPath)) && isExecutable(childPath)) {
81
+ executables.push(childPath);
82
+ }
83
+ }
84
+ return executables;
85
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iamsergio/qttest-utils",
3
- "version": "0.4.3",
3
+ "version": "0.4.5",
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",
package/src/qttest.ts CHANGED
@@ -15,6 +15,9 @@ export class QtTest {
15
15
  readonly filename: string;
16
16
  readonly buildDirPath: string;
17
17
 
18
+ /// Allows vscode extensions to associate with a test item
19
+ vscodeTestItem: any | undefined;
20
+
18
21
  slots: QtTestSlot[] | null = null;
19
22
 
20
23
  constructor(filename: string, buildDirPath: string) {
@@ -44,7 +47,7 @@ export class QtTest {
44
47
  return;
45
48
  }
46
49
 
47
- const child = spawn(this.filename, ["-functions"], {cwd: this.buildDirPath});
50
+ const child = spawn(this.filename, ["-functions"], { cwd: this.buildDirPath });
48
51
 
49
52
  child.stdout.on("data", (chunk) => {
50
53
  output += chunk.toString();
@@ -144,7 +147,7 @@ export class QtTest {
144
147
  }
145
148
 
146
149
  return await new Promise((resolve, reject) => {
147
- let opts = cwd.length > 0 ? {cwd: cwd} : {cwd: this.buildDirPath};
150
+ let opts = cwd.length > 0 ? { cwd: cwd } : { cwd: this.buildDirPath };
148
151
  const child = spawn(this.filename, args, opts);
149
152
  child.stdout.on("data", (chunk) => {
150
153
  // chunk.toString()
@@ -174,6 +177,9 @@ export class QtTestSlot {
174
177
  // The QTest executable this slot belongs to
175
178
  parentQTest: QtTest;
176
179
 
180
+ /// Allows vscode extensions to associate with a test item
181
+ vscodeTestItem: any | undefined;
182
+
177
183
  constructor(name: string, parent: QtTest) {
178
184
  this.name = name;
179
185
  this.parentQTest = parent;