Skip to content

Commit

Permalink
feat: Use Vitest for testing (#25284)
Browse files Browse the repository at this point in the history
Co-authored-by: Koen Kanters <[email protected]>
  • Loading branch information
Nerivec and Koenkk authored Dec 22, 2024
1 parent 5d059b7 commit 06f4453
Show file tree
Hide file tree
Showing 51 changed files with 2,762 additions and 4,927 deletions.
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

0 comments on commit 06f4453

Please sign in to comment.