From 3a400744a9405bb2d2e0d65b08333436f538266a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Bonnargent?= Date: Fri, 3 Jul 2020 15:03:49 +0200 Subject: [PATCH 1/5] Unit tests draft --- package.json | 6 +- src/hubs/lpf2hub.ts | 8 +- test/hubs.ts | 21 ++++++ test/hubs/duplotrainbase.ts | 15 ++++ test/hubs/hub.ts | 25 +++++++ test/hubs/lpf2.ts | 136 ++++++++++++++++++++++++++++++++++ test/hubs/movehub.ts | 26 +++++++ test/hubs/remotecontrol.ts | 15 ++++ test/hubs/technicmediumhub.ts | 21 ++++++ test/test.ts | 6 ++ test/utils/commons.ts | 32 ++++++++ test/utils/fakebledevice.ts | 103 +++++++++++++++++++++++++ 12 files changed, 411 insertions(+), 3 deletions(-) create mode 100644 test/hubs.ts create mode 100644 test/hubs/duplotrainbase.ts create mode 100644 test/hubs/hub.ts create mode 100644 test/hubs/lpf2.ts create mode 100644 test/hubs/movehub.ts create mode 100644 test/hubs/remotecontrol.ts create mode 100644 test/hubs/technicmediumhub.ts create mode 100644 test/test.ts create mode 100644 test/utils/commons.ts create mode 100644 test/utils/fakebledevice.ts diff --git a/package.json b/package.json index d19e3eaf..2f84d350 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,8 @@ "build:all": "tslint -c tslint.json \"./src/**/*.ts\" && tsc && webpack --mode=production", "docs": "jsdoc -d docs -c jsdoc.conf.json -t ./node_modules/ink-docstrap/template -R README.md dist/node/**/*.js", "all": "npm run build:all && npm run docs", - "prepublishOnly": "npm run build:node" + "prepublishOnly": "npm run build:node", + "test": "ts-mocha test/*.ts" }, "author": "Nathan Kellenicki ", "license": "MIT", @@ -22,12 +23,15 @@ }, "devDependencies": { "@types/debug": "4.1.5", + "@types/mocha": "^7.0.2", "@types/node": "^14.0.13", "@types/web-bluetooth": "0.0.6", "ink-docstrap": "^1.3.2", "jsdoc": "^3.6.4", "jsdoc-to-markdown": "^6.0.1", + "mocha": "^8.0.1", "ts-loader": "^7.0.5", + "ts-mocha": "^7.0.0", "tslint": "^6.1.2", "typescript": "^3.9.5", "webpack": "^4.43.0", diff --git a/src/hubs/lpf2hub.ts b/src/hubs/lpf2hub.ts index 7f93ac9c..c9a3c38a 100644 --- a/src/hubs/lpf2hub.ts +++ b/src/hubs/lpf2hub.ts @@ -174,9 +174,13 @@ export class LPF2Hub extends BaseHub { private _requestHubPropertyValue (property: number) { - return new Promise((resolve) => { + return new Promise((resolve, reject) => { this._propertyRequestCallbacks[property] = (message) => { - this._parseHubPropertyResponse(message); + try { + this._parseHubPropertyResponse(message); + } catch (error) { + return reject(error); + } return resolve(); }; this.send(Buffer.from([0x01, property, 0x05]), Consts.BLECharacteristic.LPF2_ALL); diff --git a/test/hubs.ts b/test/hubs.ts new file mode 100644 index 00000000..9ef1e76a --- /dev/null +++ b/test/hubs.ts @@ -0,0 +1,21 @@ +import { FakeBLEDevice } from "./utils/fakebledevice"; +import {commonsConnectTests } from './utils/commons'; + +import { DuploTrainBase } from "../src/hubs/duplotrainbase"; + +import moveHub from "./hubs/movehub"; +import technicMediumHub from "./hubs/technicmediumhub"; +import hub from "./hubs/hub"; +import duploTrainBase from "./hubs/duplotrainbase"; +import remoteControl from "./hubs/remoteControl"; +import lpf2Hub from "./hubs/lpf2"; + + +export default function hubs() { + describe("Technic Medium Hub", technicMediumHub); + describe("PoweredUp Hub", hub); + describe("Boost Move Hub", moveHub); + describe("Duplo Train Base", duploTrainBase); + describe("Remote controller", remoteControl); + describe("Common LPF2 methods", lpf2Hub); +}; diff --git a/test/hubs/duplotrainbase.ts b/test/hubs/duplotrainbase.ts new file mode 100644 index 00000000..1ba5cab3 --- /dev/null +++ b/test/hubs/duplotrainbase.ts @@ -0,0 +1,15 @@ +import { FakeBLEDevice } from "../utils/fakebledevice"; +import {commonsConnectTests } from '../utils/commons'; + +import { DuploTrainBase } from "../../src/hubs/duplotrainbase"; + +export default function duploTrainBase() { + const state = { connectEvent: false }; + const bleDevice = new FakeBLEDevice("fakebledevice", "Duplo Train Base") + const hub = new DuploTrainBase(bleDevice); + hub.on("connect", () => state.connectEvent = true); + describe("connect", () => { + before(async () => await hub.connect()); + commonsConnectTests(state, hub, bleDevice); + }); +} diff --git a/test/hubs/hub.ts b/test/hubs/hub.ts new file mode 100644 index 00000000..20926a99 --- /dev/null +++ b/test/hubs/hub.ts @@ -0,0 +1,25 @@ +import { rejects } from "assert"; + +import { FakeBLEDevice } from "../utils/fakebledevice"; +import {commonsConnectTests } from '../utils/commons'; + +import { Hub } from "../../src/hubs/hub"; + +export default function hub() { + const state = { connectEvent: false }; + const bleDevice = new FakeBLEDevice("fakebledevice", "PoweredUp Hub", "1.1.00.0004") + const hub = new Hub(bleDevice); + hub.on("connect", () => state.connectEvent = true); + + describe("connect", () => { + before(async () => await hub.connect()); + it("should reject due to unsupported firmware (<1.1.00.0004)", async () => { + let badHub = new Hub(new FakeBLEDevice("fakebledevice", "PoweredUp Hub", "1.1.00.0003")); + await rejects( + async () => await badHub.connect(), + { name: "Error", message: "Your Powered Up Hub's (PoweredUp Hub) firmware is out of date and unsupported by this library. Please update it via the official Powered Up app." } + ) + }); + commonsConnectTests(state, hub, bleDevice, "1.1.00.0004"); + }); +} diff --git a/test/hubs/lpf2.ts b/test/hubs/lpf2.ts new file mode 100644 index 00000000..e609dd61 --- /dev/null +++ b/test/hubs/lpf2.ts @@ -0,0 +1,136 @@ +import { equal, ok } from "assert"; + +import { FakeBLEDevice } from "../utils/fakebledevice"; +import { getAttachMessage } from "../utils/commons"; + +import { LPF2Hub } from "../../src/hubs/lpf2hub"; +import * as Consts from "../../src/consts"; + +import { Device } from "../../src/devices/device" +import { ColorDistanceSensor } from "../../src/devices/colordistancesensor" +import { SimpleMediumLinearMotor } from "../../src/devices/simplemediumlinearmotor"; +import { TrainMotor } from "../../src/devices/trainmotor"; +import { Light } from "../../src/devices/light"; +import { VoltageSensor } from "../../src/devices/voltagesensor"; +import { CurrentSensor } from "../../src/devices/currentsensor"; +import { PiezoBuzzer } from "../../src/devices/piezobuzzer"; +import { HubLED } from "../../src/devices/hubled"; +import { TiltSensor } from "../../src/devices/tiltsensor"; +import { MotionSensor } from "../../src/devices/motionsensor"; +import { MediumLinearMotor } from "../../src/devices/mediumlinearmotor"; +import { MoveHubMediumLinearMotor } from "../../src/devices/movehubmediumlinearmotor"; +import { MoveHubTiltSensor } from "../../src/devices/movehubtiltsensor"; +import { DuploTrainBaseMotor } from "../../src/devices/duplotrainbasemotor"; +import { DuploTrainBaseSpeaker } from "../../src/devices/duplotrainbasespeaker"; +import { DuploTrainBaseColorSensor } from "../../src/devices/duplotrainbasecolorsensor"; +import { DuploTrainBaseSpeedometer } from "../../src/devices/duplotrainbasespeedometer"; +import { TechnicLargeLinearMotor } from "../../src/devices/techniclargelinearmotor"; +import { TechnicLargeAngularMotor } from "../../src/devices/techniclargeangularmotor"; +import { TechnicMediumAngularMotor } from "../../src/devices/technicmediumangularmotor"; +import { TechnicXLargeLinearMotor } from "../../src/devices/technicxlargelinearmotor"; +import { RemoteControlButton } from "../../src/devices/remotecontrolbutton"; +import { TechnicMediumHubAccelerometerSensor } from "../../src/devices/technicmediumhubaccelerometersensor"; +import { TechnicMediumHubGyroSensor } from "../../src/devices/technicmediumhubgyrosensor"; +import { TechnicMediumHubTiltSensor } from "../../src/devices/technicmediumhubtiltsensor"; +import { TechnicColorSensor } from "../../src/devices/techniccolorsensor"; +import { TechnicDistanceSensor } from "../../src/devices/technicdistancesensor"; +import { TechnicForceSensor } from "../../src/devices/technicforcesensor"; + +export default function lpf2Hub() { + let bleDevice: FakeBLEDevice + let hub: LPF2Hub; + + function deviceAttach(type: number, Constructor: typeof Device) { + return () => { + it("should emit an 'attach' event with device", done => { + hub.on("attach", device => { + equal(device.type, type); + ok(device instanceof Constructor); + done(); + }); + + bleDevice.send(getAttachMessage(0, type)); + }); + + it("should resolve 'waitForDeviceByType'", done => { + hub.waitForDeviceByType(type).then((d) => { + const device = d as Device; + equal(device.type, type); + ok(device instanceof Constructor); + done(); + }); + + bleDevice.send(getAttachMessage(0, type)); + }); + }; + } + + beforeEach(async () => { + bleDevice = new FakeBLEDevice("fakebledevice", "LPF2 Hub"); + hub = new LPF2Hub(bleDevice, {A: 0, B: 1}); + await hub.connect() + }); + + describe("attach", () => { + describe("waitForDeviceAtPort", () => { + it("should resolve with already attached device", async () => { + await bleDevice.send(getAttachMessage(0, Consts.DeviceType.UNKNOWN)); + const device = await hub.waitForDeviceAtPort("A") as Device; + + equal(device.type, Consts.DeviceType.UNKNOWN); + ok(device instanceof Device); + return; + }); + + it("should resolve when device attached", done => { + hub.waitForDeviceAtPort("A").then(d=> { + const device = d as Device; + equal(device.type, Consts.DeviceType.UNKNOWN); + ok(device instanceof Device); + done(); + }); + bleDevice.send(getAttachMessage(0, Consts.DeviceType.UNKNOWN)); + }); + }); + + describe("Simple Medium Linear Motor", deviceAttach(Consts.DeviceType.SIMPLE_MEDIUM_LINEAR_MOTOR, SimpleMediumLinearMotor)); + describe("Train Motor", deviceAttach(Consts.DeviceType.TRAIN_MOTOR, TrainMotor)); + describe("Light", deviceAttach(Consts.DeviceType.LIGHT, Light)); + describe("Voltage sensor", deviceAttach(Consts.DeviceType.VOLTAGE_SENSOR, VoltageSensor)); + describe("Current sensor", deviceAttach(Consts.DeviceType.CURRENT_SENSOR, CurrentSensor)); + describe("Piezzo buzzer", deviceAttach(Consts.DeviceType.PIEZO_BUZZER, PiezoBuzzer)); + describe("Hub LED", deviceAttach(Consts.DeviceType.HUB_LED, HubLED)); + describe("Tilt sensor", deviceAttach(Consts.DeviceType.TILT_SENSOR, TiltSensor)); + describe("Motion sensor", deviceAttach(Consts.DeviceType.MOTION_SENSOR, MotionSensor)); + describe("Color and distance sensor", deviceAttach(Consts.DeviceType.COLOR_DISTANCE_SENSOR, ColorDistanceSensor)); + describe("Medium linear motor", deviceAttach(Consts.DeviceType.MEDIUM_LINEAR_MOTOR, MediumLinearMotor)); + describe("Move hub medium linear motor", deviceAttach(Consts.DeviceType.MOVE_HUB_MEDIUM_LINEAR_MOTOR, MoveHubMediumLinearMotor)); + describe("Move hub tilt sensor", deviceAttach(Consts.DeviceType.MOVE_HUB_TILT_SENSOR, MoveHubTiltSensor)); + describe("Duplo train base motor", deviceAttach(Consts.DeviceType.DUPLO_TRAIN_BASE_MOTOR, DuploTrainBaseMotor)); + describe("Duplo train base speaker", deviceAttach(Consts.DeviceType.DUPLO_TRAIN_BASE_SPEAKER, DuploTrainBaseSpeaker)); + describe("Duplo train base color sensor", deviceAttach(Consts.DeviceType.DUPLO_TRAIN_BASE_COLOR_SENSOR, DuploTrainBaseColorSensor)); + describe("Duplo train base speedometer", deviceAttach(Consts.DeviceType.DUPLO_TRAIN_BASE_SPEEDOMETER, DuploTrainBaseSpeedometer)); + describe("Technic large linear motor", deviceAttach(Consts.DeviceType.TECHNIC_LARGE_LINEAR_MOTOR, TechnicLargeLinearMotor)); + describe("Technic XL linear motor", deviceAttach(Consts.DeviceType.TECHNIC_XLARGE_LINEAR_MOTOR, TechnicXLargeLinearMotor)); + describe("Technic medium angular motor", deviceAttach(Consts.DeviceType.TECHNIC_MEDIUM_ANGULAR_MOTOR, TechnicMediumAngularMotor)); + describe("Technic large angular motor", deviceAttach(Consts.DeviceType.TECHNIC_LARGE_ANGULAR_MOTOR, TechnicLargeAngularMotor)); + describe("Remote controller button", deviceAttach(Consts.DeviceType.REMOTE_CONTROL_BUTTON, RemoteControlButton)); + describe("Remote controller RSSI - Generic device", deviceAttach(Consts.DeviceType.REMOTE_CONTROL_RSSI, Device)); + describe("Technic medium hub accelerometer", deviceAttach(Consts.DeviceType.TECHNIC_MEDIUM_HUB_ACCELEROMETER, TechnicMediumHubAccelerometerSensor)); + describe("Technic medium hub gyro sensor", deviceAttach(Consts.DeviceType.TECHNIC_MEDIUM_HUB_GYRO_SENSOR, TechnicMediumHubGyroSensor)); + describe("Technic medium hub tilt sensor", deviceAttach(Consts.DeviceType.TECHNIC_MEDIUM_HUB_TILT_SENSOR, TechnicMediumHubTiltSensor)); + describe("Technic medium hub temperature sensor - Generic device", deviceAttach(Consts.DeviceType.TECHNIC_MEDIUM_HUB_TEMPERATURE_SENSOR, Device)); + describe("Technic color sensor", deviceAttach(Consts.DeviceType.TECHNIC_COLOR_SENSOR, TechnicColorSensor)); + describe("Technic distance sensor", deviceAttach(Consts.DeviceType.TECHNIC_DISTANCE_SENSOR, TechnicDistanceSensor)); + describe("Technic force sensor", deviceAttach(Consts.DeviceType.TECHNIC_FORCE_SENSOR, TechnicForceSensor)); + describe("Technic medium angular motor (grey) - Generic device", deviceAttach(Consts.DeviceType.TECHNIC_MEDIUM_ANGULAR_MOTOR_GREY, Device)); + describe("Technic large angular motor (grey) - Generic device", deviceAttach(Consts.DeviceType.TECHNIC_LARGE_ANGULAR_MOTOR_GREY, Device)); + }); + + describe("shutdown", () => { + it("should send shutdown message", async () => { + await hub.shutdown(); + ok((bleDevice.messages[Consts.BLECharacteristic.LPF2_ALL] || []).includes("04000201")) + }); + }); +} diff --git a/test/hubs/movehub.ts b/test/hubs/movehub.ts new file mode 100644 index 00000000..f7dc0cc8 --- /dev/null +++ b/test/hubs/movehub.ts @@ -0,0 +1,26 @@ +import { rejects } from "assert"; + +import { FakeBLEDevice } from "../utils/fakebledevice"; +import {commonsConnectTests } from '../utils/commons'; + +import { MoveHub } from "../../src/hubs/movehub"; + +export default function moveHub() { + const state = { connectEvent: false }; + const bleDevice = new FakeBLEDevice("fakebledevice", "Boost Move Hub", "2.0.00.0017") + const hub = new MoveHub(bleDevice); + hub.on("connect", () => state.connectEvent = true); + + describe("connect", () => { + before(async () => await hub.connect()); + it("should reject due to unsupported firmware (<2.0.00.0017)", async () => { + let badHub = new MoveHub(new FakeBLEDevice("fakebledevice", "PoweredUp Hub", "2.0.00.0016")); + await rejects( + async () => await badHub.connect(), + { name: "Error", message: "Your Move Hub's (PoweredUp Hub) firmware is out of date and unsupported by this library. Please update it via the official Powered Up app." } + ) + }); + commonsConnectTests(state, hub, bleDevice, "2.0.00.0017"); + }); + +} diff --git a/test/hubs/remotecontrol.ts b/test/hubs/remotecontrol.ts new file mode 100644 index 00000000..7938186b --- /dev/null +++ b/test/hubs/remotecontrol.ts @@ -0,0 +1,15 @@ +import { FakeBLEDevice } from "../utils/fakebledevice"; +import {commonsConnectTests } from '../utils/commons'; + +import { RemoteControl } from "../../src/hubs/remotecontrol"; + +export default function remoteControl() { + const state = { connectEvent: false }; + const bleDevice = new FakeBLEDevice("fakebledevice", "Remote controller") + const hub = new RemoteControl(bleDevice); + hub.on("connect", () => state.connectEvent = true); + describe("connect", () => { + before(async () => await hub.connect()); + commonsConnectTests(state, hub, bleDevice); + }); +} diff --git a/test/hubs/technicmediumhub.ts b/test/hubs/technicmediumhub.ts new file mode 100644 index 00000000..c3dcc1b0 --- /dev/null +++ b/test/hubs/technicmediumhub.ts @@ -0,0 +1,21 @@ +import { ok } from "assert"; + +import { FakeBLEDevice } from "../utils/fakebledevice"; +import {commonsConnectTests } from '../utils/commons'; + +import { TechnicMediumHub } from "../../src/hubs/technicmediumhub"; +import * as Consts from "../../src/consts"; + +export default function technicMediumHub() { + const state = { connectEvent: false }; + const bleDevice = new FakeBLEDevice("fakebledevice", "Technic Medium Hub") + const hub = new TechnicMediumHub(bleDevice); + hub.on("connect", () => state.connectEvent = true); + + describe("connect", () => { + before(async () => await hub.connect()); + commonsConnectTests(state, hub, bleDevice); + it("should have subscribed to temperature updates", () => ok(bleDevice.messages[Consts.BLECharacteristic.LPF2_ALL].includes("0a00413d000a00000001"))); + }); + +} diff --git a/test/test.ts b/test/test.ts new file mode 100644 index 00000000..0240ca66 --- /dev/null +++ b/test/test.ts @@ -0,0 +1,6 @@ +import { equal, ok, rejects } from "assert"; + +import hubs from "./hubs"; + + +describe("Hubs", hubs); diff --git a/test/utils/commons.ts b/test/utils/commons.ts new file mode 100644 index 00000000..1f1946f7 --- /dev/null +++ b/test/utils/commons.ts @@ -0,0 +1,32 @@ +import { equal, ok } from "assert"; + +import { FakeBLEDevice } from "./fakebledevice"; +import { BaseHub } from "../../src/index-node"; +import * as Consts from "../../src/consts"; + +export function commonsConnectTests(state = { connectEvent: false }, hub: BaseHub, bleDevice: FakeBLEDevice, firmware = "1.0.00.0000") { + it("should have emmited a connect event", () => ok(state.connectEvent)); + it(`should have a uuid (${bleDevice.uuid})`, () => equal(hub.uuid, bleDevice.uuid)); + it(`should have a name (${bleDevice.name})`, () => equal(hub.name, bleDevice.name)); + it(`should have a firmware revision (${firmware})`, () => equal(hub.firmwareVersion, firmware)); + it("should have a hardware revision (1.0.00.0000)", () => equal(hub.hardwareVersion, "1.0.00.0000")); + it("should have as primary mac address (00:00:00:00:00:00)", () => equal(hub.primaryMACAddress, "00:00:00:00:00:00")); + it("should have subscribed to BUTTON updates", () => ok(bleDevice.messages[Consts.BLECharacteristic.LPF2_ALL].includes("0500010202"))); + it("should have subscribed to RSSI updates", () => ok(bleDevice.messages[Consts.BLECharacteristic.LPF2_ALL].includes("0500010502"))); + it("should have subscribed to battery level updates", () => ok(bleDevice.messages[Consts.BLECharacteristic.LPF2_ALL].includes("0500010602"))); +} + +export function versionToInt32(version: string): number { + return parseInt(version.replace(/\./g, ''), 16); +} + +export function getAttachMessage(port: number, type: number, firmware: string = "1.0.00.0000", hardware: string = "1.0.00.0000"): Buffer { + const message = Buffer.alloc(13); + message[0] = 0x04; // port event + message[1] = port; + message[2] = 0x01; // attach event + message.writeUInt16LE(type, 3); + message.writeUInt32LE(versionToInt32(firmware), 5); + message.writeUInt32LE(versionToInt32(hardware), 9); + return message; +} diff --git a/test/utils/fakebledevice.ts b/test/utils/fakebledevice.ts new file mode 100644 index 00000000..a07153fa --- /dev/null +++ b/test/utils/fakebledevice.ts @@ -0,0 +1,103 @@ +import { EventEmitter } from "events"; + +import { versionToInt32 } from './commons'; +import { IBLEAbstraction } from "../../src/interfaces"; + +import * as Consts from '../../src/consts'; + +export class FakeBLEDevice extends EventEmitter implements IBLEAbstraction { + private _uuid: string; + private _name: string; + private _firmware: string; + private _hardware: string; + + + private _connecting: boolean = false; + private _connected: boolean = false; + private _handlers: {[characteristic: string]: ((message: Buffer) => void)[]} = {} + private _incommingMessages: {[characteristic: string]: string[]} = {}; + + constructor(uuid: string, name: string, firmware: string = '1.0.00.0000', hardware: string = '1.0.00.0000') { + super(); + this._uuid = uuid; + this._name = name; + this._firmware = firmware; + this._hardware = hardware; + } + + public get uuid() { return this._uuid } + public get name() { return this._name } + public get connecting() { return this._connecting } + public get connected() { return this._connected } + + public connect(): Promise { + this.emit('connect'); + this._connecting = true; + return new Promise(resolve => { + setTimeout(() => { + this._connected = true; + this.emit('connected'); + resolve(); + }, 10); + }); + }; + public async disconnect() { + this._connected = false; + this.emit('disconnected'); + }; + + public async discoverCharacteristicsForService(uuid: string) { + this.emit('discoverCharacteristicsForService', { uuid }) + }; + + public async subscribeToCharacteristic(uuid: string, handler: (message: Buffer) => void) { + this._handlers[uuid] = this._handlers[uuid] || []; + this._handlers[uuid].push(handler) + }; + + public async writeToCharacteristic(uuid: string, message: Buffer) { + this._incommingMessages[uuid] = this._incommingMessages[uuid] || []; + this._incommingMessages[uuid].push(message.toString('hex')); + this.emit('writeToCharacteristic', { uuid, message }); + + // Some messages need reply + if (uuid === Consts.BLECharacteristic.LPF2_ALL) { + const hex = message.toString('hex') + switch (hex) { + case '0500010305': { // firmware version + const message = Buffer.from([0x01, 0x03, 0x06, 0x00, 0x00, 0x00, 0x00]); + message.writeInt32LE(versionToInt32(this._firmware), 3); + this.send(message); + break; + } + case '0500010405': { // hardware version + const message = Buffer.from([0x01, 0x04, 0x06, 0x00, 0x00, 0x00, 0x00]); + message.writeInt32LE(versionToInt32(this._hardware), 3); + this.send(message); + break; + } + case '0500010d05': { // primary MAC address 00:00:00:00:00:00 + this.send(Buffer.from([0x01, 0x0d, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])); + break; + } + } + } + }; + + public async addToCharacteristicMailbox() {}; + public async readFromCharacteristic() {}; + + public send(message: Buffer, uuid:string = Consts.BLECharacteristic.LPF2_ALL) { + message = Buffer.concat([Buffer.from([message.length + 2, 0x00]), message]) + return new Promise(resolve => { + setTimeout( + () => { + (this._handlers[uuid] || []).forEach(callback => callback(message)) + resolve(); + }, + 10 + ) + }) + }; + public get messages() { return this._incommingMessages; } +}; From 1b763f679a819603ff0560b3ac8a2dd5b48fc817 Mon Sep 17 00:00:00 2001 From: aileo Date: Mon, 25 Jan 2021 15:21:06 +0100 Subject: [PATCH 2/5] Fix tsconfig to exclude test --- tsconfig.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tsconfig.json b/tsconfig.json index 965e4a6c..0b19fcdc 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -55,5 +55,6 @@ /* Experimental Options */ // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ - } + }, + "exclude": ["test", "dist"] } \ No newline at end of file From 8a968f6dc39960363059310d61d6f5fd99ebedc6 Mon Sep 17 00:00:00 2001 From: aileo Date: Mon, 25 Jan 2021 15:26:03 +0100 Subject: [PATCH 3/5] Add tests to linter --- package-lock.json | 561 +++++++++++++++++++++++++++++++++++- package.json | 2 +- test/hubs.ts | 7 +- test/hubs/hub.ts | 2 +- test/hubs/movehub.ts | 2 +- test/utils/fakebledevice.ts | 6 +- 6 files changed, 559 insertions(+), 21 deletions(-) diff --git a/package-lock.json b/package-lock.json index 14081636..4b9a723b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -97,6 +97,19 @@ "integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==", "dev": true }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true, + "optional": true + }, + "@types/mocha": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", + "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==", + "dev": true + }, "@types/node": { "version": "14.14.14", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.14.tgz", @@ -109,6 +122,12 @@ "integrity": "sha512-P6oHnRSEqRCR1fdAtJXmKBiHE3fOWtNFyfjm9NQZPrxdQjSZgRSiKRiHjLyKBh8eCvM8ldDS8/VJN0qKg0Pk1Q==", "dev": true }, + "@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, "@webassemblyjs/ast": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.1.tgz", @@ -364,6 +383,12 @@ } } }, + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -373,6 +398,16 @@ "color-convert": "^1.9.0" } }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, "aproba": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", @@ -404,6 +439,12 @@ "integrity": "sha512-Z/JnaVEXv+A9xabHzN43FiiiWEE7gPCRXMrVmRm00tWbjZRul1iHm7ECzlyNq1p4a4ATXz+G9FJ3GqGOkOV3fg==", "dev": true }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -420,6 +461,12 @@ "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", "dev": true }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, "bindings": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", @@ -487,6 +534,12 @@ "fill-range": "^7.0.1" } }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, "browserslist": { "version": "4.16.0", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.0.tgz", @@ -541,6 +594,12 @@ "mkdirp2": "^1.0.4" } }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, "caniuse-lite": { "version": "1.0.30001170", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001170.tgz", @@ -567,6 +626,22 @@ "supports-color": "^5.3.0" } }, + "chokidar": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz", + "integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.5.0" + } + }, "chownr": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", @@ -582,6 +657,17 @@ "tslib": "^1.9.0" } }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, "code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", @@ -761,6 +847,12 @@ "ms": "2.1.2" } }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, "decompress-response": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", @@ -869,6 +961,12 @@ "integrity": "sha512-LkaEH9HHr9fodmm3txF4nFMyHN3Yr50HcpD/DBHpLCxzM9doV8AV0er6aBWva4IDs2aA9kGguces0rp+WKL7rg==", "dev": true }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, "emojis-list": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", @@ -1068,6 +1166,12 @@ "path-exists": "^4.0.0" } }, + "flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true + }, "fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", @@ -1094,6 +1198,13 @@ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true + }, "gauge": { "version": "2.7.4", "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", @@ -1147,6 +1258,12 @@ } } }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, "get-stream": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", @@ -1175,6 +1292,15 @@ "path-is-absolute": "^1.0.0" } }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, "glob-to-regexp": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", @@ -1187,6 +1313,12 @@ "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", "dev": true }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true + }, "handlebars": { "version": "4.7.6", "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.6.tgz", @@ -1212,6 +1344,12 @@ "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", "optional": true }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, "htmlparser2": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-4.1.0.tgz", @@ -1348,11 +1486,34 @@ "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", "dev": true }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "optional": true + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } }, "is-number": { "version": "7.0.0", @@ -1360,6 +1521,12 @@ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, + "is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true + }, "is-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", @@ -1607,6 +1774,72 @@ "integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=", "dev": true }, + "log-symbols": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", + "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", + "dev": true, + "requires": { + "chalk": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, "markdown-it": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz", @@ -1741,6 +1974,71 @@ "integrity": "sha512-Q2PKB4ZR4UPtjLl76JfzlgSCUZhSV1AXQgAZa1qt5RiaALFjP/CDrGvFBrOz7Ck6McPcwMAxTsJvWOUjOU8XMw==", "dev": true }, + "mocha": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.2.1.tgz", + "integrity": "sha512-cuLBVfyFfFqbNR0uUKbDGXKGk+UDFe6aR4os78XIrMQpZl/nv7JYHcvP5MFIAb374b2zFXsdgEGwmzMtP0Xg8w==", + "dev": true, + "requires": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.4.3", + "debug": "4.2.0", + "diff": "4.0.2", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.1.6", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "3.14.0", + "log-symbols": "4.0.0", + "minimatch": "3.0.4", + "ms": "2.1.2", + "nanoid": "3.1.12", + "serialize-javascript": "5.0.1", + "strip-json-comments": "3.1.1", + "supports-color": "7.2.0", + "which": "2.0.2", + "wide-align": "1.1.3", + "workerpool": "6.0.2", + "yargs": "13.3.2", + "yargs-parser": "13.1.2", + "yargs-unparser": "2.0.0" + }, + "dependencies": { + "debug": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", + "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "moment": { "version": "2.26.0", "resolved": "https://registry.npmjs.org/moment/-/moment-2.26.0.tgz", @@ -1758,6 +2056,12 @@ "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==", "optional": true }, + "nanoid": { + "version": "3.1.12", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.12.tgz", + "integrity": "sha512-1qstj9z5+x491jfiC4Nelk+f8XBad7LN20PmyWINJEMRSf3wcAjAWysw1qaA8z6NSKe2sjq1hRSDpBH5paCb6A==", + "dev": true + }, "napi-build-utils": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", @@ -1876,6 +2180,12 @@ "osenv": "^0.1.4" } }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, "npm-bundled": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.1.tgz", @@ -2173,6 +2483,15 @@ "util-deprecate": "~1.0.1" } }, + "readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, "rechoir": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.0.tgz", @@ -2254,6 +2573,18 @@ } } }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, "requizzle": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.3.tgz", @@ -2356,8 +2687,7 @@ "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "optional": true + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" }, "shebang-command": { "version": "2.0.0", @@ -2474,6 +2804,17 @@ "integrity": "sha512-DBp0lSvX5G9KGRDTkR/R+a29H+Wk2xItOF+MpZLLNDWbEV9tGPnqLPxHEYjmiz8xGtJHRIqmI+hCjmNzqoA4nQ==", "dev": true }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -2482,6 +2823,22 @@ "safe-buffer": "~5.1.0" } }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true, + "optional": true + }, "strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", @@ -2685,6 +3042,62 @@ "semver": "^6.0.0" } }, + "ts-mocha": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/ts-mocha/-/ts-mocha-7.0.0.tgz", + "integrity": "sha512-7WfkQw1W6JZXG5m4E1w2e945uWzBoZqmnOHvpMu0v+zvyKLdUQeTtRMfcQsVEKsUnYL6nTyH4okRt2PZucmFXQ==", + "dev": true, + "requires": { + "ts-node": "7.0.1", + "tsconfig-paths": "^3.5.0" + } + }, + "ts-node": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", + "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", + "dev": true, + "requires": { + "arrify": "^1.0.0", + "buffer-from": "^1.1.0", + "diff": "^3.1.0", + "make-error": "^1.1.1", + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "source-map-support": "^0.5.6", + "yn": "^2.0.0" + }, + "dependencies": { + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + } + } + }, + "tsconfig-paths": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", + "integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==", + "dev": true, + "optional": true, + "requires": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + } + }, "tslib": { "version": "1.13.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", @@ -2995,6 +3408,12 @@ "isexe": "^2.0.0" } }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, "which-pm-runs": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", @@ -3005,7 +3424,6 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "optional": true, "requires": { "string-width": "^1.0.2 || 2" }, @@ -3013,14 +3431,12 @@ "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "optional": true + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "optional": true, "requires": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" @@ -3030,7 +3446,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "optional": true, "requires": { "ansi-regex": "^3.0.0" } @@ -3053,6 +3468,23 @@ "typical": "^2.6.1" } }, + "workerpool": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.0.2.tgz", + "integrity": "sha512-DSNyvOpFKrNusaaUwk+ej6cBj1bmhLcBfj80elGk+ZIo5JSkq+unB1dLKEOcNfJDZgjGICfhQ0Q5TbP0PvF4+Q==", + "dev": true + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -3070,12 +3502,123 @@ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", "dev": true }, + "y18n": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", + "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", + "dev": true + }, "yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "optional": true }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + } + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "requires": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "dependencies": { + "camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true + }, + "decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true + } + } + }, + "yn": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", + "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", + "dev": true + }, "yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index fb65400a..1f95774c 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "build:node": "tsc", "build:browser": "webpack --mode=production", "build:all": "npm run build:node && npm run build:browser", - "lint": "tslint -c tslint.json \"./src/**/*.ts\"", + "lint": "tslint -c tslint.json \"./src/**/*.ts\" \"./test/**/*.ts\"", "build": "npm run lint && npm run build:all", "docs": "jsdoc -d docs -c jsdoc.conf.json -t ./node_modules/ink-docstrap/template -R README.md dist/node/**/*.js", "all": "npm run build:all && npm run docs", diff --git a/test/hubs.ts b/test/hubs.ts index 9ef1e76a..274e5f58 100644 --- a/test/hubs.ts +++ b/test/hubs.ts @@ -1,13 +1,8 @@ -import { FakeBLEDevice } from "./utils/fakebledevice"; -import {commonsConnectTests } from './utils/commons'; - -import { DuploTrainBase } from "../src/hubs/duplotrainbase"; - import moveHub from "./hubs/movehub"; import technicMediumHub from "./hubs/technicmediumhub"; import hub from "./hubs/hub"; import duploTrainBase from "./hubs/duplotrainbase"; -import remoteControl from "./hubs/remoteControl"; +import remoteControl from "./hubs/remotecontrol"; import lpf2Hub from "./hubs/lpf2"; diff --git a/test/hubs/hub.ts b/test/hubs/hub.ts index 20926a99..6a3f74de 100644 --- a/test/hubs/hub.ts +++ b/test/hubs/hub.ts @@ -14,7 +14,7 @@ export default function hub() { describe("connect", () => { before(async () => await hub.connect()); it("should reject due to unsupported firmware (<1.1.00.0004)", async () => { - let badHub = new Hub(new FakeBLEDevice("fakebledevice", "PoweredUp Hub", "1.1.00.0003")); + const badHub = new Hub(new FakeBLEDevice("fakebledevice", "PoweredUp Hub", "1.1.00.0003")); await rejects( async () => await badHub.connect(), { name: "Error", message: "Your Powered Up Hub's (PoweredUp Hub) firmware is out of date and unsupported by this library. Please update it via the official Powered Up app." } diff --git a/test/hubs/movehub.ts b/test/hubs/movehub.ts index f7dc0cc8..0d9fc4e0 100644 --- a/test/hubs/movehub.ts +++ b/test/hubs/movehub.ts @@ -14,7 +14,7 @@ export default function moveHub() { describe("connect", () => { before(async () => await hub.connect()); it("should reject due to unsupported firmware (<2.0.00.0017)", async () => { - let badHub = new MoveHub(new FakeBLEDevice("fakebledevice", "PoweredUp Hub", "2.0.00.0016")); + const badHub = new MoveHub(new FakeBLEDevice("fakebledevice", "PoweredUp Hub", "2.0.00.0016")); await rejects( async () => await badHub.connect(), { name: "Error", message: "Your Move Hub's (PoweredUp Hub) firmware is out of date and unsupported by this library. Please update it via the official Powered Up app." } diff --git a/test/utils/fakebledevice.ts b/test/utils/fakebledevice.ts index a07153fa..a3b26b50 100644 --- a/test/utils/fakebledevice.ts +++ b/test/utils/fakebledevice.ts @@ -84,8 +84,8 @@ export class FakeBLEDevice extends EventEmitter implements IBLEAbstraction { } }; - public async addToCharacteristicMailbox() {}; - public async readFromCharacteristic() {}; + public async addToCharacteristicMailbox() { /** TODO */ }; + public async readFromCharacteristic() { /** TODO */ }; public send(message: Buffer, uuid:string = Consts.BLECharacteristic.LPF2_ALL) { message = Buffer.concat([Buffer.from([message.length + 2, 0x00]), message]) @@ -93,7 +93,7 @@ export class FakeBLEDevice extends EventEmitter implements IBLEAbstraction { setTimeout( () => { (this._handlers[uuid] || []).forEach(callback => callback(message)) - resolve(); + resolve(undefined); }, 10 ) From 3763edf946cab1b436f4528fd52bfb32f22dcec2 Mon Sep 17 00:00:00 2001 From: aileo Date: Mon, 25 Jan 2021 17:12:34 +0100 Subject: [PATCH 4/5] Add HubLED test - improve sent message check - remove temperature subscription test on technicmediumhub - replace equal by strictEqual due to deprecation --- src/hubs/basehub.ts | 4 ++-- test/devices.ts | 6 ++++++ test/devices/hubled.ts | 36 +++++++++++++++++++++++++++++++++++ test/hubs/lpf2.ts | 14 +++++++------- test/hubs/technicmediumhub.ts | 6 +----- test/test.ts | 4 ++-- test/utils/commons.ts | 24 ++++++++++++++--------- 7 files changed, 69 insertions(+), 25 deletions(-) create mode 100644 test/devices.ts create mode 100644 test/devices/hubled.ts diff --git a/src/hubs/basehub.ts b/src/hubs/basehub.ts index c53d8819..1d2da48c 100644 --- a/src/hubs/basehub.ts +++ b/src/hubs/basehub.ts @@ -258,13 +258,13 @@ export class BaseHub extends EventEmitter { * @param {number} deviceType The device type to lookup. * @returns {Promise} Resolved once a device is attached, or resolved immediately if a device is already attached. */ - public waitForDeviceByType (deviceType: number) { + public waitForDeviceByType (deviceType: number): Promise { return new Promise((resolve) => { const existingDevices = this.getDevicesByType(deviceType); if (existingDevices.length >= 1) { return resolve(existingDevices[0]); } - this._attachCallbacks.push((device) => { + this._attachCallbacks.push((device: Device) => { if (device.type === deviceType) { resolve(device); return true; diff --git a/test/devices.ts b/test/devices.ts new file mode 100644 index 00000000..5726b405 --- /dev/null +++ b/test/devices.ts @@ -0,0 +1,6 @@ +import HubLED from "./devices/hubled"; + + +export default function devices() { + describe("Hub LED", HubLED); +}; diff --git a/test/devices/hubled.ts b/test/devices/hubled.ts new file mode 100644 index 00000000..8a8ce574 --- /dev/null +++ b/test/devices/hubled.ts @@ -0,0 +1,36 @@ +import { ok } from "assert"; + +import { FakeBLEDevice } from "../utils/fakebledevice"; +import { getAttachMessage, includeMessage } from "../utils/commons"; + +import { LPF2Hub } from "../../src/hubs/lpf2hub"; +import * as Consts from "../../src/consts"; + +import { HubLED } from "../../src/devices/hubled"; + + +export default function hubled() { + let bleDevice: FakeBLEDevice + let hub: LPF2Hub; + let device: HubLED + + beforeEach(async () => { + bleDevice = new FakeBLEDevice("fakebledevice", "LPF2 Hub"); + hub = new LPF2Hub(bleDevice, {A: 0, B: 1}); + await hub.connect() + bleDevice.send(getAttachMessage(0, Consts.DeviceType.HUB_LED)); + device = await hub.waitForDeviceByType(Consts.DeviceType.HUB_LED) as HubLED; + }) + + it('should set color to BLUE using color codes', () => { + device.setColor(Consts.Color.BLUE) + includeMessage(bleDevice, "0a004100000100000001"); // Set mode to COLOR + includeMessage(bleDevice, "0800810011510003"); // Send color command + }) + + it('should set color to RED using RGB', () => { + device.setRGB(255, 0, 0) + includeMessage(bleDevice, "0a004100010100000001"); // Set mode to RGB + includeMessage(bleDevice, "0a008100115101ff0000"); // Send color command + }) +} diff --git a/test/hubs/lpf2.ts b/test/hubs/lpf2.ts index e609dd61..8787a769 100644 --- a/test/hubs/lpf2.ts +++ b/test/hubs/lpf2.ts @@ -1,7 +1,7 @@ -import { equal, ok } from "assert"; +import { strictEqual, ok } from "assert"; import { FakeBLEDevice } from "../utils/fakebledevice"; -import { getAttachMessage } from "../utils/commons"; +import { getAttachMessage, includeMessage } from "../utils/commons"; import { LPF2Hub } from "../../src/hubs/lpf2hub"; import * as Consts from "../../src/consts"; @@ -44,7 +44,7 @@ export default function lpf2Hub() { return () => { it("should emit an 'attach' event with device", done => { hub.on("attach", device => { - equal(device.type, type); + strictEqual(device.type, type); ok(device instanceof Constructor); done(); }); @@ -55,7 +55,7 @@ export default function lpf2Hub() { it("should resolve 'waitForDeviceByType'", done => { hub.waitForDeviceByType(type).then((d) => { const device = d as Device; - equal(device.type, type); + strictEqual(device.type, type); ok(device instanceof Constructor); done(); }); @@ -77,7 +77,7 @@ export default function lpf2Hub() { await bleDevice.send(getAttachMessage(0, Consts.DeviceType.UNKNOWN)); const device = await hub.waitForDeviceAtPort("A") as Device; - equal(device.type, Consts.DeviceType.UNKNOWN); + strictEqual(device.type, Consts.DeviceType.UNKNOWN); ok(device instanceof Device); return; }); @@ -85,7 +85,7 @@ export default function lpf2Hub() { it("should resolve when device attached", done => { hub.waitForDeviceAtPort("A").then(d=> { const device = d as Device; - equal(device.type, Consts.DeviceType.UNKNOWN); + strictEqual(device.type, Consts.DeviceType.UNKNOWN); ok(device instanceof Device); done(); }); @@ -130,7 +130,7 @@ export default function lpf2Hub() { describe("shutdown", () => { it("should send shutdown message", async () => { await hub.shutdown(); - ok((bleDevice.messages[Consts.BLECharacteristic.LPF2_ALL] || []).includes("04000201")) + includeMessage(bleDevice, "04000201"); }); }); } diff --git a/test/hubs/technicmediumhub.ts b/test/hubs/technicmediumhub.ts index c3dcc1b0..0f0d9550 100644 --- a/test/hubs/technicmediumhub.ts +++ b/test/hubs/technicmediumhub.ts @@ -1,10 +1,7 @@ -import { ok } from "assert"; - import { FakeBLEDevice } from "../utils/fakebledevice"; -import {commonsConnectTests } from '../utils/commons'; +import {commonsConnectTests, includeMessage } from '../utils/commons'; import { TechnicMediumHub } from "../../src/hubs/technicmediumhub"; -import * as Consts from "../../src/consts"; export default function technicMediumHub() { const state = { connectEvent: false }; @@ -15,7 +12,6 @@ export default function technicMediumHub() { describe("connect", () => { before(async () => await hub.connect()); commonsConnectTests(state, hub, bleDevice); - it("should have subscribed to temperature updates", () => ok(bleDevice.messages[Consts.BLECharacteristic.LPF2_ALL].includes("0a00413d000a00000001"))); }); } diff --git a/test/test.ts b/test/test.ts index 0240ca66..ba5254e2 100644 --- a/test/test.ts +++ b/test/test.ts @@ -1,6 +1,6 @@ -import { equal, ok, rejects } from "assert"; - import hubs from "./hubs"; +import devices from "./devices"; describe("Hubs", hubs); +describe("Devices", devices); diff --git a/test/utils/commons.ts b/test/utils/commons.ts index 1f1946f7..aea6683b 100644 --- a/test/utils/commons.ts +++ b/test/utils/commons.ts @@ -1,19 +1,25 @@ -import { equal, ok } from "assert"; +import { strictEqual, ok } from "assert"; import { FakeBLEDevice } from "./fakebledevice"; import { BaseHub } from "../../src/index-node"; import * as Consts from "../../src/consts"; +export function includeMessage(bleDevice: FakeBLEDevice, message: string) { + if (!bleDevice.messages[Consts.BLECharacteristic.LPF2_ALL].includes(message)) { + throw new Error(`BleDevice did not sent ${message}`); + } +} + export function commonsConnectTests(state = { connectEvent: false }, hub: BaseHub, bleDevice: FakeBLEDevice, firmware = "1.0.00.0000") { it("should have emmited a connect event", () => ok(state.connectEvent)); - it(`should have a uuid (${bleDevice.uuid})`, () => equal(hub.uuid, bleDevice.uuid)); - it(`should have a name (${bleDevice.name})`, () => equal(hub.name, bleDevice.name)); - it(`should have a firmware revision (${firmware})`, () => equal(hub.firmwareVersion, firmware)); - it("should have a hardware revision (1.0.00.0000)", () => equal(hub.hardwareVersion, "1.0.00.0000")); - it("should have as primary mac address (00:00:00:00:00:00)", () => equal(hub.primaryMACAddress, "00:00:00:00:00:00")); - it("should have subscribed to BUTTON updates", () => ok(bleDevice.messages[Consts.BLECharacteristic.LPF2_ALL].includes("0500010202"))); - it("should have subscribed to RSSI updates", () => ok(bleDevice.messages[Consts.BLECharacteristic.LPF2_ALL].includes("0500010502"))); - it("should have subscribed to battery level updates", () => ok(bleDevice.messages[Consts.BLECharacteristic.LPF2_ALL].includes("0500010602"))); + it(`should have a uuid (${bleDevice.uuid})`, () => strictEqual(hub.uuid, bleDevice.uuid)); + it(`should have a name (${bleDevice.name})`, () => strictEqual(hub.name, bleDevice.name)); + it(`should have a firmware revision (${firmware})`, () => strictEqual(hub.firmwareVersion, firmware)); + it("should have a hardware revision (1.0.00.0000)", () => strictEqual(hub.hardwareVersion, "1.0.00.0000")); + it("should have as primary mac address (00:00:00:00:00:00)", () => strictEqual(hub.primaryMACAddress, "00:00:00:00:00:00")); + it("should have subscribed to BUTTON updates", () => includeMessage(bleDevice, "0500010202")); + it("should have subscribed to RSSI updates", () => includeMessage(bleDevice, "0500010502")); + it("should have subscribed to battery level updates", () => includeMessage(bleDevice, "0500010602")); } export function versionToInt32(version: string): number { From c18f51ecff0cb280fe699369dcc4ebe13cb23f4f Mon Sep 17 00:00:00 2001 From: aileo Date: Tue, 26 Jan 2021 09:23:10 +0100 Subject: [PATCH 5/5] Add tests for RemoteControlButton --- test/devices.ts | 6 ++-- test/devices/remotecontrolbutton.ts | 43 +++++++++++++++++++++++++++++ test/utils/fakebledevice.ts | 2 +- 3 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 test/devices/remotecontrolbutton.ts diff --git a/test/devices.ts b/test/devices.ts index 5726b405..4a255aba 100644 --- a/test/devices.ts +++ b/test/devices.ts @@ -1,6 +1,8 @@ -import HubLED from "./devices/hubled"; +import hubLED from "./devices/hubled"; +import remoteControlButton from "./devices/remotecontrolbutton"; export default function devices() { - describe("Hub LED", HubLED); + describe("Hub LED", hubLED); + describe("Remote control button", remoteControlButton); }; diff --git a/test/devices/remotecontrolbutton.ts b/test/devices/remotecontrolbutton.ts new file mode 100644 index 00000000..3f4c6d2e --- /dev/null +++ b/test/devices/remotecontrolbutton.ts @@ -0,0 +1,43 @@ +import { strictEqual } from "assert"; + +import { FakeBLEDevice } from "../utils/fakebledevice"; +import { getAttachMessage, includeMessage } from "../utils/commons"; + +import { LPF2Hub } from "../../src/hubs/lpf2hub"; +import * as Consts from "../../src/consts"; + +import { RemoteControlButton, ButtonState } from "../../src/devices/remotecontrolbutton"; + +export default function remoteControlButton() { + let bleDevice: FakeBLEDevice + let hub: LPF2Hub; + let device: RemoteControlButton; + + function testEvent(eventType: number, eventContant: number) { + return done => { + device.on('remoteButton', ({event})=> { + strictEqual(event, eventContant); + done() + }); + const message = Buffer.alloc(3); + message[0] = 0x45; + message[1] = 0; + message[2] = eventType; + bleDevice.send(message); + } + } + + beforeEach(async () => { + bleDevice = new FakeBLEDevice("fakebledevice", "LPF2 Hub"); + hub = new LPF2Hub(bleDevice, {A: 0, B: 1}); + await hub.connect() + bleDevice.send(getAttachMessage(0, Consts.DeviceType.REMOTE_CONTROL_BUTTON)); + device = await hub.waitForDeviceByType(Consts.DeviceType.REMOTE_CONTROL_BUTTON) as RemoteControlButton; + }) + + it('should detect UP', testEvent(0x01, ButtonState.UP)) + it('should detect DOWN', testEvent(0xff, ButtonState.DOWN)) + it('should detect STOP', testEvent(0x7f, ButtonState.STOP)) + it('should detect RELEASED', testEvent(0x00, ButtonState.RELEASED)) + +} diff --git a/test/utils/fakebledevice.ts b/test/utils/fakebledevice.ts index a3b26b50..ef507aa5 100644 --- a/test/utils/fakebledevice.ts +++ b/test/utils/fakebledevice.ts @@ -98,6 +98,6 @@ export class FakeBLEDevice extends EventEmitter implements IBLEAbstraction { 10 ) }) - }; + } public get messages() { return this._incommingMessages; } };