From 4bccb62e478e5eed189bb15eb1cecbcdde5ee579 Mon Sep 17 00:00:00 2001 From: Francis Gulotta Date: Sat, 10 Mar 2018 23:08:17 -0500 Subject: [PATCH] chore: move parsers to their new packages and clean up docs --- README.md | 9 +- docs/BaseBinding.html | 4 +- docs/ByteLengthParser.html | 292 ----------------- docs/CCTalkParser.html | 194 ------------ docs/DelimiterParser.html | 194 ------------ docs/Poller.html | 4 +- docs/ReadLineParser.html | 194 ------------ docs/ReadyParser.html | 299 ------------------ docs/RegexParser.html | 194 ------------ docs/SerialPort.html | 4 +- docs/bindings_base.js.html | 4 +- docs/bindings_poller.js.html | 4 +- docs/global.html | 13 +- docs/index.html | 17 +- docs/index.js.html | 4 +- ...{parsers_index.js.html => parsers.js.html} | 25 +- docs/parsers_byte-length.js.html | 116 ------- docs/parsers_cctalk.js.html | 101 ------ docs/parsers_delimiter.js.html | 109 ------- docs/parsers_readline.js.html | 89 ------ docs/parsers_ready.js.html | 124 -------- docs/parsers_regex.js.html | 110 ------- docs/serialport.js.html | 6 +- lib/bindings/linux-list.js | 2 +- lib/parsers.js | 36 +++ lib/parsers/byte-length.js | 58 ---- lib/parsers/cctalk.js | 43 --- lib/parsers/delimiter.js | 51 --- lib/parsers/index.js | 37 --- lib/parsers/readline.js | 31 -- lib/parsers/ready.js | 66 ---- lib/parsers/regex.js | 52 --- lib/serialport.js | 2 +- package.json | 6 + test/parser-byte-length.js | 63 ---- test/parser-cctalk.js | 41 --- test/parser-delimiter.js | 143 --------- test/parser-readline.js | 115 ------- test/parser-ready.js | 99 ------ test/parser-regex.js | 120 ------- 40 files changed, 96 insertions(+), 2979 deletions(-) delete mode 100644 docs/ByteLengthParser.html delete mode 100644 docs/CCTalkParser.html delete mode 100644 docs/DelimiterParser.html delete mode 100644 docs/ReadLineParser.html delete mode 100644 docs/ReadyParser.html delete mode 100644 docs/RegexParser.html rename docs/{parsers_index.js.html => parsers.js.html} (50%) delete mode 100644 docs/parsers_byte-length.js.html delete mode 100644 docs/parsers_cctalk.js.html delete mode 100644 docs/parsers_delimiter.js.html delete mode 100644 docs/parsers_readline.js.html delete mode 100644 docs/parsers_ready.js.html delete mode 100644 docs/parsers_regex.js.html create mode 100644 lib/parsers.js delete mode 100644 lib/parsers/byte-length.js delete mode 100644 lib/parsers/cctalk.js delete mode 100644 lib/parsers/delimiter.js delete mode 100644 lib/parsers/index.js delete mode 100644 lib/parsers/readline.js delete mode 100644 lib/parsers/ready.js delete mode 100644 lib/parsers/regex.js delete mode 100644 test/parser-byte-length.js delete mode 100644 test/parser-cctalk.js delete mode 100644 test/parser-delimiter.js delete mode 100644 test/parser-readline.js delete mode 100644 test/parser-ready.js delete mode 100644 test/parser-regex.js diff --git a/README.md b/README.md index 8b96053b8..aba6b1c9e 100644 --- a/README.md +++ b/README.md @@ -20,16 +20,17 @@ We're not against firmware but we're better than it. ## Quick Answers to Important Questions - [**API Docs**](https://node-serialport.github.io/node-serialport/) +- [Parsers API Docs](https://node-serialport.github.io/parsers/) - **For support**, open a [GitHub issue](https://github.com/node-serialport/node-serialport/issues/new). - **For discussions, design ideas, and clarifications**, please join our [Gitter chat room](https://gitter.im/EmergingTechnologyAdvisors/node-serialport). -- **To test Node-Serialport**, we recommend two related projects—[Browser Serialport](https://github.com/garrows/browser-serialport) ("just like Node Serialport, but for browser apps") and [Serialport Test Piliot](https://github.com/j5js/serialport-test-pilot). - **To contribute**, please review our [contribution guide](CONTRIBUTING.md) and [Code of Conduct](CODE_OF_CONDUCT.md). You might want to check out our [roadmap](https://github.com/node-serialport/node-serialport/issues/746). We also have issues tagged ["good first PR"](https://github.com/node-serialport/node-serialport/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+pr%22), if you'd like to start somewhere specific. We'll do our best to support you until we merge your PR. *** ## API Documentation -Can be found at https://node-serialport.github.io/node-serialport/ +- [API Docs](https://node-serialport.github.io/parsers/) +- [Parsers API Docs](https://node-serialport.github.io/parsers/) See our [changelog](CHANGELOG.md) for what's new, and our [upgrade guide](UPGRADE_GUIDE.md) for a walk-through on differences between major versions. @@ -43,6 +44,8 @@ npm run docs And browsing to `./docs/index.html`. +Parsers have been spun out in to their own [GitHub Repo](https://github.com/node-serialport/parsers). + *** ## Helpful Resources for Getting Started with Node-Serialport @@ -69,7 +72,7 @@ In addition to reading the [article mentioned above](http://www.voodootikigod.co * [Testing](#testing) * [Debugging](#debugging) * [Error Handling](#error-handling) -d* [Command Line Tools](#command-line-tools) +* [Command Line Tools](#command-line-tools) * [Serial Port List](#serial-port-list) * [Srial Port Terminal](#serial-port-terminal) * [Serial Port Repl](#serial-port-repl) diff --git a/docs/BaseBinding.html b/docs/BaseBinding.html index ad812b731..0259b92c7 100644 --- a/docs/BaseBinding.html +++ b/docs/BaseBinding.html @@ -22,7 +22,7 @@
@@ -2383,7 +2383,7 @@
Returns:

- Documentation generated by JSDoc 3.5.5 on Tue Feb 27 2018 23:06:42 GMT-0500 (EST) using the docdash theme. + Documentation generated by JSDoc 3.5.5 on Sat Mar 10 2018 23:07:13 GMT-0500 (EST) using the docdash theme.
diff --git a/docs/ByteLengthParser.html b/docs/ByteLengthParser.html deleted file mode 100644 index c70c3e494..000000000 --- a/docs/ByteLengthParser.html +++ /dev/null @@ -1,292 +0,0 @@ - - - - - ByteLengthParser - Documentation - - - - - - - - - - - - - - - - -
- -

ByteLengthParser

- - - - - - - -
- -
- -

- ByteLengthParser -

- -

A transform stream that emits data as a buffer after a specific number of bytes are received.

- - -
- -
-
- - - - -

Constructor

- - -

new ByteLengthParser(options)

- - - - - - -
- - -
Source:
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - -
Example
- -
// To use the `ByteLength` parser:
-const SerialPort = require('serialport');
-const ByteLength = SerialPort.parsers.ByteLength
-const port = new SerialPort('/dev/tty-usbserial1');
-const parser = port.pipe(new ByteLength({length: 8}));
-parser.on('data', console.log); // will have 8 bytes per data event
- - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
options - - -Object - - - -

parser options object

-
Properties
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
length - - -Number - - - -

the number of bytes on each data event

- -
- - - - - - - - - - - - - - - - - -
- - -

Extends

- - - - -
    -
  • Transform
  • -
- - - - - - - - - - - - - - - - - - - -
- -
- - - - -
- -
- -
- Documentation generated by JSDoc 3.5.5 on Tue Feb 27 2018 23:06:42 GMT-0500 (EST) using the docdash theme. -
- - - - - \ No newline at end of file diff --git a/docs/CCTalkParser.html b/docs/CCTalkParser.html deleted file mode 100644 index 146abc58c..000000000 --- a/docs/CCTalkParser.html +++ /dev/null @@ -1,194 +0,0 @@ - - - - - CCTalkParser - Documentation - - - - - - - - - - - - - - - - -
- -

CCTalkParser

- - - - - - - -
- -
- -

- CCTalkParser -

- -

Parses the CCTalk protocol

- - -
- -
-
- - - - -

Constructor

- - -

new CCTalkParser()

- - - - - - -
- - -
Source:
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - -
Example
- -
// CCTalk Messages are emitted as buffers.
-const SerialPort = require('serialport');
-const CCTalk = SerialPort.parsers.CCTalk;
-const port = new SerialPort('/dev/ttyUSB0');
-const parser = port.pipe(new CCtalk());
-parser.on('data', console.log);
- - - - - - - - - - - - - - - - - - - -
- - -

Extends

- - - - -
    -
  • Transform
  • -
- - - - - - - - - - - - - - - - - - - -
- -
- - - - -
- -
- -
- Documentation generated by JSDoc 3.5.5 on Tue Feb 27 2018 23:06:42 GMT-0500 (EST) using the docdash theme. -
- - - - - \ No newline at end of file diff --git a/docs/DelimiterParser.html b/docs/DelimiterParser.html deleted file mode 100644 index 1dfdc1353..000000000 --- a/docs/DelimiterParser.html +++ /dev/null @@ -1,194 +0,0 @@ - - - - - DelimiterParser - Documentation - - - - - - - - - - - - - - - - -
- -

