@iobroker/testing 2.4.4 → 2.5.3
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.md +11 -0
- package/LICENSE +1 -1
- package/build/lib/adapterTools.js +27 -38
- package/build/lib/executeCommand.js +3 -4
- package/build/tests/integration/index.js +57 -74
- package/build/tests/integration/lib/adapterSetup.d.ts +1 -1
- package/build/tests/integration/lib/adapterSetup.js +76 -93
- package/build/tests/integration/lib/controllerSetup.d.ts +1 -1
- package/build/tests/integration/lib/controllerSetup.js +82 -99
- package/build/tests/integration/lib/dbConnection.js +32 -53
- package/build/tests/integration/lib/harness.js +129 -153
- package/build/tests/integration/lib/tools.js +1 -1
- package/build/tests/packageFiles/index.js +32 -26
- package/build/tests/unit/index.js +2 -11
- package/build/tests/unit/mocks/mockAdapter.d.ts +1 -1
- package/build/tests/unit/mocks/mockAdapter.js +17 -18
- package/build/tests/unit/mocks/mockAdapterCore.d.ts +1 -1
- package/build/tests/unit/mocks/mockDatabase.d.ts +2 -2
- package/build/tests/unit/mocks/mockDatabase.js +10 -10
- package/build/tests/unit/mocks/mockLogger.js +8 -8
- package/build/tests/unit/mocks/tools.d.ts +1 -1
- package/build/tests/unit/mocks/tools.js +2 -2
- package/package.json +30 -28
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,17 @@
|
|
|
4
4
|
PLACEHOLDER for next version:
|
|
5
5
|
## __WORK IN PROGRESS__
|
|
6
6
|
-->
|
|
7
|
+
## 2.5.3 (2022-01-29)
|
|
8
|
+
* Fix: Ensure the tests use the `file` DB type
|
|
9
|
+
|
|
10
|
+
## 2.5.2 (2021-09-18)
|
|
11
|
+
* Fix: `adminUI.config` is now respected for the config UI check and JSON config is allowed too
|
|
12
|
+
* Updated dependencies
|
|
13
|
+
* Modernized build process
|
|
14
|
+
|
|
15
|
+
## 2.5.1 (2021-09-05)
|
|
16
|
+
* We now use the nightly js-controller dev builds instead of GitHub installation
|
|
17
|
+
|
|
7
18
|
## 2.4.4 (2021-03-14)
|
|
8
19
|
* Fix error: `iopackContent.common.titleLang` is not iterable
|
|
9
20
|
|
package/LICENSE
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c)
|
|
3
|
+
Copyright (c) 2022 AlCalzone <d.griesel@gmx.net>
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -18,15 +18,6 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
18
18
|
__setModuleDefault(result, mod);
|
|
19
19
|
return result;
|
|
20
20
|
};
|
|
21
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
22
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
23
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
24
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
25
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
26
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
27
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
28
|
-
});
|
|
29
|
-
};
|
|
30
21
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
31
22
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
32
23
|
};
|
|
@@ -37,7 +28,7 @@ const typeguards_1 = require("alcalzone-shared/typeguards");
|
|
|
37
28
|
const debug_1 = __importDefault(require("debug"));
|
|
38
29
|
const fs_extra_1 = require("fs-extra");
|
|
39
30
|
const path = __importStar(require("path"));
|
|
40
|
-
const debug = debug_1.default("testing:unit:adapterTools");
|
|
31
|
+
const debug = (0, debug_1.default)("testing:unit:adapterTools");
|
|
41
32
|
/**
|
|
42
33
|
* Loads an adapter's package.json
|
|
43
34
|
* @param adapterDir The directory the adapter resides in
|
|
@@ -64,32 +55,30 @@ exports.adapterShouldSupportCompactMode = adapterShouldSupportCompactMode;
|
|
|
64
55
|
* Locates an adapter's main file
|
|
65
56
|
* @param adapterDir The directory the adapter resides in
|
|
66
57
|
*/
|
|
67
|
-
function locateAdapterMainFile(adapterDir) {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
throw new Error(`The adapter main file was not found in ${adapterDir}`);
|
|
92
|
-
});
|
|
58
|
+
async function locateAdapterMainFile(adapterDir) {
|
|
59
|
+
debug(`locating adapter main file in ${adapterDir}...`);
|
|
60
|
+
const ioPackage = loadIoPackage(adapterDir);
|
|
61
|
+
const npmPackage = loadNpmPackage(adapterDir);
|
|
62
|
+
// First look for the file defined in io-package.json or package.json or use "main.js" as a fallback
|
|
63
|
+
const mainFile = typeof ioPackage.common.main === "string"
|
|
64
|
+
? ioPackage.common.main
|
|
65
|
+
: typeof npmPackage.main === "string"
|
|
66
|
+
? npmPackage.main
|
|
67
|
+
: "main.js";
|
|
68
|
+
let ret = path.join(adapterDir, mainFile);
|
|
69
|
+
debug(` => trying ${ret}`);
|
|
70
|
+
if (await (0, fs_extra_1.pathExists)(ret)) {
|
|
71
|
+
debug(` => found ${mainFile}`);
|
|
72
|
+
return ret;
|
|
73
|
+
}
|
|
74
|
+
// If both don't exist, JS-Controller uses <adapter name>.js as another fallback
|
|
75
|
+
ret = path.join(adapterDir, ioPackage.common.name + ".js");
|
|
76
|
+
debug(` => trying ${ret}`);
|
|
77
|
+
if (await (0, fs_extra_1.pathExists)(ret)) {
|
|
78
|
+
debug(` => found ${mainFile}`);
|
|
79
|
+
return ret;
|
|
80
|
+
}
|
|
81
|
+
throw new Error(`The adapter main file was not found in ${adapterDir}`);
|
|
93
82
|
}
|
|
94
83
|
exports.locateAdapterMainFile = locateAdapterMainFile;
|
|
95
84
|
/**
|
|
@@ -141,12 +130,12 @@ exports.getAdapterFullName = getAdapterFullName;
|
|
|
141
130
|
function getAdapterDependencies(adapterDir) {
|
|
142
131
|
const ioPackage = loadIoPackage(adapterDir);
|
|
143
132
|
const ret = {};
|
|
144
|
-
if (typeguards_1.isArray(ioPackage.common.dependencies)) {
|
|
133
|
+
if ((0, typeguards_1.isArray)(ioPackage.common.dependencies)) {
|
|
145
134
|
for (const dep of ioPackage.common.dependencies) {
|
|
146
135
|
if (typeof dep === "string") {
|
|
147
136
|
ret[dep] = "latest";
|
|
148
137
|
}
|
|
149
|
-
else if (typeguards_1.isObject(dep)) {
|
|
138
|
+
else if ((0, typeguards_1.isObject)(dep)) {
|
|
150
139
|
const key = Object.keys(dep)[0];
|
|
151
140
|
if (key)
|
|
152
141
|
ret[key] = dep[key] || "latest";
|
|
@@ -7,10 +7,10 @@ const isWindows = /^win/.test(process.platform);
|
|
|
7
7
|
function executeCommand(command, argsOrOptions, options) {
|
|
8
8
|
return new Promise((resolve) => {
|
|
9
9
|
let args;
|
|
10
|
-
if (typeguards_1.isArray(argsOrOptions)) {
|
|
10
|
+
if ((0, typeguards_1.isArray)(argsOrOptions)) {
|
|
11
11
|
args = argsOrOptions;
|
|
12
12
|
}
|
|
13
|
-
else if (typeguards_1.isObject(argsOrOptions)) {
|
|
13
|
+
else if ((0, typeguards_1.isObject)(argsOrOptions)) {
|
|
14
14
|
// no args were given
|
|
15
15
|
options = argsOrOptions;
|
|
16
16
|
}
|
|
@@ -24,7 +24,6 @@ function executeCommand(command, argsOrOptions, options) {
|
|
|
24
24
|
options.stdout || process.stdout,
|
|
25
25
|
options.stderr || process.stderr,
|
|
26
26
|
],
|
|
27
|
-
// @ts-ignore This option exists starting with NodeJS 8
|
|
28
27
|
windowsHide: true,
|
|
29
28
|
};
|
|
30
29
|
if (options.cwd != null)
|
|
@@ -45,7 +44,7 @@ function executeCommand(command, argsOrOptions, options) {
|
|
|
45
44
|
try {
|
|
46
45
|
let bufferedStdout;
|
|
47
46
|
let bufferedStderr;
|
|
48
|
-
const cmd = child_process_1.spawn(command, args, spawnOptions).on("close", (code, signal) => {
|
|
47
|
+
const cmd = (0, child_process_1.spawn)(command, args, spawnOptions).on("close", (code, signal) => {
|
|
49
48
|
resolve({
|
|
50
49
|
exitCode: code !== null && code !== void 0 ? code : undefined,
|
|
51
50
|
signal: signal !== null && signal !== void 0 ? signal : undefined,
|
|
@@ -18,15 +18,6 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
18
18
|
__setModuleDefault(result, mod);
|
|
19
19
|
return result;
|
|
20
20
|
};
|
|
21
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
22
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
23
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
24
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
25
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
26
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
27
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
28
|
-
});
|
|
29
|
-
};
|
|
30
21
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
31
22
|
exports.testAdapter = void 0;
|
|
32
23
|
const async_1 = require("alcalzone-shared/async");
|
|
@@ -39,8 +30,8 @@ const controllerSetup_1 = require("./lib/controllerSetup");
|
|
|
39
30
|
const dbConnection_1 = require("./lib/dbConnection");
|
|
40
31
|
const harness_1 = require("./lib/harness");
|
|
41
32
|
function testAdapter(adapterDir, options = {}) {
|
|
42
|
-
const appName = adapterTools_1.getAppName(adapterDir);
|
|
43
|
-
const adapterName = adapterTools_1.getAdapterName(adapterDir);
|
|
33
|
+
const appName = (0, adapterTools_1.getAppName)(adapterDir);
|
|
34
|
+
const adapterName = (0, adapterTools_1.getAdapterName)(adapterDir);
|
|
44
35
|
const testDir = path.join(os.tmpdir(), `test-${appName}.${adapterName}`);
|
|
45
36
|
let harness;
|
|
46
37
|
const dbConnection = new dbConnection_1.DBConnection(appName, testDir);
|
|
@@ -51,87 +42,79 @@ function testAdapter(adapterDir, options = {}) {
|
|
|
51
42
|
describe(`Test the adapter (in a live environment)`, () => {
|
|
52
43
|
let objectsBackup;
|
|
53
44
|
let statesBackup;
|
|
54
|
-
before(function () {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
cwd: testDir,
|
|
71
|
-
});
|
|
72
|
-
// Prepare/clean the databases and config
|
|
73
|
-
if (wasJsControllerInstalled)
|
|
74
|
-
yield controllerSetup.setupJsController();
|
|
75
|
-
yield controllerSetup.setupSystemConfig();
|
|
76
|
-
yield controllerSetup.disableAdminInstances();
|
|
77
|
-
yield adapterSetup.deleteOldInstances();
|
|
78
|
-
yield adapterSetup.addAdapterInstance();
|
|
79
|
-
// Create a copy of the databases that we can restore later
|
|
80
|
-
({
|
|
81
|
-
objects: objectsBackup,
|
|
82
|
-
states: statesBackup,
|
|
83
|
-
} = yield dbConnection.readDB());
|
|
45
|
+
before(async function () {
|
|
46
|
+
// Installation may take a while - especially if rsa-compat needs to be installed
|
|
47
|
+
const oneMinute = 60000;
|
|
48
|
+
this.timeout(30 * oneMinute);
|
|
49
|
+
if (await controllerSetup.isJsControllerRunning()) {
|
|
50
|
+
throw new Error("JS-Controller is already running! Stop it for the first test run and try again!");
|
|
51
|
+
}
|
|
52
|
+
const adapterSetup = new adapterSetup_1.AdapterSetup(adapterDir, testDir, dbConnection);
|
|
53
|
+
// First we need to copy all files and execute an npm install
|
|
54
|
+
await controllerSetup.prepareTestDir();
|
|
55
|
+
await adapterSetup.copyAdapterFilesToTestDir();
|
|
56
|
+
// Remember if JS-Controller is installed already. If so, we need to call setup first later
|
|
57
|
+
const wasJsControllerInstalled = await controllerSetup.isJsControllerInstalled();
|
|
58
|
+
// Call npm install
|
|
59
|
+
await (0, executeCommand_1.executeCommand)("npm", ["i", "--production"], {
|
|
60
|
+
cwd: testDir,
|
|
84
61
|
});
|
|
62
|
+
// Prepare/clean the databases and config
|
|
63
|
+
if (wasJsControllerInstalled)
|
|
64
|
+
await controllerSetup.setupJsController();
|
|
65
|
+
await controllerSetup.setupSystemConfig();
|
|
66
|
+
await controllerSetup.disableAdminInstances();
|
|
67
|
+
await adapterSetup.deleteOldInstances();
|
|
68
|
+
await adapterSetup.addAdapterInstance();
|
|
69
|
+
// Create a copy of the databases that we can restore later
|
|
70
|
+
({ objects: objectsBackup, states: statesBackup } =
|
|
71
|
+
await dbConnection.readDB());
|
|
85
72
|
});
|
|
86
|
-
beforeEach(function () {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
},
|
|
103
|
-
});
|
|
104
|
-
// Start the controller instance
|
|
105
|
-
yield harness.startController();
|
|
106
|
-
// And enable the sendTo emulation
|
|
107
|
-
yield harness.enableSendTo();
|
|
73
|
+
beforeEach(async function () {
|
|
74
|
+
this.timeout(30000);
|
|
75
|
+
// Clean up before every single test
|
|
76
|
+
await Promise.all([
|
|
77
|
+
controllerSetup.clearDBDir(),
|
|
78
|
+
controllerSetup.clearLogDir(),
|
|
79
|
+
dbConnection.writeDB(objectsBackup, statesBackup),
|
|
80
|
+
]);
|
|
81
|
+
// Create a new test harness
|
|
82
|
+
harness = new harness_1.TestHarness(adapterDir, testDir);
|
|
83
|
+
// Enable the adapter and set its loglevel to debug
|
|
84
|
+
await harness.changeAdapterConfig(appName, testDir, adapterName, {
|
|
85
|
+
common: {
|
|
86
|
+
enabled: true,
|
|
87
|
+
loglevel: "debug",
|
|
88
|
+
},
|
|
108
89
|
});
|
|
90
|
+
// Start the controller instance
|
|
91
|
+
await harness.startController();
|
|
92
|
+
// And enable the sendTo emulation
|
|
93
|
+
await harness.enableSendTo();
|
|
109
94
|
});
|
|
110
|
-
afterEach(function () {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
harness.removeAllListeners();
|
|
117
|
-
});
|
|
95
|
+
afterEach(async function () {
|
|
96
|
+
// Stopping the processes may take a while
|
|
97
|
+
this.timeout(30000);
|
|
98
|
+
// Stop the controller again
|
|
99
|
+
await harness.stopController();
|
|
100
|
+
harness.removeAllListeners();
|
|
118
101
|
});
|
|
119
102
|
it("The adapter starts", function () {
|
|
120
103
|
this.timeout(60000);
|
|
121
104
|
return new Promise((resolve, reject) => {
|
|
122
105
|
// Register a handler to check the alive state and exit codes
|
|
123
106
|
harness
|
|
124
|
-
.on("stateChange", (id, state) =>
|
|
107
|
+
.on("stateChange", async (id, state) => {
|
|
125
108
|
if (id === `system.adapter.${adapterName}.0.alive` &&
|
|
126
109
|
state &&
|
|
127
110
|
state.val === true) {
|
|
128
111
|
// Wait a bit so we can catch errors that do not happen immediately
|
|
129
|
-
|
|
112
|
+
await (0, async_1.wait)(options.waitBeforeStartupSuccess != undefined
|
|
130
113
|
? options.waitBeforeStartupSuccess
|
|
131
114
|
: 5000);
|
|
132
115
|
resolve(`The adapter started successfully.`);
|
|
133
116
|
}
|
|
134
|
-
})
|
|
117
|
+
})
|
|
135
118
|
.on("failed", (code) => {
|
|
136
119
|
if (options.allowedExitCodes == undefined ||
|
|
137
120
|
options.allowedExitCodes.indexOf(code) === -1) {
|
|
@@ -18,15 +18,6 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
18
18
|
__setModuleDefault(result, mod);
|
|
19
19
|
return result;
|
|
20
20
|
};
|
|
21
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
22
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
23
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
24
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
25
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
26
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
27
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
28
|
-
});
|
|
29
|
-
};
|
|
30
21
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
31
22
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
32
23
|
};
|
|
@@ -40,18 +31,18 @@ const path = __importStar(require("path"));
|
|
|
40
31
|
const adapterTools_1 = require("../../../lib/adapterTools");
|
|
41
32
|
const executeCommand_1 = require("../../../lib/executeCommand");
|
|
42
33
|
const tools_1 = require("./tools");
|
|
43
|
-
const debug = debug_1.default("testing:integration:AdapterSetup");
|
|
34
|
+
const debug = (0, debug_1.default)("testing:integration:AdapterSetup");
|
|
44
35
|
class AdapterSetup {
|
|
45
36
|
constructor(adapterDir, testDir, dbConnection) {
|
|
46
37
|
this.adapterDir = adapterDir;
|
|
47
38
|
this.testDir = testDir;
|
|
48
39
|
this.dbConnection = dbConnection;
|
|
49
40
|
debug("Creating AdapterSetup...");
|
|
50
|
-
this.adapterName = adapterTools_1.getAdapterName(this.adapterDir);
|
|
51
|
-
this.adapterFullName = adapterTools_1.getAdapterFullName(this.adapterDir);
|
|
52
|
-
this.appName = adapterTools_1.getAppName(this.adapterDir);
|
|
53
|
-
this.testAdapterDir = tools_1.getTestAdapterDir(this.adapterDir, this.testDir);
|
|
54
|
-
this.testControllerDir = tools_1.getTestControllerDir(this.appName, this.testDir);
|
|
41
|
+
this.adapterName = (0, adapterTools_1.getAdapterName)(this.adapterDir);
|
|
42
|
+
this.adapterFullName = (0, adapterTools_1.getAdapterFullName)(this.adapterDir);
|
|
43
|
+
this.appName = (0, adapterTools_1.getAppName)(this.adapterDir);
|
|
44
|
+
this.testAdapterDir = (0, tools_1.getTestAdapterDir)(this.adapterDir, this.testDir);
|
|
45
|
+
this.testControllerDir = (0, tools_1.getTestControllerDir)(this.appName, this.testDir);
|
|
55
46
|
debug(` directories:`);
|
|
56
47
|
debug(` controller: ${this.testControllerDir}`);
|
|
57
48
|
debug(` adapter: ${this.testAdapterDir}`);
|
|
@@ -61,95 +52,87 @@ class AdapterSetup {
|
|
|
61
52
|
/**
|
|
62
53
|
* Tests if the adapter is already installed in the test directory
|
|
63
54
|
*/
|
|
64
|
-
isAdapterInstalled() {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
return fs_extra_1.pathExists(this.testAdapterDir);
|
|
68
|
-
});
|
|
55
|
+
async isAdapterInstalled() {
|
|
56
|
+
// We expect the adapter to be installed if the dir in <testDir>/node_modules exists
|
|
57
|
+
return (0, fs_extra_1.pathExists)(this.testAdapterDir);
|
|
69
58
|
}
|
|
70
59
|
/** Copies all adapter files (except a few) to the test directory */
|
|
71
|
-
copyAdapterFilesToTestDir() {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
stdout: "pipe",
|
|
78
|
-
});
|
|
79
|
-
if (packResult.exitCode !== 0 || typeof packResult.stdout !== "string")
|
|
80
|
-
throw new Error(`Packing the adapter tarball failed!`);
|
|
81
|
-
// The last non-empty line of `npm pack`s STDOUT contains the tarball path
|
|
82
|
-
const stdoutLines = packResult.stdout.trim().split(/[\r\n]+/);
|
|
83
|
-
const tarballName = stdoutLines[stdoutLines.length - 1].trim();
|
|
84
|
-
const tarballPath = path.resolve(this.adapterDir, tarballName);
|
|
85
|
-
yield fs_extra_1.copy(tarballPath, path.resolve(this.testDir, tarballName));
|
|
86
|
-
yield fs_extra_1.unlink(tarballPath);
|
|
87
|
-
// Complete the package.json, so npm can do it's magic
|
|
88
|
-
debug("Saving the adapter in package.json");
|
|
89
|
-
const packageJsonPath = path.join(this.testDir, "package.json");
|
|
90
|
-
const packageJson = yield fs_extra_1.readJSON(packageJsonPath);
|
|
91
|
-
packageJson.dependencies[this.adapterFullName] = `file:./${tarballName}`;
|
|
92
|
-
for (const [dep, version] of objects_1.entries(adapterTools_1.getAdapterDependencies(this.adapterDir))) {
|
|
93
|
-
// Don't overwrite the js-controller github dependency with a probably lower one
|
|
94
|
-
if (dep === "js-controller")
|
|
95
|
-
continue;
|
|
96
|
-
packageJson.dependencies[`${this.appName}.${dep}`] = version;
|
|
97
|
-
}
|
|
98
|
-
yield fs_extra_1.writeJSON(packageJsonPath, packageJson, { spaces: 2 });
|
|
99
|
-
debug("Deleting old remains of this adapter");
|
|
100
|
-
if (yield fs_extra_1.pathExists(this.testAdapterDir))
|
|
101
|
-
yield fs_extra_1.remove(this.testAdapterDir);
|
|
102
|
-
debug(" => done!");
|
|
60
|
+
async copyAdapterFilesToTestDir() {
|
|
61
|
+
debug("Copying adapter files to test directory...");
|
|
62
|
+
// We install the adapter almost like it would be installed in the real world
|
|
63
|
+
// Therefore pack it into a tarball and put it in the test dir for installation
|
|
64
|
+
const packResult = await (0, executeCommand_1.executeCommand)("npm", ["pack", "--loglevel", "silent"], {
|
|
65
|
+
stdout: "pipe",
|
|
103
66
|
});
|
|
67
|
+
if (packResult.exitCode !== 0 || typeof packResult.stdout !== "string")
|
|
68
|
+
throw new Error(`Packing the adapter tarball failed!`);
|
|
69
|
+
// The last non-empty line of `npm pack`s STDOUT contains the tarball path
|
|
70
|
+
const stdoutLines = packResult.stdout.trim().split(/[\r\n]+/);
|
|
71
|
+
const tarballName = stdoutLines[stdoutLines.length - 1].trim();
|
|
72
|
+
const tarballPath = path.resolve(this.adapterDir, tarballName);
|
|
73
|
+
await (0, fs_extra_1.copy)(tarballPath, path.resolve(this.testDir, tarballName));
|
|
74
|
+
await (0, fs_extra_1.unlink)(tarballPath);
|
|
75
|
+
// Complete the package.json, so npm can do it's magic
|
|
76
|
+
debug("Saving the adapter in package.json");
|
|
77
|
+
const packageJsonPath = path.join(this.testDir, "package.json");
|
|
78
|
+
const packageJson = await (0, fs_extra_1.readJSON)(packageJsonPath);
|
|
79
|
+
packageJson.dependencies[this.adapterFullName] = `file:./${tarballName}`;
|
|
80
|
+
for (const [dep, version] of (0, objects_1.entries)((0, adapterTools_1.getAdapterDependencies)(this.adapterDir))) {
|
|
81
|
+
// Don't overwrite the js-controller github dependency with a probably lower one
|
|
82
|
+
if (dep === "js-controller")
|
|
83
|
+
continue;
|
|
84
|
+
packageJson.dependencies[`${this.appName}.${dep}`] = version;
|
|
85
|
+
}
|
|
86
|
+
await (0, fs_extra_1.writeJSON)(packageJsonPath, packageJson, { spaces: 2 });
|
|
87
|
+
debug("Deleting old remains of this adapter");
|
|
88
|
+
if (await (0, fs_extra_1.pathExists)(this.testAdapterDir))
|
|
89
|
+
await (0, fs_extra_1.remove)(this.testAdapterDir);
|
|
90
|
+
debug(" => done!");
|
|
104
91
|
}
|
|
105
92
|
/**
|
|
106
93
|
* Adds an instance for an already installed adapter in the test directory
|
|
107
94
|
*/
|
|
108
|
-
addAdapterInstance() {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
stdout: "ignore",
|
|
121
|
-
});
|
|
122
|
-
if (addResult.exitCode !== 0)
|
|
123
|
-
throw new Error(`Adding the adapter instance failed!`);
|
|
124
|
-
debug(" => done!");
|
|
95
|
+
async addAdapterInstance() {
|
|
96
|
+
debug("Adding adapter instance...");
|
|
97
|
+
// execute iobroker add <adapter> -- This also installs missing dependencies
|
|
98
|
+
const addResult = await (0, executeCommand_1.executeCommand)("node", [
|
|
99
|
+
`${this.appName}.js`,
|
|
100
|
+
"add",
|
|
101
|
+
this.adapterName,
|
|
102
|
+
"--enabled",
|
|
103
|
+
"false",
|
|
104
|
+
], {
|
|
105
|
+
cwd: this.testControllerDir,
|
|
106
|
+
stdout: "ignore",
|
|
125
107
|
});
|
|
108
|
+
if (addResult.exitCode !== 0)
|
|
109
|
+
throw new Error(`Adding the adapter instance failed!`);
|
|
110
|
+
debug(" => done!");
|
|
126
111
|
}
|
|
127
|
-
deleteOldInstances() {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
delete objects[id];
|
|
143
|
-
}
|
|
112
|
+
async deleteOldInstances() {
|
|
113
|
+
debug("Removing old adapter instances...");
|
|
114
|
+
const { objects, states } = await this.dbConnection.readDB();
|
|
115
|
+
const instanceRegex = new RegExp(`^system\\.adapter\\.${this.adapterName}\\.\\d+`);
|
|
116
|
+
const instanceObjsRegex = new RegExp(`^${this.adapterName}\\.\\d+\.`);
|
|
117
|
+
const belongsToAdapter = (id) => {
|
|
118
|
+
return (instanceRegex.test(id) ||
|
|
119
|
+
instanceObjsRegex.test(id) ||
|
|
120
|
+
id === this.adapterName ||
|
|
121
|
+
id === `${this.adapterName}.admin`);
|
|
122
|
+
};
|
|
123
|
+
if (objects) {
|
|
124
|
+
for (const id of Object.keys(objects)) {
|
|
125
|
+
if (belongsToAdapter(id))
|
|
126
|
+
delete objects[id];
|
|
144
127
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
128
|
+
}
|
|
129
|
+
if (states) {
|
|
130
|
+
for (const id of Object.keys(states)) {
|
|
131
|
+
if (belongsToAdapter(id))
|
|
132
|
+
delete states[id];
|
|
150
133
|
}
|
|
151
|
-
|
|
152
|
-
|
|
134
|
+
}
|
|
135
|
+
await this.dbConnection.writeDB(objects, states);
|
|
153
136
|
}
|
|
154
137
|
}
|
|
155
138
|
exports.AdapterSetup = AdapterSetup;
|