Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Use vitest for testing #25284

Merged
merged 40 commits into from
Dec 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
837319e
remove deps
Nerivec Dec 21, 2024
71e98a5
add vitest
Nerivec Dec 21, 2024
1ce213e
compat tests/mocks
Nerivec Dec 21, 2024
4cd7e17
fix coverage ignore
Nerivec Dec 21, 2024
b3a079b
comment test rc
Nerivec Dec 21, 2024
fc9ac7b
prettier
Nerivec Dec 21, 2024
8c88265
remove deps
Nerivec Dec 21, 2024
d96bdd7
add vitest
Nerivec Dec 21, 2024
468267c
compat tests/mocks
Nerivec Dec 21, 2024
7dfedc3
fix coverage ignore
Nerivec Dec 21, 2024
f155997
comment test rc
Nerivec Dec 21, 2024
947dca4
prettier
Nerivec Dec 21, 2024
cbd709b
Merge branch 'vitest' of https://github.com/Nerivec/zigbee2mqtt into …
Nerivec Dec 21, 2024
52a4911
move rc test to top and revert its actions
Nerivec Dec 21, 2024
26d5f74
optimize test run time
Nerivec Dec 21, 2024
5d05664
split tests
Nerivec Dec 21, 2024
8c4ef34
revert split
Nerivec Dec 21, 2024
07dc35a
remove mockMQTT object wrapper
Nerivec Dec 21, 2024
15149f1
Merge branch 'dev' into vitest
Nerivec Dec 21, 2024
8573ad7
rc bypass
Nerivec Dec 21, 2024
de2f57c
add clean script
Nerivec Dec 22, 2024
40a89ca
remove deps
Nerivec Dec 21, 2024
9882a7c
add vitest
Nerivec Dec 21, 2024
d32ad60
compat tests/mocks
Nerivec Dec 21, 2024
1e58b18
fix coverage ignore
Nerivec Dec 21, 2024
a5cca19
comment test rc
Nerivec Dec 21, 2024
b8ecd3b
prettier
Nerivec Dec 21, 2024
2dbe156
remove deps
Nerivec Dec 21, 2024
26f41e3
add vitest
Nerivec Dec 21, 2024
ec88393
compat tests/mocks
Nerivec Dec 21, 2024
d05d9e7
prettier
Nerivec Dec 21, 2024
9de05a6
move rc test to top and revert its actions
Nerivec Dec 21, 2024
6074320
optimize test run time
Nerivec Dec 21, 2024
4541d8f
split tests
Nerivec Dec 21, 2024
fa7ca53
revert split
Nerivec Dec 21, 2024
ced3cfc
remove mockMQTT object wrapper
Nerivec Dec 21, 2024
1969f66
rc bypass
Nerivec Dec 21, 2024
4c0133c
add clean script
Nerivec Dec 22, 2024
965b1ce
Merge branch 'vitest' of https://github.com/Nerivec/zigbee2mqtt into …
Nerivec Dec 22, 2024
0c4d0a3
Merge branch 'dev' into vitest
Koenkk Dec 22, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ jobs:
pnpm run eslint
- name: Test
run: pnpm run test-with-coverage
run: pnpm run test:coverage

- name: Log in to the Docker container registry
if: (github.ref == 'refs/heads/dev' || startsWith(github.ref, 'refs/tags/')) && github.event_name == 'push'
Expand Down Expand Up @@ -188,4 +188,4 @@ jobs:
run: pnpm run build

- name: Test
run: pnpm run test-with-coverage
run: pnpm run test:coverage
5 changes: 0 additions & 5 deletions babel.config.js

This file was deleted.

