UNPKG

zwave-js

Version:

Z-Wave driver written entirely in JavaScript/TypeScript

106 lines 4.25 kB
import { fs } from "@zwave-js/core/bindings/fs/node"; import { copyFilesRecursive, noop } from "@zwave-js/shared"; import { wait } from "alcalzone-shared/async"; import crypto from "node:crypto"; import fsp from "node:fs/promises"; import os from "node:os"; import path from "node:path"; import { test } from "vitest"; import { prepareDriver, prepareMocks } from "./integrationTestSuiteShared.js"; function suite(name, options, modifier) { const { controllerCapabilities, nodeCapabilities, customSetup, testBody, debug = false, provisioningDirectory, clearMessageStatsBeforeTest = true, additionalDriverOptions, } = options; let driver; let node; let mockPort; let serial; let continueStartup; let mockController; let mockNode; const cacheDir = path.join(os.tmpdir(), `zjs_test_cache_${crypto.randomBytes(4).toString("hex")}`); async function prepareTest() { if (debug) { console.log(`Running integration test in directory ${cacheDir}`); } // Make sure every test is starting fresh await fsp.rm(cacheDir, { recursive: true, force: true }).catch(noop); await fsp.mkdir(cacheDir, { recursive: true }); // And potentially provision the cache if (provisioningDirectory) { await copyFilesRecursive(fs, provisioningDirectory, cacheDir); } ({ driver, continueStartup, mockPort, serial } = await prepareDriver(cacheDir, debug, additionalDriverOptions)); ({ mockController, mockNodes: [mockNode], } = await prepareMocks(mockPort, serial, { capabilities: controllerCapabilities, securityKeys: driver.options.securityKeys, }, [ { id: 2, capabilities: nodeCapabilities, }, ])); if (customSetup) { await customSetup(driver, mockController, mockNode); } return new Promise((resolve) => { driver.once("driver ready", () => { // Test code goes here const onReady = () => { if (clearMessageStatsBeforeTest) { mockNode.clearReceivedControllerFrames(); mockNode.clearSentControllerFrames(); mockController.clearReceivedHostMessages(); } process.nextTick(resolve); }; node = driver.controller.nodes.getOrThrow(mockNode.id); if (options.additionalDriverOptions?.testingHooks ?.skipNodeInterview) { onReady(); } else { node.once("ready", onReady); } }); if (options.additionalDriverOptions?.bootloaderMode === "stay" || options.additionalDriverOptions?.bootloaderMode === "allow") { driver.once("bootloader ready", () => { process.nextTick(resolve); }); } continueStartup(); }); } // Integration tests need to run in serial, or they might block the serial port on CI const fn = modifier === "only" ? test.sequential.only : modifier === "skip" ? test.sequential.skip : test.sequential; fn(name, async (t) => { t.onTestFinished(async () => { // Give everything a chance to settle before destroying the driver. await wait(100); await driver.destroy(); if (!debug) { await fsp.rm(cacheDir, { recursive: true, force: true }) .catch(noop); } }); await prepareTest(); await testBody(t, driver, node, mockController, mockNode); }, 30000); } /** Performs an integration test with a real driver using a mock controller and one mock node */ export const integrationTest = ((name, options) => { suite(name, options); }); integrationTest.only = (name, options) => { suite(name, options, "only"); }; integrationTest.skip = (name, options) => { suite(name, options, "skip"); }; //# sourceMappingURL=integrationTestSuite.js.map