From 81dee84edac8caac2908f29f983d6d353458547c Mon Sep 17 00:00:00 2001 From: Mike Pennisi Date: Tue, 23 Jan 2024 18:53:15 -0500 Subject: [PATCH] Procedurally enforce JS formatting --- .prettierrc | 7 +++ lib/cli.js | 8 ++-- lib/create-command-server.js | 8 ++-- lib/create-voice-server.js | 8 ++-- package-lock.json | 18 +++++++- package.json | 7 ++- test/test.js | 83 +++++++++++++++++++----------------- 7 files changed, 85 insertions(+), 54 deletions(-) create mode 100644 .prettierrc diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..7e80c95 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,7 @@ +{ + "tabWidth": 2, + "useTabs": false, + "printWidth": 100, + "singleQuote": true, + "arrowParens": "avoid" +} diff --git a/lib/cli.js b/lib/cli.js index a45f628..051fe88 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -14,13 +14,13 @@ const DEFAULT_PORT = 4382; */ const log = (...args) => console.error(new Date().toISOString(), ...args); -module.exports = async (process) => { +module.exports = async process => { const argv = yargs(hideBin(process.argv)) .option('port', { coerce(string) { if (!/^(0|[1-9][0-9]*)$/.test(string)) { throw new TypeError( - `"port" option: expected a non-negative integer value but received "${string}"` + `"port" option: expected a non-negative integer value but received "${string}"`, ); } return Number(string); @@ -42,11 +42,11 @@ module.exports = async (process) => { log(`listening on port ${argv.port}`); - commandServer.on('error', (error) => { + commandServer.on('error', error => { log(`error: ${error}`); }); - voiceServer.on('message', (message) => { + voiceServer.on('message', message => { log(`voice server received message ${JSON.stringify(message)}`); if (message.name == 'speech') { commandServer.broadcast({ diff --git a/lib/create-command-server.js b/lib/create-command-server.js index db6c90d..96085bb 100644 --- a/lib/create-command-server.js +++ b/lib/create-command-server.js @@ -5,9 +5,9 @@ const sessionModule = require('./modules/session'); const broadcast = (server, message) => { const packedMessage = JSON.stringify(message); - server.clients.forEach((websocket) => { + server.clients.forEach(websocket => { if (websocket.sessionId) { - websocket.send(packedMessage, (error) => { + websocket.send(packedMessage, error => { if (error) { server.emit('error', `error sending message: ${error}`); } @@ -24,7 +24,7 @@ const methodHandlers = { const onConnection = websocket => { const send = value => websocket.send(JSON.stringify(value)); - websocket.on('message', async (data) => { + websocket.on('message', async data => { let parsed; try { parsed = JSON.parse(data); @@ -87,7 +87,7 @@ module.exports = async function createWebSocketServer(port) { path: '/session', port, }); - await new Promise((resolve) => server.once('listening', resolve)); + await new Promise(resolve => server.once('listening', resolve)); server.broadcast = broadcast.bind(null, server); server.on('connection', onConnection); diff --git a/lib/create-voice-server.js b/lib/create-voice-server.js index 31ed75b..8bbdc10 100644 --- a/lib/create-voice-server.js +++ b/lib/create-voice-server.js @@ -4,12 +4,12 @@ const net = require('net'); const onConnection = (server, socket) => { let emitted = ''; - socket.on('data', (buffer) => emitted += buffer.toString()); + socket.on('data', buffer => (emitted += buffer.toString())); socket.on('end', () => { const match = emitted.match(/^(lifecycle|speech|internalError):(.*)$/); - const [name, data] = match ? - [match[1], match[2]] : - ['internalError', `unrecognized message: "${emitted}"`]; + const [name, data] = match + ? [match[1], match[2]] + : ['internalError', `unrecognized message: "${emitted}"`]; server.emit('message', { type: 'event', name, data }); }); diff --git a/package-lock.json b/package-lock.json index 1e4eb4f..b246439 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,7 +19,8 @@ "at-driver": "bin/at-driver" }, "devDependencies": { - "mocha": "^9.1.2" + "mocha": "^9.1.2", + "prettier": "^3.2.4" } }, "node_modules/@ungap/promise-all-settled": { @@ -1059,6 +1060,21 @@ "node": ">=6" } }, + "node_modules/prettier": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.4.tgz", + "integrity": "sha512-FWu1oLHKCrtpO1ypU6J0SbK2d9Ckwysq6bHj/uaCP26DxrPpppCLQRGVuqAxSTvhF00AcvDRyYrLNW7ocBhFFQ==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", diff --git a/package.json b/package.json index 9e4d2bc..5411746 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,9 @@ "scripts": { "postinstall": "Release\\MakeVoice.exe", "postuninstall": "Release\\MakeVoice.exe /u", - "test": "mocha --ui tdd test" + "prettier": "prettier --write lib test", + "test": "prettier --check lib test && npm run test-unit", + "test-unit": "mocha --ui tdd test" }, "files": [ "lib", @@ -20,7 +22,8 @@ "author": "", "license": "MIT", "devDependencies": { - "mocha": "^9.1.2" + "mocha": "^9.1.2", + "prettier": "^3.2.4" }, "dependencies": { "robotjs": "^0.6.0", diff --git a/test/test.js b/test/test.js index bbe891d..3b4b0c6 100644 --- a/test/test.js +++ b/test/test.js @@ -7,14 +7,17 @@ const net = require('net'); const WebSocket = require('ws'); const executable = path.join(__dirname, '..', 'bin', 'at-driver'); -const invert = (promise) => promise.then( - () => { throw new Error('expected promise to be rejected, but it was fulfilled'); }, - () => {} -); +const invert = promise => + promise.then( + () => { + throw new Error('expected promise to be rejected, but it was fulfilled'); + }, + () => {}, + ); suite('at-driver', () => { const children = []; - const run = (args) => { + const run = args => { const child = child_process.spawn(process.execPath, [executable, ...args]); children.push(child); const whenClosed = new Promise((resolve, reject) => { @@ -22,20 +25,19 @@ suite('at-driver', () => { child.on('close', () => reject(new Error('Server closed unexpectedly'))); }); return new Promise((resolve, reject) => { - child.stderr.on('data', () => resolve({whenClosed})); + child.stderr.on('data', () => resolve({ whenClosed })); whenClosed.catch(reject); }); }; const sendVoicePacket = async (type, data) => { const NAMED_PIPE = '\\\\?\\pipe\\my_pipe'; - const stream = await new Promise((resolve) => { + const stream = await new Promise(resolve => { const stream = net.connect(NAMED_PIPE); stream.on('connect', () => resolve(stream)); }); await new Promise(resolve => stream.end(`${type}:${data}`, 'utf8', resolve)); - - } - const connect = (port) => { + }; + const connect = port => { const websocket = new WebSocket(`ws://localhost:${port}/session`); return new Promise((resolve, reject) => { @@ -44,62 +46,62 @@ suite('at-driver', () => { }); }; teardown(() => { - children.forEach((child) => child.kill()); + children.forEach(child => child.kill()); children.length = 0; }); test('WebSocket server on default port', async () => { - const {whenClosed} = await run([]); + const { whenClosed } = await run([]); return Promise.race([whenClosed, connect(4382)]); }); test('WebSocket server on custom port', async () => { - const {whenClosed} = await run(['--port', '6543']); + const { whenClosed } = await run(['--port', '6543']); return Promise.race([whenClosed, connect(6543)]); }); test('rejects invalid port values: unspecified', async () => { - const {whenClosed} = await run(['--port']); + const { whenClosed } = await run(['--port']); return invert(whenClosed); }); test('rejects invalid port values: non-numeric', async () => { - const {whenClosed} = await run(['--port', 'seven']); + const { whenClosed } = await run(['--port', 'seven']); return invert(whenClosed); }); test('rejects invalid port values: negative', async () => { - const {whenClosed} = await run(['--port', '-8000']); + const { whenClosed } = await run(['--port', '-8000']); return invert(whenClosed); }); test('rejects invalid port values: non-integer', async () => { - const {whenClosed} = await run(['--port', '2004.3']); + const { whenClosed } = await run(['--port', '2004.3']); return invert(whenClosed); }); test('rejects invalid port values: non-decimal', async () => { - const {whenClosed} = await run(['--port', '0x1000']); + const { whenClosed } = await run(['--port', '0x1000']); return invert(whenClosed); }); suite('protocol', () => { let websocket, whenClosed; - const nextMessage = (websocket) => { + const nextMessage = websocket => { return new Promise((resolve, reject) => { - websocket.once('message', (buffer) => { - try { + websocket.once('message', buffer => { + try { resolve(JSON.parse(buffer.toString())); - } catch (error) { + } catch (error) { reject(error); - } + } }); websocket.once('error', reject); }); }; setup(async () => { - ({whenClosed} = await run([])); + ({ whenClosed } = await run([])); websocket = await Promise.race([whenClosed, connect(4382)]); }); @@ -111,7 +113,7 @@ suite('at-driver', () => { assert.deepEqual(message, { id: null, error: 'unknown error', - message: 'Unable to parse message: "not JSON".' + message: 'Unable to parse message: "not JSON".', }); }); @@ -122,7 +124,7 @@ suite('at-driver', () => { assert.deepEqual(message, { id: null, error: 'unknown error', - message: 'Malformed message: "[]".' + message: 'Malformed message: "[]".', }); }); @@ -133,7 +135,7 @@ suite('at-driver', () => { assert.deepEqual(message, { id: null, error: 'unknown command', - message: 'Unrecognized message type (no method): "{"id": 1, "type": "foobar"}".' + message: 'Unrecognized message type (no method): "{"id": 1, "type": "foobar"}".', }); }); @@ -144,7 +146,8 @@ suite('at-driver', () => { assert.deepEqual(message, { id: null, error: 'unknown error', - message: 'Command missing required "id": "{"method": "interaction.pressKeys", "params": {"keys": ["A"]}}".' + message: + 'Command missing required "id": "{"method": "interaction.pressKeys", "params": {"keys": ["A"]}}".', }); }); @@ -164,35 +167,37 @@ suite('at-driver', () => { assert.deepEqual(message, { id: 83, - result: {} + result: {}, }); }); test('rejects invalid "pressKey" Command', async () => { - websocket.send('{"id": 902, "method": "interaction.pressKeys", "params": {"keys": ["df daf% ?"]}}'); + websocket.send( + '{"id": 902, "method": "interaction.pressKeys", "params": {"keys": ["df daf% ?"]}}', + ); const message = await Promise.race([whenClosed, nextMessage(websocket)]); assert.deepEqual(message, { id: 902, error: 'unknown error', - message: 'Invalid key code specified.' + message: 'Invalid key code specified.', }); }); suite('with sessionId', () => { let sessionId, capabilities; - setup(async() => { + setup(async () => { websocket.send('{"id": 527, "method": "session.new", "params": {}}'); const message = await Promise.race([whenClosed, nextMessage(websocket)]); assert.ok(message.result); sessionId = message.result.sessionId; capabilities = message.result.capabilities; - }) + }); test('returns a sessionId', () => { assert.notEqual(sessionId, undefined); - }) + }); test('sends voice events', async () => { await Promise.race([whenClosed, sendVoicePacket('speech', 'Hello, world!')]); @@ -200,12 +205,12 @@ suite('at-driver', () => { const message = await Promise.race([whenClosed, nextMessage(websocket)]); assert.deepEqual(message, { - method: "interaction.capturedOutput", + method: 'interaction.capturedOutput', params: { - data: "Hello, world!" - } + data: 'Hello, world!', + }, }); - }) - }) + }); + }); }); });