10 changes: 7 additions & 3 deletions lib/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,10 +131,11 @@ export class Controller {
try {
this.sdNotify = process.env.NOTIFY_SOCKET ? await import('sd-notify') : undefined;
logger.debug('sd-notify loaded');
/* v8 ignore start */
} catch {
// istanbul ignore next
logger.debug('sd-notify is not installed');
}
/* v8 ignore stop */

// Start zigbee
try {
Expand All @@ -145,10 +146,13 @@ export class Controller {
logger.error('Check https://www.zigbee2mqtt.io/guide/installation/20_zigbee2mqtt-fails-to-start.html for possible solutions');
logger.error('Exiting...');
logger.error((error as Error).stack!);
/* istanbul ignore if */

/* v8 ignore start */
if ((error as Error).message.includes('USB adapter discovery error (No valid USB adapter found)')) {
logger.error('If this happens after updating to Zigbee2MQTT 2.0.0, see https://github.com/Koenkk/zigbee2mqtt/discussions/24364');
}
/* v8 ignore stop */

return await this.exit(1);
}

Expand Down Expand Up @@ -292,6 +296,7 @@ export class Controller {
softwareBuildID: entity.zh.softwareBuildID,
// Manufacturer name can contain \u0000, remove this.
// https://github.com/home-assistant/core/issues/85691
/* v8 ignore next */
manufacturerName: entity.zh.manufacturerName?.split('\u0000')[0],
};
}
Expand Down Expand Up @@ -360,7 +365,6 @@ export class Controller {
try {
await extension[method]?.();
} catch (error) {
/* istanbul ignore next */
logger.error(`Failed to call '${extension.constructor.name}' '${method}' (${(error as Error).stack})`);
}
}
Expand Down
4 changes: 2 additions & 2 deletions lib/extension/availability.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export default class Availability extends Extension {

private isAvailable(entity: Device | Group): boolean {
if (entity.isDevice()) {
return Date.now() - (entity.zh.lastSeen ?? /* istanbul ignore next */ 0) < this.getTimeout(entity);
return Date.now() - (entity.zh.lastSeen ?? /* v8 ignore next */ 0) < this.getTimeout(entity);
} else {
const membersDevices = entity.membersDevices();
return membersDevices.length === 0 || membersDevices.some((d) => this.availabilityCache[d.ieeeAddr]);
Expand Down Expand Up @@ -164,7 +164,7 @@ export default class Availability extends Extension {

private async publishAvailability(entity: Device | Group, logLastSeen: boolean, forcePublish = false, skipGroups = false): Promise<void> {
if (logLastSeen && entity.isDevice()) {
const ago = Date.now() - (entity.zh.lastSeen ?? /* istanbul ignore next */ 0);
const ago = Date.now() - (entity.zh.lastSeen ?? /* v8 ignore next */ 0);

if (this.isActiveDevice(entity)) {
logger.debug(`Active device '${entity.name}' was last seen '${(ago / utils.minutes(1)).toFixed(2)}' minutes ago.`);
Expand Down
7 changes: 0 additions & 7 deletions lib/extension/bind.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,12 +170,10 @@ const POLL_ON_MESSAGE: Readonly<PollOnMessage> = [
const supportedAttrs = await getColorCapabilities(endpoint);
const readAttrs: string[] = [];

/* istanbul ignore else */
if (supportedAttrs.colorXY) {
readAttrs.push('currentX', 'currentY');
}

/* istanbul ignore else */
if (supportedAttrs.colorTemperature) {
readAttrs.push('colorTemperature');
}
Expand Down Expand Up @@ -390,7 +388,6 @@ export default class Bind extends Extension {
failed: failedClusters,
};

/* istanbul ignore else */
if (successfulClusters.length !== 0) {
if (type === 'bind') {
await this.setupReporting(
Expand Down Expand Up @@ -466,7 +463,6 @@ export default class Bind extends Extension {
const coordinatorEndpoint = this.zigbee.firstCoordinatorEndpoint();

for (const bind of binds) {
/* istanbul ignore else */
if (bind.cluster.name in REPORT_CLUSTERS) {
for (const endpoint of this.getSetupReportingEndpoints(bind, coordinatorEndpoint)) {
const entity = `${this.zigbee.resolveEntity(endpoint.getDevice())!.name}/${endpoint.ID}`;
Expand All @@ -477,7 +473,6 @@ export default class Bind extends Extension {
const items = [];

for (const c of REPORT_CLUSTERS[bind.cluster.name as ClusterName]!) {
/* istanbul ignore else */
if (!c.condition || (await c.condition(endpoint))) {
const i = {...c};
delete i.condition;
Expand Down Expand Up @@ -524,7 +519,6 @@ export default class Bind extends Extension {
}

for (const b of endpoint.binds) {
/* istanbul ignore else */
if (b.target === coordinator && !requiredClusters.includes(b.cluster.name) && b.cluster.name in REPORT_CLUSTERS) {
boundClusters.push(b.cluster.name);
}
Expand All @@ -537,7 +531,6 @@ export default class Bind extends Extension {
const items = [];

for (const item of REPORT_CLUSTERS[cluster as ClusterName]!) {
/* istanbul ignore else */
if (!item.condition || (await item.condition(endpoint))) {
const i = {...item};
delete i.condition;
Expand Down
2 changes: 1 addition & 1 deletion lib/extension/bridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -804,7 +804,7 @@ export default class Bridge extends Extension {
let icon = device.options.icon ?? definitionIcon;

if (icon) {
/* istanbul ignore next */
/* v8 ignore next */
icon = icon.replace('${zigbeeModel}', utils.sanitizeImageParameter(device.zh.modelID ?? ''));
icon = icon.replace('${model}', utils.sanitizeImageParameter(device.definition.model));
}
Expand Down
1 change: 0 additions & 1 deletion lib/extension/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ abstract class Extension {
/**
* Is called once the extension has to start
*/
/* istanbul ignore next */
async start(): Promise<void> {}

/**
Expand Down
1 change: 0 additions & 1 deletion lib/extension/externalJS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ export default abstract class ExternalJSExtension<M> extends Extension {
}

for (const fileName of fs.readdirSync(this.basePath)) {
/* istanbul ignore else */
if (fileName.endsWith('.js')) {
yield {name: fileName, code: this.getFileCode(fileName)};
}
Expand Down
13 changes: 6 additions & 7 deletions lib/extension/frontend.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import type {IncomingMessage, Server, ServerResponse} from 'node:http';
import type {Socket} from 'node:net';

import type {RequestHandler} from 'express-static-gzip';

import assert from 'node:assert';
import {existsSync, readFileSync} from 'node:fs';
import {createServer} from 'node:http';
Expand All @@ -9,7 +11,7 @@ import {posix} from 'node:path';
import {parse} from 'node:url';

import bind from 'bind-decorator';
import expressStaticGzip, {RequestHandler} from 'express-static-gzip';
import expressStaticGzip from 'express-static-gzip';
import finalhandler from 'finalhandler';
import stringify from 'json-stable-stringify-without-jsonify';
import WebSocket from 'ws';
Expand Down Expand Up @@ -71,18 +73,19 @@ export default class Frontend extends Extension {
}

override async start(): Promise<void> {
/* istanbul ignore next */
const options = {
enableBrotli: true,
// TODO: https://github.com/Koenkk/zigbee2mqtt/issues/24654 - enable compressed index serving when express-static-gzip is fixed.
index: false,
serveStatic: {
index: 'index.html',
/* v8 ignore start */
setHeaders: (res: ServerResponse, path: string): void => {
if (path.endsWith('index.html')) {
res.setHeader('Cache-Control', 'no-store');
}
},
/* v8 ignore stop */
},
};
this.fileServer = expressStaticGzip(frontend.getPath(), options);
Expand Down Expand Up @@ -172,7 +175,6 @@ export default class Frontend extends Extension {
});

for (const [topic, payload] of Object.entries(this.mqtt.retainedMessages)) {
/* istanbul ignore else */
if (topic.startsWith(`${this.mqttBaseTopic}/`)) {
ws.send(
stringify({
Expand All @@ -188,9 +190,8 @@ export default class Frontend extends Extension {
const payload = this.state.get(device);
const lastSeen = settings.get().advanced.last_seen;

/* istanbul ignore if */
if (lastSeen !== 'disable') {
payload.last_seen = utils.formatDate(device.zh.lastSeen ?? 0, lastSeen);
payload.last_seen = utils.formatDate(device.zh.lastSeen ?? /* v8 ignore next */ 0, lastSeen);
}

if (device.zh.linkquality !== undefined) {
Expand All @@ -202,14 +203,12 @@ export default class Frontend extends Extension {
}

@bind private onMQTTPublishMessage(data: eventdata.MQTTMessagePublished): void {
/* istanbul ignore else */
if (data.topic.startsWith(`${this.mqttBaseTopic}/`)) {
// Send topic without base_topic
const topic = data.topic.substring(this.mqttBaseTopic.length + 1);
const payload = utils.parseJSON(data.payload, data.payload);

for (const client of this.wss.clients) {
/* istanbul ignore else */
if (client.readyState === WebSocket.OPEN) {
client.send(stringify({topic, payload}));
}
Expand Down
1 change: 0 additions & 1 deletion lib/extension/groups.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ export default class Groups extends Extension {
if (entity instanceof Device) {
const endpoint = entity.endpoint(endpointName);

/* istanbul ignore else */
if (endpoint) {
for (const group of groups) {
if (
Expand Down
Loading
Loading