DelimiterParser

- - - - - - - -
- -
- -

- DelimiterParser -

- -

A transform stream that emits data each time a byte sequence is received.

- - -
- -
-
- - - - -

Constructor

- - -

new DelimiterParser()

- - - - - - -
- - -
Source:
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - -
Example
- -
// To use the `Delimiter` parser, provide a delimiter as a string, buffer, or array of bytes:
-const SerialPort = require('serialport');
-const Delimiter = SerialPort.parsers.Delimiter;
-const port = new SerialPort('/dev/tty-usbserial1');
-const parser = port.pipe(new Delimiter({ delimiter: '\n' }));
-parser.on('data', console.log);
- - - - - - - - - - - - - - - - - - - -
- - -

Extends

- - - - -
    -
  • Transform
  • -
- - - - - - - - - - - - - - - - - - - -
- -
- - - - -
- -
- -
- Documentation generated by JSDoc 3.5.5 on Tue Feb 27 2018 23:06:42 GMT-0500 (EST) using the docdash theme. -
- - - - - \ No newline at end of file diff --git a/docs/Poller.html b/docs/Poller.html index bd941d870..00e1dfe81 100644 --- a/docs/Poller.html +++ b/docs/Poller.html @@ -22,7 +22,7 @@
@@ -576,7 +576,7 @@
Returns:

- Documentation generated by JSDoc 3.5.5 on Tue Feb 27 2018 23:06:42 GMT-0500 (EST) using the docdash theme. + Documentation generated by JSDoc 3.5.5 on Sat Mar 10 2018 23:07:13 GMT-0500 (EST) using the docdash theme.
diff --git a/docs/ReadLineParser.html b/docs/ReadLineParser.html deleted file mode 100644 index 421502ec2..000000000 --- a/docs/ReadLineParser.html +++ /dev/null @@ -1,194 +0,0 @@ - - - - - ReadLineParser - Documentation - - - - - - - - - - - - - - - - -
- -

ReadLineParser

- - - - - - - -
- -
- -

- ReadLineParser -

- -

A transform stream that emits data after a newline delimiter is received.

-

To use the Readline parser, provide a delimiter (defaults to \n). Data is emitted as string controllable by the encoding option (defaults to utf8).

- - -
- -
-
- - - - -

Constructor

- - -

new ReadLineParser()

- - - - - - -
- - -
Source:
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - -
Example
- -
const SerialPort = require('serialport');
-const Readline = SerialPort.parsers.Readline;
-const port = new SerialPort('/dev/tty-usbserial1');
-const parser = port.pipe(new Readline({ delimiter: '\r\n' }));
-parser.on('data', console.log);
- - - - - - - - - - - - - - - - - - - -
- - -

Extends

- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - -
- -
- -
- Documentation generated by JSDoc 3.5.5 on Tue Feb 27 2018 23:06:42 GMT-0500 (EST) using the docdash theme. -
- - - - - \ No newline at end of file diff --git a/docs/ReadyParser.html b/docs/ReadyParser.html deleted file mode 100644 index 4045eca3c..000000000 --- a/docs/ReadyParser.html +++ /dev/null @@ -1,299 +0,0 @@ - - - - - ReadyParser - Documentation - - - - - - - - - - - - - - - - -
- -

ReadyParser

- - - - - - - -
- -
- -

- ReadyParser -

- -

A transform stream that waits for a sequence of "ready" bytes before emitting a ready event and emitting data events

-

To use the Ready parser provide a byte start sequence. After the bytes have been received a ready event is fired and data events are passed through.

- - -
- -
-
- - - - -

Constructor

- - -

new ReadyParser(options)

- - - - - - -
- - -
Source:
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - -
Example
- -
const SerialPort = require('serialport');
-const Ready = SerialPort.parsers.Ready;
-const port = new SerialPort('/dev/tty-usbserial1');
-const parser = port.pipe(new Ready({ delimiter: 'READY' }));
-parser.on('ready', () => console.log('the ready byte sequence has been received'))
-parser.on('data', console.log); // all data after READY is received
- - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
options - - -object - - - -

options for the parser

-
Properties
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
delimiter - - -string -| - -Buffer -| - -array - - - -

data to look for before emitted "ready"

- -
- - - - - - - - - - - - - - - - - -
- - -

Extends

- - - - -
    -
  • Transform
  • -
- - - - - - - - - - - - - - - - - - - -
- -
- - - - -
- -
- -
- Documentation generated by JSDoc 3.5.5 on Tue Feb 27 2018 23:06:42 GMT-0500 (EST) using the docdash theme. -
- - - - - \ No newline at end of file diff --git a/docs/RegexParser.html b/docs/RegexParser.html deleted file mode 100644 index 56e1d0e78..000000000 --- a/docs/RegexParser.html +++ /dev/null @@ -1,194 +0,0 @@ - - - - - RegexParser - Documentation - - - - - - - - - - - - - - - - -
- -

RegexParser

- - - - - - - -
- -
- -

- RegexParser -

- -

A transform stream that uses a regular expression to split the incoming text upon.

-

To use the Regex parser provide a regular expression to split the incoming text upon. Data is emitted as string controllable by the encoding option (defaults to utf8).

- - -
- -
-
- - - - -

Constructor

- - -

new RegexParser()

- - - - - - -
- - -
Source:
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - -
Example
- -
const SerialPort = require('serialport');
-const Regex = SerialPort.parsers.Regex;
-const port = new SerialPort('/dev/tty-usbserial1');
-const parser = port.pipe(new Regex({ regex: /[\r\n]+/ }));
-parser.on('data', console.log);
- - - - - - - - - - - - - - - - - - - -
- - -

Extends

- - - - -
    -
  • Transform
  • -
- - - - - - - - - - - - - - - - - - - -
- -
- - - - -
- -
- -
- Documentation generated by JSDoc 3.5.5 on Tue Feb 27 2018 23:06:42 GMT-0500 (EST) using the docdash theme. -
- - - - - \ No newline at end of file diff --git a/docs/SerialPort.html b/docs/SerialPort.html index b9e1a908b..c67e2704f 100644 --- a/docs/SerialPort.html +++ b/docs/SerialPort.html @@ -22,7 +22,7 @@
@@ -2981,7 +2981,7 @@
Returns:

- Documentation generated by JSDoc 3.5.5 on Tue Feb 27 2018 23:06:42 GMT-0500 (EST) using the docdash theme. + Documentation generated by JSDoc 3.5.5 on Sat Mar 10 2018 23:07:13 GMT-0500 (EST) using the docdash theme.
diff --git a/docs/bindings_base.js.html b/docs/bindings_base.js.html index 94b10cbe7..ed658c530 100644 --- a/docs/bindings_base.js.html +++ b/docs/bindings_base.js.html @@ -22,7 +22,7 @@
@@ -280,7 +280,7 @@

bindings/base.js


- Documentation generated by JSDoc 3.5.5 on Tue Feb 27 2018 23:06:42 GMT-0500 (EST) using the docdash theme. + Documentation generated by JSDoc 3.5.5 on Sat Mar 10 2018 23:07:12 GMT-0500 (EST) using the docdash theme.
diff --git a/docs/bindings_poller.js.html b/docs/bindings_poller.js.html index 94cbfb884..b445bcd0a 100644 --- a/docs/bindings_poller.js.html +++ b/docs/bindings_poller.js.html @@ -22,7 +22,7 @@
@@ -151,7 +151,7 @@

bindings/poller.js


- Documentation generated by JSDoc 3.5.5 on Tue Feb 27 2018 23:06:42 GMT-0500 (EST) using the docdash theme. + Documentation generated by JSDoc 3.5.5 on Sat Mar 10 2018 23:07:12 GMT-0500 (EST) using the docdash theme.
diff --git a/docs/global.html b/docs/global.html index 8d2103076..561f69204 100644 --- a/docs/global.html +++ b/docs/global.html @@ -22,7 +22,7 @@
@@ -1416,6 +1416,8 @@
Type:

Parsers

+

The default Parsers are Transform streams that process incoming data. To use the parsers, you must create them and then pipe the Serialport to the parser. Be careful to only write to the SerialPort object and not the parser. Full documentation for parsers can be found in their api docs.

+ @@ -1424,7 +1426,7 @@

Parsers

Source:
@@ -1634,8 +1636,7 @@
Properties:
-

The default Parsers are Transform streams that parse data in different ways to transform incoming data.

-

To use the parsers, you must create them and then pipe the Serialport to the parser. Be careful to only write to the SerialPort object and not the parser.

+

Parsers are collection of transform streams to processes incoming data

@@ -1818,7 +1819,7 @@

data

-

Listening for the data event puts the port in flowing mode. Data is emitted as soon as it's received. Data is a Buffer object with a varying amount of data in it. The readLine parser converts the data into string lines. See the parsers section for more information on parsers, and the Node.js stream documentation for more information on the data event.

+

Listening for the data event puts the port in flowing mode. Data is emitted as soon as it's received. Data is a Buffer object with a varying amount of data in it. The readLine parser converts the data into string lines. See the parsers section for more information on parsers, and the Node.js stream documentation for more information on the data event.

@@ -2027,7 +2028,7 @@

open


