@iobroker/testing 4.0.0 → 4.1.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/LICENSE +1 -1
- package/README.md +4 -0
- package/build/tests/integration/index.d.ts +5 -0
- package/build/tests/integration/index.js +1 -1
- package/build/tests/integration/lib/controllerSetup.d.ts +1 -1
- package/build/tests/integration/lib/controllerSetup.js +3 -3
- package/build/tests/integration/lib/dbConnection.d.ts +2 -2
- package/build/tests/packageFiles/index.js +35 -3
- package/build/tests/unit/mocks/mockAdapter.d.ts +1 -1
- package/build/tests/unit/mocks/mockLogger.d.ts +1 -1
- package/build/tests/unit/mocks/tools.d.ts +4 -4
- package/package.json +16 -16
package/LICENSE
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c)
|
|
3
|
+
Copyright (c) 2024 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
|
package/README.md
CHANGED
|
@@ -43,6 +43,10 @@ tests.integration(path.join(__dirname, ".."), {
|
|
|
43
43
|
// By default, termination during startup is not allowed.
|
|
44
44
|
allowedExitCodes: [11],
|
|
45
45
|
|
|
46
|
+
// To test against a different version of JS-Controller, you can change the version or dist-tag here.
|
|
47
|
+
// Make sure to remove this setting when you're done testing.
|
|
48
|
+
controllerVersion: "latest", // or a specific version like "4.0.1"
|
|
49
|
+
|
|
46
50
|
// Define your own tests inside defineAdditionalTests
|
|
47
51
|
defineAdditionalTests({ suite }) {
|
|
48
52
|
// All tests (it, describe) must be grouped in one or more suites. Each suite sets up a fresh environment for the adapter tests.
|
|
@@ -7,6 +7,11 @@ export interface TestAdapterOptions {
|
|
|
7
7
|
loglevel?: ioBroker.LogLevel;
|
|
8
8
|
/** How long to wait before the adapter startup is considered successful */
|
|
9
9
|
waitBeforeStartupSuccess?: number;
|
|
10
|
+
/**
|
|
11
|
+
* Which JS-Controller version or dist-tag should be used for the tests. Default: dev
|
|
12
|
+
* This should only be changed during active development.
|
|
13
|
+
*/
|
|
14
|
+
controllerVersion?: string;
|
|
10
15
|
/** Allows you to define additional tests */
|
|
11
16
|
defineAdditionalTests?: (args: TestContext) => void;
|
|
12
17
|
}
|
|
@@ -58,7 +58,7 @@ function testAdapter(adapterDir, options = {}) {
|
|
|
58
58
|
// Installation happens in two steps:
|
|
59
59
|
// First we need to set up JS Controller, so the databases etc. can be created
|
|
60
60
|
// First we need to copy all files and execute an npm install
|
|
61
|
-
await controllerSetup.prepareTestDir();
|
|
61
|
+
await controllerSetup.prepareTestDir(options.controllerVersion);
|
|
62
62
|
// Only then we can install the adapter, because some (including VIS) try to access
|
|
63
63
|
// the databases if JS Controller is installed
|
|
64
64
|
await adapterSetup.installAdapterInTestDir();
|
|
@@ -8,7 +8,7 @@ export declare class ControllerSetup {
|
|
|
8
8
|
private testAdapterDir;
|
|
9
9
|
private testControllerDir;
|
|
10
10
|
private testDataDir;
|
|
11
|
-
prepareTestDir(): Promise<void>;
|
|
11
|
+
prepareTestDir(controllerVersion?: string): Promise<void>;
|
|
12
12
|
/**
|
|
13
13
|
* Tests if JS-Controller is already installed
|
|
14
14
|
* @param appName The branded name of "iobroker"
|
|
@@ -53,8 +53,8 @@ class ControllerSetup {
|
|
|
53
53
|
debug(` appName: ${this.appName}`);
|
|
54
54
|
debug(` adapterName: ${this.adapterName}`);
|
|
55
55
|
}
|
|
56
|
-
async prepareTestDir() {
|
|
57
|
-
debug(
|
|
56
|
+
async prepareTestDir(controllerVersion = "dev") {
|
|
57
|
+
debug(`Preparing the test directory. JS-Controller version: "${controllerVersion}"...`);
|
|
58
58
|
// Make sure the test dir exists
|
|
59
59
|
await (0, fs_extra_1.ensureDir)(this.testDir);
|
|
60
60
|
// Write the package.json
|
|
@@ -69,7 +69,7 @@ class ControllerSetup {
|
|
|
69
69
|
author: "",
|
|
70
70
|
license: "ISC",
|
|
71
71
|
dependencies: {
|
|
72
|
-
[`${this.appName}.js-controller`]:
|
|
72
|
+
[`${this.appName}.js-controller`]: controllerVersion,
|
|
73
73
|
},
|
|
74
74
|
description: "",
|
|
75
75
|
};
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
/// <reference types="node" />
|
|
4
4
|
/// <reference types="node" />
|
|
5
5
|
import EventEmitter from "events";
|
|
6
|
-
export
|
|
7
|
-
export
|
|
6
|
+
export type ObjectsDB = Record<string, ioBroker.Object>;
|
|
7
|
+
export type StatesDB = Record<string, ioBroker.State>;
|
|
8
8
|
export interface DBConnection {
|
|
9
9
|
on(event: "objectChange", handler: ioBroker.ObjectChangeHandler): this;
|
|
10
10
|
on(event: "stateChange", handler: ioBroker.StateChangeHandler): this;
|
|
@@ -93,13 +93,13 @@ function validatePackageFiles(adapterDir) {
|
|
|
93
93
|
skipIfInvalid.call(this, "package.json");
|
|
94
94
|
});
|
|
95
95
|
const packageContent = require(packageJsonPath);
|
|
96
|
+
const iopackContent = require(ioPackageJsonPath);
|
|
96
97
|
const requiredProperties = [
|
|
97
98
|
"name",
|
|
98
99
|
"version",
|
|
99
100
|
"description",
|
|
100
101
|
"author",
|
|
101
102
|
"license",
|
|
102
|
-
"main",
|
|
103
103
|
"repository",
|
|
104
104
|
"repository.type",
|
|
105
105
|
];
|
|
@@ -112,6 +112,11 @@ function validatePackageFiles(adapterDir) {
|
|
|
112
112
|
(0, chai_1.expect)(name).to.match(/^[a-z]/, `The adapter name must start with a letter!`);
|
|
113
113
|
(0, chai_1.expect)(name).to.match(/[a-z0-9]$/, `The adapter name must end with a letter or number!`);
|
|
114
114
|
});
|
|
115
|
+
if (!iopackContent.common.onlyWWW) {
|
|
116
|
+
it(`property main is defined for non onlyWWW adapters`, () => {
|
|
117
|
+
(0, chai_1.expect)(packageContent.main).to.not.be.undefined;
|
|
118
|
+
});
|
|
119
|
+
}
|
|
115
120
|
it(`The repository type is "git"`, () => {
|
|
116
121
|
(0, chai_1.expect)(packageContent.repository.type).to.equal("git");
|
|
117
122
|
});
|
|
@@ -142,7 +147,6 @@ function validatePackageFiles(adapterDir) {
|
|
|
142
147
|
"common.desc",
|
|
143
148
|
"common.icon",
|
|
144
149
|
"common.extIcon",
|
|
145
|
-
"common.license",
|
|
146
150
|
"common.type",
|
|
147
151
|
"common.authors",
|
|
148
152
|
"native",
|
|
@@ -174,6 +178,29 @@ function validatePackageFiles(adapterDir) {
|
|
|
174
178
|
(0, chai_1.expect)((0, typeguards_1.isObject)(news)).to.be.true;
|
|
175
179
|
(0, chai_1.expect)(Object.keys(news).length).to.be.at.most(20);
|
|
176
180
|
});
|
|
181
|
+
if (iopackContent.common.licenseInformation) {
|
|
182
|
+
it(`if common.licenseInformation exists, it is an object with required properties`, () => {
|
|
183
|
+
(0, chai_1.expect)(iopackContent.common.licenseInformation).to.be.an("object");
|
|
184
|
+
(0, chai_1.expect)(iopackContent.common.licenseInformation.type).to.be.oneOf(["free", "commercial", "paid", "limited"]);
|
|
185
|
+
if (iopackContent.common.licenseInformation.type !== "free") {
|
|
186
|
+
(0, chai_1.expect)(iopackContent.common.licenseInformation.link, "License link is missing").to.not.be.undefined;
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
it(`common.license should not exist together with common.licenseInformation`, () => {
|
|
190
|
+
(0, chai_1.expect)(iopackContent.common.license, "common.license must be removed").to.be.undefined;
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
it(`common.license must exist without common.licenseInformation`, () => {
|
|
195
|
+
(0, chai_1.expect)(iopackContent.common.license, "common.licenseInformation (preferred) or common.license (deprecated) must exist").to.not.be.undefined;
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
if (iopackContent.common.tier != undefined) {
|
|
199
|
+
it(`common.tier must be 1, 2 or 3`, () => {
|
|
200
|
+
(0, chai_1.expect)(iopackContent.common.tier).to.be.at.least(1);
|
|
201
|
+
(0, chai_1.expect)(iopackContent.common.tier).to.be.at.most(3);
|
|
202
|
+
});
|
|
203
|
+
}
|
|
177
204
|
// If the adapter has a configuration page, check that a supported admin UI is used
|
|
178
205
|
const hasNoConfigPage = iopackContent.common.noConfig === true ||
|
|
179
206
|
iopackContent.common.noConfig === "true" ||
|
|
@@ -200,7 +227,12 @@ function validatePackageFiles(adapterDir) {
|
|
|
200
227
|
(0, chai_1.expect)(iopackContent.common.version).to.equal(packageContent.version);
|
|
201
228
|
});
|
|
202
229
|
it("The license matches", () => {
|
|
203
|
-
|
|
230
|
+
if (iopackContent.common.licenseInformation) {
|
|
231
|
+
(0, chai_1.expect)(iopackContent.common.licenseInformation.license).to.equal(packageContent.license);
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
(0, chai_1.expect)(iopackContent.common.license).to.equal(packageContent.license);
|
|
235
|
+
}
|
|
204
236
|
});
|
|
205
237
|
});
|
|
206
238
|
});
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import type { MockDatabase } from "./mockDatabase";
|
|
3
3
|
import { MockLogger } from "./mockLogger";
|
|
4
4
|
import { Mock } from "./tools";
|
|
5
|
-
export
|
|
5
|
+
export type MockAdapter = Mock<ioBroker.Adapter> & {
|
|
6
6
|
readyHandler: ioBroker.ReadyHandler | undefined;
|
|
7
7
|
objectChangeHandler: ioBroker.ObjectChangeHandler | undefined;
|
|
8
8
|
stateChangeHandler: ioBroker.StateChangeHandler | undefined;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/// <reference types="sinon" />
|
|
2
2
|
import type { Equals, Overwrite } from "alcalzone-shared/types";
|
|
3
|
-
export
|
|
4
|
-
export
|
|
3
|
+
export type IsAny<T> = Equals<T extends never ? false : true, boolean>;
|
|
4
|
+
export type MockableMethods<T, All = Required<T>, NoAny = {
|
|
5
5
|
[K in keyof All]: IsAny<All[K]> extends true ? never : All[K] extends (...args: any[]) => void ? K : never;
|
|
6
6
|
}> = NoAny[keyof NoAny];
|
|
7
|
-
export
|
|
7
|
+
export type Mock<T extends {}> = Overwrite<T, {
|
|
8
8
|
[K in MockableMethods<T>]: sinon.SinonStub;
|
|
9
9
|
}>;
|
|
10
10
|
export declare function doResetHistory(parent: Record<string, any>): void;
|
|
11
11
|
export declare function doResetBehavior(parent: Record<string, any>, implementedMethods: Record<string, any>): void;
|
|
12
12
|
export declare function stubAndPromisifyImplementedMethods<T extends string>(parent: Record<T, any>, implementedMethods: Partial<Record<T, any>>, allowUserOverrides?: T[]): void;
|
|
13
|
-
export
|
|
13
|
+
export type ImplementedMethodDictionary<T> = Partial<Record<MockableMethods<T>, "none" | "normal" | "no error">>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@iobroker/testing",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.1.1",
|
|
4
4
|
"description": "Shared utilities for adapter and module testing in ioBroker",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -40,36 +40,36 @@
|
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@alcalzone/release-script": "^3.5.9",
|
|
42
42
|
"@alcalzone/release-script-plugin-license": "^3.5.9",
|
|
43
|
-
"@iobroker/adapter-core": "^2.6.
|
|
43
|
+
"@iobroker/adapter-core": "^2.6.8",
|
|
44
44
|
"@tsconfig/node14": "^1.0.3",
|
|
45
|
-
"@types/chai": "^4.3.
|
|
45
|
+
"@types/chai": "^4.3.5",
|
|
46
46
|
"@types/chai-as-promised": "^7.1.5",
|
|
47
47
|
"@types/debug": "4.1.7",
|
|
48
48
|
"@types/fs-extra": "^9.0.13",
|
|
49
|
-
"@types/iobroker": "^4.0.
|
|
50
|
-
"@types/mocha": "^
|
|
51
|
-
"@types/node": "^
|
|
49
|
+
"@types/iobroker": "^4.0.5",
|
|
50
|
+
"@types/mocha": "^10.0.1",
|
|
51
|
+
"@types/node": "^18.16.3",
|
|
52
52
|
"@types/sinon": "^10.0.13",
|
|
53
|
-
"@types/sinon-chai": "^3.2.
|
|
54
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
|
55
|
-
"@typescript-eslint/parser": "^5.
|
|
56
|
-
"eslint": "^8.
|
|
57
|
-
"eslint-config-prettier": "^8.
|
|
53
|
+
"@types/sinon-chai": "^3.2.9",
|
|
54
|
+
"@typescript-eslint/eslint-plugin": "^5.54.0",
|
|
55
|
+
"@typescript-eslint/parser": "^5.59.8",
|
|
56
|
+
"eslint": "^8.44.0",
|
|
57
|
+
"eslint-config-prettier": "^8.8.0",
|
|
58
58
|
"eslint-plugin-prettier": "^4.2.1",
|
|
59
|
-
"prettier": "^2.
|
|
59
|
+
"prettier": "^2.8.8",
|
|
60
60
|
"rimraf": "^3.0.2",
|
|
61
61
|
"source-map-support": "^0.5.21",
|
|
62
62
|
"ts-node": "^10.9.1",
|
|
63
|
-
"typescript": "~4.
|
|
63
|
+
"typescript": "~4.9.3"
|
|
64
64
|
},
|
|
65
65
|
"dependencies": {
|
|
66
66
|
"alcalzone-shared": "~4.0.3",
|
|
67
|
-
"chai": "^4.3.
|
|
67
|
+
"chai": "^4.3.7",
|
|
68
68
|
"chai-as-promised": "^7.1.1",
|
|
69
69
|
"debug": "^4.3.4",
|
|
70
70
|
"fs-extra": "^10.1.0",
|
|
71
|
-
"mocha": "^10.
|
|
72
|
-
"sinon": "^
|
|
71
|
+
"mocha": "^10.2.0",
|
|
72
|
+
"sinon": "^15.0.1",
|
|
73
73
|
"sinon-chai": "^3.7.0"
|
|
74
74
|
}
|
|
75
75
|
}
|