- Documentation generated by JSDoc 3.5.5 on Tue Feb 27 2018 23:06:42 GMT-0500 (EST) using the docdash theme. + Documentation generated by JSDoc 3.5.5 on Sat Mar 10 2018 23:49:02 GMT-0500 (EST) using the docdash theme.
diff --git a/docs/index.html b/docs/index.html index 8aa335aca..af5b8eb61 100644 --- a/docs/index.html +++ b/docs/index.html @@ -22,7 +22,7 @@
@@ -53,17 +53,21 @@

Intro to Node-Serialport

Imagine a world where you can write JavaScri

We're not against firmware but we're better than it.

Quick Answers to Important Questions


-

API Documentation

Can be found at https://node-serialport.github.io/node-serialport/

+

API Documentation

See our changelog for what's new, and our upgrade guide for a walk-through on differences between major versions.

Older versions are no longer supported but their docs can be found by looking through release tags.

You can generate the docs by running

npm run docs

And browsing to ./docs/index.html.

+

Parsers have been spun out in to their own GitHub Repo.


Helpful Resources for Getting Started with Node-Serialport

In addition to reading the article mentioned above, these others might help you:

    @@ -89,7 +93,10 @@

    Table of Contents

    + +
  • Command Line Tools
    • Serial Port List
    • Srial Port Terminal
    • Serial Port Repl
    • @@ -465,7 +472,7 @@

      Serial Port List

      serialport-list will list all available

      - Documentation generated by JSDoc 3.5.5 on Tue Feb 27 2018 23:06:42 GMT-0500 (EST) using the docdash theme. + Documentation generated by JSDoc 3.5.5 on Sat Mar 10 2018 23:49:02 GMT-0500 (EST) using the docdash theme.
      diff --git a/docs/index.js.html b/docs/index.js.html index 8660eaa41..74ef79b18 100644 --- a/docs/index.js.html +++ b/docs/index.js.html @@ -22,7 +22,7 @@
      @@ -65,7 +65,7 @@

      index.js


      - Documentation generated by JSDoc 3.5.5 on Tue Feb 27 2018 23:06:42 GMT-0500 (EST) using the docdash theme. + Documentation generated by JSDoc 3.5.5 on Sat Mar 10 2018 23:07:12 GMT-0500 (EST) using the docdash theme.
      diff --git a/docs/parsers_index.js.html b/docs/parsers.js.html similarity index 50% rename from docs/parsers_index.js.html rename to docs/parsers.js.html index 7d5d75a00..4cf4ccaff 100644 --- a/docs/parsers_index.js.html +++ b/docs/parsers.js.html @@ -2,7 +2,7 @@ - parsers/index.js - Documentation + parsers.js - Documentation @@ -22,12 +22,12 @@
      -

      parsers/index.js

      +

      parsers.js

      @@ -39,9 +39,8 @@

      parsers/index.js

      'use strict';
       /**
      - * The default `Parsers` are [Transform streams](https://nodejs.org/api/stream.html#stream_class_stream_transform) that parse data in different ways to transform incoming data.
      -
      - To use the parsers, you must create them and then pipe the Serialport to the parser. Be careful to only write to the SerialPort object and not the parser.
      + * Parsers are collection of transform streams to processes incoming data
      + * @summary The default `Parsers` are [Transform streams](https://nodejs.org/api/stream.html#stream_class_stream_transform) that process incoming data. To use the parsers, you must create them and then pipe the Serialport to the parser. Be careful to only write to the SerialPort object and not the parser. Full documentation for parsers can be found in [their api docs](https://node-serialport.github.io/parsers/).
        * @typedef {Object} Parsers
        * @property {Transform} ByteLength
        * @property {Transform} CCtalk
      @@ -67,12 +66,12 @@ 

      parsers/index.js

      */ module.exports = { - ByteLength: require('./byte-length'), - CCTalk: require('./cctalk'), - Delimiter: require('./delimiter'), - Readline: require('./readline'), - Ready: require('./ready'), - Regex: require('./regex') + ByteLength: require('parser-byte-length'), + CCTalk: require('parser-cctalk'), + Delimiter: require('parser-delimiter'), + Readline: require('parser-readline'), + Ready: require('parser-ready'), + Regex: require('parser-regex') };
      @@ -86,7 +85,7 @@

      parsers/index.js


      - Documentation generated by JSDoc 3.5.5 on Tue Feb 27 2018 23:06:42 GMT-0500 (EST) using the docdash theme. + Documentation generated by JSDoc 3.5.5 on Sat Mar 10 2018 23:07:12 GMT-0500 (EST) using the docdash theme.
      diff --git a/docs/parsers_byte-length.js.html b/docs/parsers_byte-length.js.html deleted file mode 100644 index b58164c36..000000000 --- a/docs/parsers_byte-length.js.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - parsers/byte-length.js - Documentation - - - - - - - - - - - - - - - - -
      - -

      parsers/byte-length.js

      - - - - - - - -
      -
      -
      'use strict';
      -const Buffer = require('safe-buffer').Buffer;
      -const Transform = require('stream').Transform;
      -
      -/**
      - * A transform stream that emits data as a buffer after a specific number of bytes are received.
      - * @extends Transform
      - * @param {Object} options parser options object
      - * @param {Number} options.length the number of bytes on each data event
      - * @example
      -// To use the `ByteLength` parser:
      -const SerialPort = require('serialport');
      -const ByteLength = SerialPort.parsers.ByteLength
      -const port = new SerialPort('/dev/tty-usbserial1');
      -const parser = port.pipe(new ByteLength({length: 8}));
      -parser.on('data', console.log); // will have 8 bytes per data event
      - */
      -class ByteLengthParser extends Transform {
      -  constructor(options) {
      -    super(options);
      -    options = options || {};
      -
      -    if (typeof options.length !== 'number') {
      -      throw new TypeError('"length" is not a number');
      -    }
      -
      -    if (options.length < 1) {
      -      throw new TypeError('"length" is not greater than 0');
      -    }
      -
      -    this.length = options.length;
      -    this.position = 0;
      -    this.buffer = Buffer.alloc(this.length);
      -  }
      -
      -  _transform(chunk, encoding, cb) {
      -    let cursor = 0;
      -    while (cursor < chunk.length) {
      -      this.buffer[this.position] = chunk[cursor];
      -      cursor++;
      -      this.position++;
      -      if (this.position === this.length) {
      -        this.push(this.buffer);
      -        this.buffer = Buffer.alloc(this.length);
      -        this.position = 0;
      -      }
      -    }
      -    cb();
      -  }
      -
      -  _flush(cb) {
      -    this.push(this.buffer.slice(0, this.position));
      -    this.buffer = Buffer.alloc(this.length);
      -    cb();
      -  }
      -};
      -
      -module.exports = ByteLengthParser;
      -
      -
      -
      - - - - -
      - -
      - -
      - Documentation generated by JSDoc 3.5.5 on Tue Feb 27 2018 23:06:42 GMT-0500 (EST) using the docdash theme. -
      - - - - - diff --git a/docs/parsers_cctalk.js.html b/docs/parsers_cctalk.js.html deleted file mode 100644 index 82a7a3695..000000000 --- a/docs/parsers_cctalk.js.html +++ /dev/null @@ -1,101 +0,0 @@ - - - - - parsers/cctalk.js - Documentation - - - - - - - - - - - - - - - - -
      - -

      parsers/cctalk.js

      - - - - - - - -
      -
      -
      'use strict';
      -const Transform = require('stream').Transform;
      -const Buffer = require('safe-buffer').Buffer;
      -/**
      - * Parses the CCTalk protocol
      - * @extends Transform
      - * @example
      -// CCTalk Messages are emitted as buffers.
      -const SerialPort = require('serialport');
      -const CCTalk = SerialPort.parsers.CCTalk;
      -const port = new SerialPort('/dev/ttyUSB0');
      -const parser = port.pipe(new CCtalk());
      -parser.on('data', console.log);
      - */
      -class CCTalkParser extends Transform {
      -  constructor() {
      -    super();
      -    this.array = [];
      -    this.cursor = 0;
      -  }
      -  _transform(buffer, _, cb) {
      -    this.cursor += buffer.length;
      -    // TODO: Better Faster es7 no supported by node 4
      -    // ES7 allows directly push [...buffer]
      -    // this.array = this.array.concat(Array.from(buffer)); //Slower ?!?
      -    Array.from(buffer)
      -      .map((byte) => this.array.push(byte));
      -    while (this.cursor > 1 && this.cursor >= this.array[1] + 5) {
      -      // full frame accumulated
      -      // copy command from the array
      -      const FullMsgLength = this.array[1] + 5;
      -
      -      const frame = Buffer.from(this.array.slice(0, FullMsgLength));
      -      // Preserve Extra Data
      -      this.array = this.array.slice(frame.length, this.array.length);
      -      this.cursor -= FullMsgLength;
      -      this.push(frame);
      -    }
      -    cb();
      -  }
      -};
      -
      -module.exports = CCTalkParser;
      -
      -
      -
      - - - - -
      - -
      - -
      - Documentation generated by JSDoc 3.5.5 on Tue Feb 27 2018 23:06:42 GMT-0500 (EST) using the docdash theme. -
      - - - - - diff --git a/docs/parsers_delimiter.js.html b/docs/parsers_delimiter.js.html deleted file mode 100644 index c889782b7..000000000 --- a/docs/parsers_delimiter.js.html +++ /dev/null @@ -1,109 +0,0 @@ - - - - - parsers/delimiter.js - Documentation - - - - - - - - - - - - - - - - -
      - -

      parsers/delimiter.js

      - - - - - - - -
      -
      -
      'use strict';
      -const Buffer = require('safe-buffer').Buffer;
      -const Transform = require('stream').Transform;
      -/**
      - * A transform stream that emits data each time a byte sequence is received.
      - * @extends Transform
      - * @example
      -// To use the `Delimiter` parser, provide a delimiter as a string, buffer, or array of bytes:
      -const SerialPort = require('serialport');
      -const Delimiter = SerialPort.parsers.Delimiter;
      -const port = new SerialPort('/dev/tty-usbserial1');
      -const parser = port.pipe(new Delimiter({ delimiter: '\n' }));
      -parser.on('data', console.log);
      - */
      -class DelimiterParser extends Transform {
      -  constructor(options) {
      -    options = options || {};
      -    super(options);
      -
      -    if (options.delimiter === undefined) {
      -      throw new TypeError('"delimiter" is not a bufferable object');
      -    }
      -
      -    if (options.delimiter.length === 0) {
      -      throw new TypeError('"delimiter" has a 0 or undefined length');
      -    }
      -
      -    this.includeDelimiter = options.includeDelimiter !== undefined ? options.includeDelimiter : false;
      -    this.delimiter = Buffer.from(options.delimiter);
      -    this.buffer = Buffer.alloc(0);
      -  }
      -
      -  _transform(chunk, encoding, cb) {
      -    let data = Buffer.concat([this.buffer, chunk]);
      -    let position;
      -    while ((position = data.indexOf(this.delimiter)) !== -1) {
      -      this.push(data.slice(0, position + (this.includeDelimiter ? this.delimiter.length : 0)));
      -      data = data.slice(position + this.delimiter.length);
      -    }
      -    this.buffer = data;
      -    cb();
      -  }
      -
      -  _flush(cb) {
      -    this.push(this.buffer);
      -    this.buffer = Buffer.alloc(0);
      -    cb();
      -  }
      -};
      -
      -module.exports = DelimiterParser;
      -
      -
      -
      - - - - -
      - -
      - -
      - Documentation generated by JSDoc 3.5.5 on Tue Feb 27 2018 23:06:42 GMT-0500 (EST) using the docdash theme. -
      - - - - - diff --git a/docs/parsers_readline.js.html b/docs/parsers_readline.js.html deleted file mode 100644 index 6cbc3dbf3..000000000 --- a/docs/parsers_readline.js.html +++ /dev/null @@ -1,89 +0,0 @@ - - - - - parsers/readline.js - Documentation - - - - - - - - - - - - - - - - -
      - -

      parsers/readline.js

      - - - - - - - -
      -
      -
      'use strict';
      -const Buffer = require('safe-buffer').Buffer;
      -const DelimiterParser = require('./delimiter');
      -/**
      - *  A transform stream that emits data after a newline delimiter is received.
      - *
      - *  To use the `Readline` parser, provide a delimiter (defaults to `\n`). Data is emitted as string controllable by the `encoding` option (defaults to `utf8`).
      - * @extends DelimiterParser
      - * @example
      -const SerialPort = require('serialport');
      -const Readline = SerialPort.parsers.Readline;
      -const port = new SerialPort('/dev/tty-usbserial1');
      -const parser = port.pipe(new Readline({ delimiter: '\r\n' }));
      -parser.on('data', console.log);
      -*/
      -class ReadLineParser extends DelimiterParser {
      -  constructor(options) {
      -    const opts = Object.assign({
      -      delimiter: Buffer.from('\n', 'utf8'),
      -      encoding: 'utf8'
      -    }, options);
      -
      -    if (typeof opts.delimiter === 'string') {
      -      opts.delimiter = Buffer.from(opts.delimiter, opts.encoding);
      -    }
      -
      -    super(opts);
      -  }
      -};
      -
      -module.exports = ReadLineParser;
      -
      -
      -
      - - - - -
      - -
      - -
      - Documentation generated by JSDoc 3.5.5 on Tue Feb 27 2018 23:06:42 GMT-0500 (EST) using the docdash theme. -
      - - - - - diff --git a/docs/parsers_ready.js.html b/docs/parsers_ready.js.html deleted file mode 100644 index 773240f05..000000000 --- a/docs/parsers_ready.js.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - parsers/ready.js - Documentation - - - - - - - - - - - - - - - - -
      - -

      parsers/ready.js

      - - - - - - - -
      -
      -
      'use strict';
      -const Buffer = require('safe-buffer').Buffer;
      -const Transform = require('stream').Transform;
      -/**
      - * A transform stream that waits for a sequence of "ready" bytes before emitting a ready event and emitting data events
      - *
      - * To use the `Ready` parser provide a byte start sequence. After the bytes have been received a ready event is fired and data events are passed through.
      - * @extends Transform
      - * @example
      -const SerialPort = require('serialport');
      -const Ready = SerialPort.parsers.Ready;
      -const port = new SerialPort('/dev/tty-usbserial1');
      -const parser = port.pipe(new Ready({ delimiter: 'READY' }));
      -parser.on('ready', () => console.log('the ready byte sequence has been received'))
      -parser.on('data', console.log); // all data after READY is received
      - */
      -class ReadyParser extends Transform {
      -  /**
      -   *
      -   * @param {object} options options for the parser
      -   * @param {string|Buffer|array} options.delimiter data to look for before emitted "ready"
      -   */
      -  constructor(options) {
      -    options = options || {};
      -    if (options.delimiter === undefined) {
      -      throw new TypeError('"delimiter" is not a bufferable object');
      -    }
      -
      -    if (options.delimiter.length === 0) {
      -      throw new TypeError('"delimiter" has a 0 or undefined length');
      -    }
      -
      -    super(options);
      -    this.delimiter = Buffer.from(options.delimiter);
      -    this.readOffset = 0;
      -    this.ready = false;
      -  }
      -
      -  _transform(chunk, encoding, cb) {
      -    if (this.ready) {
      -      this.push(chunk);
      -      return cb();
      -    }
      -    const delimiter = this.delimiter;
      -    let chunkOffset = 0;
      -    while (this.readOffset < delimiter.length && chunkOffset < chunk.length) {
      -      if (delimiter[this.readOffset] === chunk[chunkOffset]) {
      -        this.readOffset++;
      -      } else {
      -        this.readOffset = 0;
      -      }
      -      chunkOffset++;
      -    }
      -    if (this.readOffset === delimiter.length) {
      -      this.ready = true;
      -      this.emit('ready');
      -      const chunkRest = chunk.slice(chunkOffset);
      -      if (chunkRest.length > 0) {
      -        this.push(chunkRest);
      -      }
      -    }
      -    cb();
      -  }
      -};
      -
      -module.exports = ReadyParser;
      -
      -
      -
      - - - - -
      - -
      - -
      - Documentation generated by JSDoc 3.5.5 on Tue Feb 27 2018 23:06:42 GMT-0500 (EST) using the docdash theme. -
      - - - - - diff --git a/docs/parsers_regex.js.html b/docs/parsers_regex.js.html deleted file mode 100644 index f6454aec4..000000000 --- a/docs/parsers_regex.js.html +++ /dev/null @@ -1,110 +0,0 @@ - - - - - parsers/regex.js - Documentation - - - - - - - - - - - - - - - - -
      - -

      parsers/regex.js

      - - - - - - - -
      -
      -
      'use strict';
      -const Transform = require('stream').Transform;
      -/**
      - * A transform stream that uses a regular expression to split the incoming text upon.
      - *
      - * To use the `Regex` parser provide a regular expression to split the incoming text upon. Data is emitted as string controllable by the `encoding` option (defaults to `utf8`).
      - * @extends Transform
      - * @example
      -const SerialPort = require('serialport');
      -const Regex = SerialPort.parsers.Regex;
      -const port = new SerialPort('/dev/tty-usbserial1');
      -const parser = port.pipe(new Regex({ regex: /[\r\n]+/ }));
      -parser.on('data', console.log);
      - */
      -class RegexParser extends Transform {
      -  constructor(options) {
      -    const opts = Object.assign({
      -      encoding: 'utf8'
      -    }, options);
      -
      -    if (opts.regex === undefined) {
      -      throw new TypeError('"options.regex" must be a regular expression pattern or object');
      -    }
      -
      -    if (!(opts.regex instanceof RegExp)) {
      -      opts.regex = new RegExp(opts.regex);
      -    }
      -    super(opts);
      -
      -    this.regex = opts.regex;
      -    this.buffer = '';
      -  }
      -
      -  _transform(chunk, encoding, cb) {
      -    const data = this.buffer + chunk;
      -    const parts = data.split(this.regex);
      -    this.buffer = parts.pop();
      -
      -    parts.forEach((part) => {
      -      this.push(part);
      -    });
      -    cb();
      -  }
      -
      -  _flush(cb) {
      -    this.push(this.buffer);
      -    this.buffer = '';
      -    cb();
      -  }
      -};
      -
      -module.exports = RegexParser;
      -
      -
      -
      - - - - -
      - -
      - -
      - Documentation generated by JSDoc 3.5.5 on Tue Feb 27 2018 23:06:42 GMT-0500 (EST) using the docdash theme. -
      - - - - - diff --git a/docs/serialport.js.html b/docs/serialport.js.html index 32065b77d..2598b5205 100644 --- a/docs/serialport.js.html +++ b/docs/serialport.js.html @@ -22,7 +22,7 @@
      @@ -373,7 +373,7 @@

      serialport.js

      */ /** - * Listening for the `data` event puts the port in flowing mode. Data is emitted as soon as it's received. Data is a `Buffer` object with a varying amount of data in it. The `readLine` parser converts the data into string lines. See the [parsers](#module_serialport--SerialPort.parsers) section for more information on parsers, and the [Node.js stream documentation](https://nodejs.org/api/stream.html#stream_event_data) for more information on the data event. + * Listening for the `data` event puts the port in flowing mode. Data is emitted as soon as it's received. Data is a `Buffer` object with a varying amount of data in it. The `readLine` parser converts the data into string lines. See the [parsers](https://node-serialport.github.io/node-serialport/global.html#Parsers) section for more information on parsers, and the [Node.js stream documentation](https://nodejs.org/api/stream.html#stream_event_data) for more information on the data event. * @event data */ @@ -684,7 +684,7 @@

      serialport.js


      - Documentation generated by JSDoc 3.5.5 on Tue Feb 27 2018 23:06:42 GMT-0500 (EST) using the docdash theme. + Documentation generated by JSDoc 3.5.5 on Sat Mar 10 2018 23:49:02 GMT-0500 (EST) using the docdash theme.
      diff --git a/lib/bindings/linux-list.js b/lib/bindings/linux-list.js index 3d79244b5..cd7764d7c 100644 --- a/lib/bindings/linux-list.js +++ b/lib/bindings/linux-list.js @@ -1,7 +1,7 @@ 'use strict'; const childProcess = require('child_process'); -const Readline = require('../parsers/readline'); +const Readline = require('parser-readline'); // get only serial port names function checkPathOfDevice(path) { diff --git a/lib/parsers.js b/lib/parsers.js new file mode 100644 index 000000000..941fad8e0 --- /dev/null +++ b/lib/parsers.js @@ -0,0 +1,36 @@ +'use strict'; +/** + * Parsers are collection of transform streams to processes incoming data + * @summary The default `Parsers` are [Transform streams](https://nodejs.org/api/stream.html#stream_class_stream_transform) that process incoming data. To use the parsers, you must create them and then pipe the Serialport to the parser. Be careful to only write to the SerialPort object and not the parser. Full documentation for parsers can be found in [their api docs](https://node-serialport.github.io/parsers/). + * @typedef {Object} Parsers + * @property {Transform} ByteLength + * @property {Transform} CCtalk + * @property {Transform} Delimiter + * @property {Transform} Readline + * @property {Transform} Ready + * @property {Transform} Regex + + * @since 5.0.0 + * @example +```js +const SerialPort = require('serialport'); +const Readline = SerialPort.parsers.Readline; +const port = new SerialPort('/dev/tty-usbserial1'); +const parser = new Readline(); +port.pipe(parser); +parser.on('data', console.log); +port.write('ROBOT PLEASE RESPOND\n'); + +// Creating the parser and piping can be shortened to +// const parser = port.pipe(new Readline()); +``` + */ + +module.exports = { + ByteLength: require('parser-byte-length'), + CCTalk: require('parser-cctalk'), + Delimiter: require('parser-delimiter'), + Readline: require('parser-readline'), + Ready: require('parser-ready'), + Regex: require('parser-regex') +}; diff --git a/lib/parsers/byte-length.js b/lib/parsers/byte-length.js deleted file mode 100644 index 91271bec4..000000000 --- a/lib/parsers/byte-length.js +++ /dev/null @@ -1,58 +0,0 @@ -'use strict'; -const Buffer = require('safe-buffer').Buffer; -const Transform = require('stream').Transform; - -/** - * A transform stream that emits data as a buffer after a specific number of bytes are received. - * @extends Transform - * @param {Object} options parser options object - * @param {Number} options.length the number of bytes on each data event - * @example -// To use the `ByteLength` parser: -const SerialPort = require('serialport'); -const ByteLength = SerialPort.parsers.ByteLength -const port = new SerialPort('/dev/tty-usbserial1'); -const parser = port.pipe(new ByteLength({length: 8})); -parser.on('data', console.log); // will have 8 bytes per data event - */ -class ByteLengthParser extends Transform { - constructor(options) { - super(options); - options = options || {}; - - if (typeof options.length !== 'number') { - throw new TypeError('"length" is not a number'); - } - - if (options.length < 1) { - throw new TypeError('"length" is not greater than 0'); - } - - this.length = options.length; - this.position = 0; - this.buffer = Buffer.alloc(this.length); - } - - _transform(chunk, encoding, cb) { - let cursor = 0; - while (cursor < chunk.length) { - this.buffer[this.position] = chunk[cursor]; - cursor++; - this.position++; - if (this.position === this.length) { - this.push(this.buffer); - this.buffer = Buffer.alloc(this.length); - this.position = 0; - } - } - cb(); - } - - _flush(cb) { - this.push(this.buffer.slice(0, this.position)); - this.buffer = Buffer.alloc(this.length); - cb(); - } -}; - -module.exports = ByteLengthParser; diff --git a/lib/parsers/cctalk.js b/lib/parsers/cctalk.js deleted file mode 100644 index de03a6c96..000000000 --- a/lib/parsers/cctalk.js +++ /dev/null @@ -1,43 +0,0 @@ -'use strict'; -const Transform = require('stream').Transform; -const Buffer = require('safe-buffer').Buffer; -/** - * Parses the CCTalk protocol - * @extends Transform - * @example -// CCTalk Messages are emitted as buffers. -const SerialPort = require('serialport'); -const CCTalk = SerialPort.parsers.CCTalk; -const port = new SerialPort('/dev/ttyUSB0'); -const parser = port.pipe(new CCtalk()); -parser.on('data', console.log); - */ -class CCTalkParser extends Transform { - constructor() { - super(); - this.array = []; - this.cursor = 0; - } - _transform(buffer, _, cb) { - this.cursor += buffer.length; - // TODO: Better Faster es7 no supported by node 4 - // ES7 allows directly push [...buffer] - // this.array = this.array.concat(Array.from(buffer)); //Slower ?!? - Array.from(buffer) - .map((byte) => this.array.push(byte)); - while (this.cursor > 1 && this.cursor >= this.array[1] + 5) { - // full frame accumulated - // copy command from the array - const FullMsgLength = this.array[1] + 5; - - const frame = Buffer.from(this.array.slice(0, FullMsgLength)); - // Preserve Extra Data - this.array = this.array.slice(frame.length, this.array.length); - this.cursor -= FullMsgLength; - this.push(frame); - } - cb(); - } -}; - -module.exports = CCTalkParser; diff --git a/lib/parsers/delimiter.js b/lib/parsers/delimiter.js deleted file mode 100644 index 5653e7e20..000000000 --- a/lib/parsers/delimiter.js +++ /dev/null @@ -1,51 +0,0 @@ -'use strict'; -const Buffer = require('safe-buffer').Buffer; -const Transform = require('stream').Transform; -/** - * A transform stream that emits data each time a byte sequence is received. - * @extends Transform - * @example -// To use the `Delimiter` parser, provide a delimiter as a string, buffer, or array of bytes: -const SerialPort = require('serialport'); -const Delimiter = SerialPort.parsers.Delimiter; -const port = new SerialPort('/dev/tty-usbserial1'); -const parser = port.pipe(new Delimiter({ delimiter: '\n' })); -parser.on('data', console.log); - */ -class DelimiterParser extends Transform { - constructor(options) { - options = options || {}; - super(options); - - if (options.delimiter === undefined) { - throw new TypeError('"delimiter" is not a bufferable object'); - } - - if (options.delimiter.length === 0) { - throw new TypeError('"delimiter" has a 0 or undefined length'); - } - - this.includeDelimiter = options.includeDelimiter !== undefined ? options.includeDelimiter : false; - this.delimiter = Buffer.from(options.delimiter); - this.buffer = Buffer.alloc(0); - } - - _transform(chunk, encoding, cb) { - let data = Buffer.concat([this.buffer, chunk]); - let position; - while ((position = data.indexOf(this.delimiter)) !== -1) { - this.push(data.slice(0, position + (this.includeDelimiter ? this.delimiter.length : 0))); - data = data.slice(position + this.delimiter.length); - } - this.buffer = data; - cb(); - } - - _flush(cb) { - this.push(this.buffer); - this.buffer = Buffer.alloc(0); - cb(); - } -}; - -module.exports = DelimiterParser; diff --git a/lib/parsers/index.js b/lib/parsers/index.js deleted file mode 100644 index 6e18d42b2..000000000 --- a/lib/parsers/index.js +++ /dev/null @@ -1,37 +0,0 @@ -'use strict'; -/** - * The default `Parsers` are [Transform streams](https://nodejs.org/api/stream.html#stream_class_stream_transform) that parse data in different ways to transform incoming data. - - To use the parsers, you must create them and then pipe the Serialport to the parser. Be careful to only write to the SerialPort object and not the parser. - * @typedef {Object} Parsers - * @property {Transform} ByteLength - * @property {Transform} CCtalk - * @property {Transform} Delimiter - * @property {Transform} Readline - * @property {Transform} Ready - * @property {Transform} Regex - - * @since 5.0.0 - * @example -```js -const SerialPort = require('serialport'); -const Readline = SerialPort.parsers.Readline; -const port = new SerialPort('/dev/tty-usbserial1'); -const parser = new Readline(); -port.pipe(parser); -parser.on('data', console.log); -port.write('ROBOT PLEASE RESPOND\n'); - -// Creating the parser and piping can be shortened to -// const parser = port.pipe(new Readline()); -``` - */ - -module.exports = { - ByteLength: require('./byte-length'), - CCTalk: require('./cctalk'), - Delimiter: require('./delimiter'), - Readline: require('./readline'), - Ready: require('./ready'), - Regex: require('./regex') -}; diff --git a/lib/parsers/readline.js b/lib/parsers/readline.js deleted file mode 100644 index c463f4b64..000000000 --- a/lib/parsers/readline.js +++ /dev/null @@ -1,31 +0,0 @@ -'use strict'; -const Buffer = require('safe-buffer').Buffer; -const DelimiterParser = require('./delimiter'); -/** - * A transform stream that emits data after a newline delimiter is received. - * - * To use the `Readline` parser, provide a delimiter (defaults to `\n`). Data is emitted as string controllable by the `encoding` option (defaults to `utf8`). - * @extends DelimiterParser - * @example -const SerialPort = require('serialport'); -const Readline = SerialPort.parsers.Readline; -const port = new SerialPort('/dev/tty-usbserial1'); -const parser = port.pipe(new Readline({ delimiter: '\r\n' })); -parser.on('data', console.log); -*/ -class ReadLineParser extends DelimiterParser { - constructor(options) { - const opts = Object.assign({ - delimiter: Buffer.from('\n', 'utf8'), - encoding: 'utf8' - }, options); - - if (typeof opts.delimiter === 'string') { - opts.delimiter = Buffer.from(opts.delimiter, opts.encoding); - } - - super(opts); - } -}; - -module.exports = ReadLineParser; diff --git a/lib/parsers/ready.js b/lib/parsers/ready.js deleted file mode 100644 index e3495545d..000000000 --- a/lib/parsers/ready.js +++ /dev/null @@ -1,66 +0,0 @@ -'use strict'; -const Buffer = require('safe-buffer').Buffer; -const Transform = require('stream').Transform; -/** - * A transform stream that waits for a sequence of "ready" bytes before emitting a ready event and emitting data events - * - * To use the `Ready` parser provide a byte start sequence. After the bytes have been received a ready event is fired and data events are passed through. - * @extends Transform - * @example -const SerialPort = require('serialport'); -const Ready = SerialPort.parsers.Ready; -const port = new SerialPort('/dev/tty-usbserial1'); -const parser = port.pipe(new Ready({ delimiter: 'READY' })); -parser.on('ready', () => console.log('the ready byte sequence has been received')) -parser.on('data', console.log); // all data after READY is received - */ -class ReadyParser extends Transform { - /** - * - * @param {object} options options for the parser - * @param {string|Buffer|array} options.delimiter data to look for before emitted "ready" - */ - constructor(options) { - options = options || {}; - if (options.delimiter === undefined) { - throw new TypeError('"delimiter" is not a bufferable object'); - } - - if (options.delimiter.length === 0) { - throw new TypeError('"delimiter" has a 0 or undefined length'); - } - - super(options); - this.delimiter = Buffer.from(options.delimiter); - this.readOffset = 0; - this.ready = false; - } - - _transform(chunk, encoding, cb) { - if (this.ready) { - this.push(chunk); - return cb(); - } - const delimiter = this.delimiter; - let chunkOffset = 0; - while (this.readOffset < delimiter.length && chunkOffset < chunk.length) { - if (delimiter[this.readOffset] === chunk[chunkOffset]) { - this.readOffset++; - } else { - this.readOffset = 0; - } - chunkOffset++; - } - if (this.readOffset === delimiter.length) { - this.ready = true; - this.emit('ready'); - const chunkRest = chunk.slice(chunkOffset); - if (chunkRest.length > 0) { - this.push(chunkRest); - } - } - cb(); - } -}; - -module.exports = ReadyParser; diff --git a/lib/parsers/regex.js b/lib/parsers/regex.js deleted file mode 100644 index 977d04b78..000000000 --- a/lib/parsers/regex.js +++ /dev/null @@ -1,52 +0,0 @@ -'use strict'; -const Transform = require('stream').Transform; -/** - * A transform stream that uses a regular expression to split the incoming text upon. - * - * To use the `Regex` parser provide a regular expression to split the incoming text upon. Data is emitted as string controllable by the `encoding` option (defaults to `utf8`). - * @extends Transform - * @example -const SerialPort = require('serialport'); -const Regex = SerialPort.parsers.Regex; -const port = new SerialPort('/dev/tty-usbserial1'); -const parser = port.pipe(new Regex({ regex: /[\r\n]+/ })); -parser.on('data', console.log); - */ -class RegexParser extends Transform { - constructor(options) { - const opts = Object.assign({ - encoding: 'utf8' - }, options); - - if (opts.regex === undefined) { - throw new TypeError('"options.regex" must be a regular expression pattern or object'); - } - - if (!(opts.regex instanceof RegExp)) { - opts.regex = new RegExp(opts.regex); - } - super(opts); - - this.regex = opts.regex; - this.buffer = ''; - } - - _transform(chunk, encoding, cb) { - const data = this.buffer + chunk; - const parts = data.split(this.regex); - this.buffer = parts.pop(); - - parts.forEach((part) => { - this.push(part); - }); - cb(); - } - - _flush(cb) { - this.push(this.buffer); - this.buffer = ''; - cb(); - } -}; - -module.exports = RegexParser; diff --git a/lib/serialport.js b/lib/serialport.js index acffaa9ee..fe176aa74 100644 --- a/lib/serialport.js +++ b/lib/serialport.js @@ -334,7 +334,7 @@ SerialPort.prototype._writev = function(data, callback) { */ /** - * Listening for the `data` event puts the port in flowing mode. Data is emitted as soon as it's received. Data is a `Buffer` object with a varying amount of data in it. The `readLine` parser converts the data into string lines. See the [parsers](#module_serialport--SerialPort.parsers) section for more information on parsers, and the [Node.js stream documentation](https://nodejs.org/api/stream.html#stream_event_data) for more information on the data event. + * Listening for the `data` event puts the port in flowing mode. Data is emitted as soon as it's received. Data is a `Buffer` object with a varying amount of data in it. The `readLine` parser converts the data into string lines. See the [parsers](https://node-serialport.github.io/node-serialport/global.html#Parsers) section for more information on parsers, and the [Node.js stream documentation](https://nodejs.org/api/stream.html#stream_event_data) for more information on the data event. * @event data */ diff --git a/package.json b/package.json index 72e2ccbd9..3dc179cc7 100644 --- a/package.json +++ b/package.json @@ -60,6 +60,12 @@ "commander": "^2.13.0", "debug": "^3.1.0", "nan": "^2.9.2", + "parser-byte-length": "^1.0.2", + "parser-cctalk": "^1.0.2", + "parser-delimiter": "^1.0.2", + "parser-readline": "^1.0.2", + "parser-ready": "^1.0.2", + "parser-regex": "^1.0.2", "prebuild-install": "^2.4.1", "promirepl": "^1.0.1", "prompt-list": "^3.1.2", diff --git a/test/parser-byte-length.js b/test/parser-byte-length.js deleted file mode 100644 index dde382fda..000000000 --- a/test/parser-byte-length.js +++ /dev/null @@ -1,63 +0,0 @@ -'use strict'; -/* eslint-disable no-new */ - -const Buffer = require('safe-buffer').Buffer; -const sinon = require('sinon'); -const ByteLengthParser = require('../lib/parsers/byte-length'); - -describe('ByteLengthParser', () => { - it('emits data events every 8 bytes', () => { - const data = Buffer.from('Robots are so freaking cool!'); - const spy = sinon.spy(); - const parser = new ByteLengthParser({ length: 8 }); - parser.on('data', spy); - parser.write(data); - assert.equal(spy.callCount, 3); - assert.deepEqual(spy.getCall(0).args[0], Buffer.from('Robots a')); - assert.deepEqual(spy.getCall(1).args[0], Buffer.from('re so fr')); - assert.deepEqual(spy.getCall(2).args[0], Buffer.from('eaking c')); - }); - - it('throws when not provided with a length', () => { - assert.throws(() => { - new ByteLengthParser({}); - }); - }); - - it('throws when length is zero', () => { - assert.throws(() => { - new ByteLengthParser({ - length: 0 - }); - }); - }); - - it('throws when called with a non numeric length', () => { - assert.throws(() => { - new ByteLengthParser({ - length: 'foop' - }); - }); - }); - - it('continues looking for bytes in additional writes', () => { - const parser = new ByteLengthParser({ length: 4 }); - const spy = sinon.spy(); - parser.on('data', spy); - parser.write(Buffer.from('ab')); - parser.write(Buffer.from('cd')); - assert.equal(spy.callCount, 1); - assert.deepEqual(spy.getCall(0).args[0], Buffer.from('abcd')); - }); - - it('flushes remaining data when the stream ends', () => { - const parser = new ByteLengthParser({ length: 4 }); - const spy = sinon.spy(); - parser.on('data', spy); - parser.write(Buffer.from('12')); - assert.equal(spy.callCount, 0); - parser.end(); - assert.equal(spy.callCount, 1); - assert.deepEqual(spy.getCall(0).args[0], Buffer.from('12')); - }); -}); diff --git a/test/parser-cctalk.js b/test/parser-cctalk.js deleted file mode 100644 index 7c757a8e7..000000000 --- a/test/parser-cctalk.js +++ /dev/null @@ -1,41 +0,0 @@ -'use strict'; -/* eslint-disable no-new */ - -const Buffer = require('safe-buffer').Buffer; -const sinon = require('sinon'); -const CCTalkParser = require('../lib/parsers/cctalk'); - -describe('CCTalkParser', () => { - it('emits data for a default length message', () => { - const data = Buffer.from([2, 0, 1, 254, 217]); - const spy = sinon.spy(); - const parser = new CCTalkParser(); - parser.on('data', spy); - parser.write(data); - assert.equal(spy.callCount, 1); - assert.deepEqual(spy.getCall(0).args[0], Buffer.from([2, 0, 1, 254, 217])); - }); - - it('emits data for a 7 byte length message', () => { - const parser = new CCTalkParser(); - const spy = sinon.spy(); - parser.on('data', spy); - parser.write(Buffer.from([2, 2, 1, 254, 1, 1, 217])); - assert.equal(spy.callCount, 1); - assert.deepEqual(spy.getCall(0).args[0], Buffer.from([2, 2, 1, 254, 1, 1, 217])); - }); - - it('emits 2 times data first length 7 secund length 5', () => { - const parser = new CCTalkParser(); - const spy = sinon.spy(); - parser.on('data', spy); - parser.write(Buffer.from([2, 2, 1])); - parser.write(Buffer.from([254, 1, 1])); - parser.write(Buffer.from([217, 2])); - parser.write(Buffer.from([0, 1, 254, 217])); - assert.equal(spy.callCount, 2); - assert.deepEqual(spy.getCall(0).args[0], Buffer.from([2, 2, 1, 254, 1, 1, 217])); - assert.deepEqual(spy.getCall(1).args[0], Buffer.from([2, 0, 1, 254, 217])); - }); -}); -// TODO: parser.write(Buffer.from([2, 2, 1, 254, 1, 1, 217, 2, 0, 1, 254, 217, 2, 2, 1, 251, 1, 1, 217, 2, 2, 1, 252, 1, 1, 217, 2, 0, 1, 253, 217])); diff --git a/test/parser-delimiter.js b/test/parser-delimiter.js deleted file mode 100644 index efecd542d..000000000 --- a/test/parser-delimiter.js +++ /dev/null @@ -1,143 +0,0 @@ -'use strict'; -/* eslint-disable no-new */ - -const Buffer = require('safe-buffer').Buffer; -const sinon = require('sinon'); - -const DelimiterParser = require('../lib/parsers/delimiter'); - -describe('DelimiterParser', () => { - it('transforms data to strings split on a delimiter', () => { - const spy = sinon.spy(); - const parser = new DelimiterParser({ - delimiter: Buffer.from('\n') - }); - parser.on('data', spy); - parser.write(Buffer.from('I love robots\nEach ')); - parser.write(Buffer.from('and Every One\n')); - parser.write(Buffer.from('\n')); - parser.write(Buffer.from('even you!')); - - assert.deepEqual(spy.getCall(0).args[0], Buffer.from('I love robots')); - assert.deepEqual(spy.getCall(1).args[0], Buffer.from('Each and Every One')); - assert(spy.calledTwice); - }); - - it('includes delimiter when includeDelimiter is true', () => { - const spy = sinon.spy(); - const parser = new DelimiterParser({ - delimiter: Buffer.from('\n'), - includeDelimiter: true - }); - parser.on('data', spy); - parser.write(Buffer.from('I love robots\nEach ')); - parser.write(Buffer.from('and Every One\n')); - parser.write(Buffer.from('\n')); - parser.write(Buffer.from('even you!')); - - assert.deepEqual(spy.getCall(0).args[0], Buffer.from('I love robots\n')); - assert.deepEqual(spy.getCall(1).args[0], Buffer.from('Each and Every One\n')); - assert.deepEqual(spy.getCall(2).args[0], Buffer.from('\n')); - assert.equal(spy.callCount, 3); - }); - - it('flushes remaining data when the stream ends', () => { - const parser = new DelimiterParser({ delimiter: Buffer.from([0]) }); - const spy = sinon.spy(); - parser.on('data', spy); - parser.write(Buffer.from([1])); - assert.equal(spy.callCount, 0); - parser.end(); - assert.equal(spy.callCount, 1); - assert.deepEqual(spy.getCall(0).args[0], Buffer.from([1])); - }); - - it('throws when not provided with a delimiter', () => { - assert.throws(() => { - new DelimiterParser({}); - }); - }); - - it('throws when called with a 0 length delimiter', () => { - assert.throws(() => { - new DelimiterParser({ - delimiter: Buffer.alloc(0) - }); - }); - - assert.throws(() => { - new DelimiterParser({ - delimiter: '' - }); - }); - - assert.throws(() => { - new DelimiterParser({ - delimiter: [] - }); - }); - }); - - it('allows setting of the delimiter with a string', () => { - new DelimiterParser({ delimiter: 'string' }); - }); - - it('allows setting of the delimiter with a buffer', () => { - new DelimiterParser({ delimiter: Buffer.from([1]) }); - }); - - it('allows setting of the delimiter with an array of bytes', () => { - new DelimiterParser({ delimiter: [1] }); - }); - - it('emits data events every time it meets 00x 00x', () => { - const data = Buffer.from('This could be\0\0binary data\0\0sent from a Moteino\0\0'); - const parser = new DelimiterParser({ delimiter: [0, 0] }); - const spy = sinon.spy(); - parser.on('data', spy); - parser.write(data); - assert.equal(spy.callCount, 3); - assert.deepEqual(spy.getCall(0).args[0], Buffer.from('This could be')); - assert.deepEqual(spy.getCall(1).args[0], Buffer.from('binary data')); - assert.deepEqual(spy.getCall(2).args[0], Buffer.from('sent from a Moteino')); - }); - - it('accepts single byte delimiter', () => { - const data = Buffer.from('This could be\0binary data\0sent from a Moteino\0'); - const parser = new DelimiterParser({ delimiter: [0] }); - const spy = sinon.spy(); - parser.on('data', spy); - parser.write(data); - assert.equal(spy.callCount, 3); - }); - - it('Works when buffer starts with delimiter', () => { - const data = Buffer.from('\0Hello\0World\0'); - const parser = new DelimiterParser({ delimiter: Buffer.from([0]) }); - const spy = sinon.spy(); - parser.on('data', spy); - parser.write(data); - assert.equal(spy.callCount, 2); - }); - - it('should only emit if delimiters are strictly in row', () => { - const data = Buffer.from('\0Hello\u0001World\0\0\u0001'); - const parser = new DelimiterParser({ delimiter: [0, 1] }); - const spy = sinon.spy(); - parser.on('data', spy); - parser.write(data); - assert.equal(spy.callCount, 1); - }); - - it('continues looking for delimiters in the next buffers', () => { - const parser = new DelimiterParser({ delimiter: [0, 0] }); - const spy = sinon.spy(); - parser.on('data', spy); - parser.write(Buffer.from('This could be\0\0binary ')); - parser.write(Buffer.from('data\0\0sent from a Moteino\0\0')); - assert.equal(spy.callCount, 3); - assert.deepEqual(spy.getCall(0).args[0], Buffer.from('This could be')); - assert.deepEqual(spy.getCall(1).args[0], Buffer.from('binary data')); - assert.deepEqual(spy.getCall(2).args[0], Buffer.from('sent from a Moteino')); - }); -}); diff --git a/test/parser-readline.js b/test/parser-readline.js deleted file mode 100644 index b37aca5b2..000000000 --- a/test/parser-readline.js +++ /dev/null @@ -1,115 +0,0 @@ -'use strict'; -/* eslint-disable no-new */ - -const Buffer = require('safe-buffer').Buffer; -const sinon = require('sinon'); - -const ReadlineParser = require('../lib/parsers/readline'); - -describe('ReadlineParser', () => { - it('transforms data to strings split on a delimiter', () => { - const spy = sinon.spy(); - const parser = new ReadlineParser(); - parser.on('data', spy); - parser.write(Buffer.from('I love robots\nEach ')); - parser.write(Buffer.from('and Every One\n')); - parser.write(Buffer.from('even you!')); - assert(spy.calledWith('I love robots')); - assert(spy.calledWith('Each and Every One')); - assert(spy.calledTwice); - parser.end(); - assert(spy.calledWith('even you!')); - assert(spy.calledThrice); - }); - - it('allows setting of the delimiter with a string', () => { - const spy = sinon.spy(); - const parser = new ReadlineParser({ delimiter: 'a' }); - parser.on('data', spy); - parser.write(Buffer.from('how are youa')); - assert(spy.calledWith('how ')); - assert(spy.calledWith('re you')); - }); - - it('allows setting of the delimiter with a buffer', () => { - const spy = sinon.spy(); - const parser = new ReadlineParser({ delimiter: Buffer.from('a') }); - parser.on('data', spy); - parser.write(Buffer.from('how are youa')); - assert(spy.calledWith('how ')); - assert(spy.calledWith('re you')); - }); - - it('allows setting of the delimiter with an array of bytes', () => { - const spy = sinon.spy(); - const parser = new ReadlineParser({ delimiter: [97] }); - parser.on('data', spy); - parser.write(Buffer.from('how are youa')); - assert(spy.calledWith('how ')); - assert(spy.calledWith('re you')); - }); - - it('allows setting of encoding', () => { - const spy = sinon.spy(); - const parser = new ReadlineParser({ - encoding: 'hex' - }); - parser.on('data', spy); - parser.write(Buffer.from('a\nb\n')); - assert.equal(spy.getCall(0).args[0], '61'); - assert.equal(spy.getCall(1).args[0], '62'); - }); - - it('encoding should be reflected in a string delimiter', () => { - const spy = sinon.spy(); - const parser = new ReadlineParser({ - delimiter: 'FF', - encoding: 'hex' - }); - parser.on('data', spy); - parser.write(Buffer.from([0, 255, 1, 255])); - assert.equal(spy.getCall(0).args[0], '00'); - assert.equal(spy.getCall(1).args[0], '01'); - }); - - it('throws when called with a 0 length delimiter', () => { - assert.throws(() => { - new ReadlineParser({ - delimiter: Buffer.alloc(0) - }); - }); - - assert.throws(() => { - new ReadlineParser({ - delimiter: '' - }); - }); - - assert.throws(() => { - new ReadlineParser({ - delimiter: [] - }); - }); - }); - - it('allows setting of the delimiter with a string', () => { - new ReadlineParser({ delimiter: 'string' }); - }); - - it('allows setting of the delimiter with a buffer', () => { - new ReadlineParser({ delimiter: Buffer.from([1]) }); - }); - - it('allows setting of the delimiter with an array of bytes', () => { - new ReadlineParser({ delimiter: [1] }); - }); - - it('doesn\'t emits empty data events', () => { - const spy = sinon.spy(); - const parser = new ReadlineParser({ delimiter: 'a' }); - parser.on('data', spy); - parser.write(Buffer.from('aFa')); - assert(spy.calledOnce); - assert(spy.calledWith('F')); - }); -}); diff --git a/test/parser-ready.js b/test/parser-ready.js deleted file mode 100644 index fcdf92002..000000000 --- a/test/parser-ready.js +++ /dev/null @@ -1,99 +0,0 @@ -'use strict'; -/* eslint-disable no-new */ - -const Buffer = require('safe-buffer').Buffer; -const sinon = require('sinon'); - -const ReadyParser = require('../lib/parsers/ready'); - -describe('ReadyParser', () => { - it('emits data received after the ready data', () => { - const spy = sinon.spy(); - const parser = new ReadyParser({ - delimiter: Buffer.from('\n') - }); - parser.on('data', spy); - parser.write(Buffer.from('which will you get?')); - parser.write(Buffer.from('garbage\ngold')); - parser.write(Buffer.from('just for you')); - - assert.deepEqual(spy.getCall(0).args[0], Buffer.from('gold')); - assert.deepEqual(spy.getCall(1).args[0], Buffer.from('just for you')); - assert(spy.calledTwice); - }); - - it('emits the ready event before the data event', () => { - const spy = sinon.spy(); - const parser = new ReadyParser({ delimiter: '!' }); - parser.on('ready', () => { - parser.on('data', spy); - }); - parser.write(Buffer.from('!hi')); - assert(spy.calledOnce); - }); - - it('has a ready property', () => { - const parser = new ReadyParser({ - delimiter: Buffer.from('\n') - }); - parser.resume(); - assert.isFalse(parser.ready); - parser.write(Buffer.from('not the new line')); - assert.isFalse(parser.ready); - parser.write(Buffer.from('this is the \n')); - assert.isTrue(parser.ready); - }); - - it('throws when not provided with a delimiter', () => { - assert.throws(() => { - new ReadyParser({}); - }); - }); - - it('throws when called with a 0 length delimiter', () => { - assert.throws(() => { - new ReadyParser({ - delimiter: Buffer.alloc(0) - }); - }); - - assert.throws(() => { - new ReadyParser({ - delimiter: '' - }); - }); - - assert.throws(() => { - new ReadyParser({ - delimiter: [] - }); - }); - }); - - it('allows setting of the delimiter with a string', () => { - new ReadyParser({ delimiter: 'string' }); - }); - - it('allows setting of the delimiter with a buffer', () => { - new ReadyParser({ delimiter: Buffer.from([1]) }); - }); - - it('allows setting of the delimiter with an array of bytes', () => { - new ReadyParser({ delimiter: [1] }); - }); - - it('allows receiving the delimiter over small writes', () => { - const spy = sinon.spy(); - const parser = new ReadyParser({ - delimiter: Buffer.from('READY') - }); - parser.on('data', spy); - parser.write(Buffer.from('bad data then REA')); - parser.write(Buffer.from('D')); - parser.write(Buffer.from('Y')); - parser.write(Buffer.from('!!!!!!')); - - assert.deepEqual(spy.getCall(0).args[0], Buffer.from('!!!!!!')); - assert(spy.calledOnce); - }); -}); diff --git a/test/parser-regex.js b/test/parser-regex.js deleted file mode 100644 index 621fcb8a9..000000000 --- a/test/parser-regex.js +++ /dev/null @@ -1,120 +0,0 @@ -'use strict'; -/* eslint-disable no-new */ - -const Buffer = require('safe-buffer').Buffer; -const sinon = require('sinon'); - -const RegexParser = require('../lib/parsers/regex'); - -describe('RegexParser', () => { - it('transforms data to strings split on either carriage return or new line', () => { - const spy = sinon.spy(); - const parser = new RegexParser({ - regex: /[\r\n]+/ - }); - parser.on('data', spy); - parser.write(Buffer.from('I love robots\r\nEach ')); - parser.write(Buffer.from('and Every One\r')); - parser.write(Buffer.from('even you!')); - parser.write(Buffer.from('\nThe angry red robot')); - - assert(spy.calledThrice, 'expecting 3 data events'); - assert.deepEqual(spy.getCall(0).args[0], 'I love robots'); - assert.deepEqual(spy.getCall(1).args[0], 'Each and Every One'); - assert.deepEqual(spy.getCall(2).args[0], 'even you!'); - }); - - it('flushes remaining data when the stream ends', () => { - const parser = new RegexParser({ regex: /\n/ }); - const spy = sinon.spy(); - parser.on('data', spy); - parser.write(Buffer.from([1])); - assert.equal(spy.callCount, 0); - parser.end(); - assert.equal(spy.callCount, 1); - assert.deepEqual(spy.getCall(0).args[0], Buffer.from([1]).toString()); - }); - - it('throws when not provided with a regex', () => { - assert.throws(() => { - new RegexParser({}); - }); - }); - - it('throws when called with an invalid regex expression', () => { - assert.throws(() => { - new RegexParser({ - regex: '\\' - }); - }); - }); - - it('allows setting of the regex with a regex string', () => { - const spy = sinon.spy(); - const parser = new RegexParser({ regex: 'a|b' }); - parser.on('data', spy); - parser.write('bhow are youa'); - assert(spy.calledWith('how ')); - assert(spy.calledWith('re you')); - }); - - it('allows setting of the regex with a buffer', () => { - const parser = new RegexParser({ regex: Buffer.from('a|b') }); - const spy = sinon.spy(); - parser.on('data', spy); - parser.write('bhow are youa'); - assert(spy.calledWith('how ')); - assert(spy.calledWith('re you')); - }); - - it('allows setting of encoding', () => { - const spy = sinon.spy(); - const parser = new RegexParser({ - regex: /\r/, - encoding: 'hex' - }); - parser.on('data', spy); - parser.write(Buffer.from('a\rb\r')); - assert.equal(spy.getCall(0).args[0], '61'); - assert.equal(spy.getCall(1).args[0], '62'); - }); - - it('Works when buffer starts with regex regex', () => { - const data = Buffer.from('\rHello\rWorld\r'); - const parser = new RegexParser({ regex: /\r/ }); - const spy = sinon.spy(); - parser.on('data', spy); - parser.write(data); - assert.equal(spy.callCount, 2); - }); - - it('should match unicode in buffer string', () => { - const data = Buffer.from('\u000aHello\u000aWorld\u000d\u000a!'); - const parser = new RegexParser({ regex: /\r\n|\n/ }); - const spy = sinon.spy(); - parser.on('data', spy); - parser.write(data); - assert.equal(spy.callCount, 2); - }); - - it('continues looking for regexs in the next buffers', () => { - const parser = new RegexParser({ regex: /\r\n|\n/ }); - const spy = sinon.spy(); - parser.on('data', spy); - parser.write(Buffer.from('This could be\na poem ')); - parser.write(Buffer.from('or prose\r\nsent from a robot\r\n')); - assert.equal(spy.callCount, 3); - assert.deepEqual(spy.getCall(0).args[0], 'This could be'); - assert.deepEqual(spy.getCall(1).args[0], 'a poem or prose'); - assert.deepEqual(spy.getCall(2).args[0], 'sent from a robot'); - }); - - it('doesn\'t emits empty data events', () => { - const spy = sinon.spy(); - const parser = new RegexParser({ regex: /a|b/ }); - parser.on('data', spy); - parser.write(Buffer.from('abaFab')); - assert(spy.calledOnce); - assert(spy.calledWith('F')); - }); -});