Skip to content

Commit

Permalink
Use jsdoc to generate the api docs (#882)
Browse files Browse the repository at this point in the history
This moves a lot of docs into JSDOC and provides a doc build system including throwing a CI error if the docs are out of date or if the wrong file was edited. Docs are put into the README for now but html docs are possible. Updated contributors guide to explain how to update the docs.

Todo: 
 - transition static methods and parsers into jsdoc
 - options objects and callbacks show as instance methods
  • Loading branch information
reconbot committed Jul 25, 2016
1 parent 1b704cb commit 3d509b1
Show file tree
Hide file tree
Showing 7 changed files with 706 additions and 102 deletions.
431 changes: 431 additions & 0 deletions .README.hbs

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions .npmignore
@@ -1,6 +1,7 @@
.github
.jshintrc
.travis.yml
.README.hbs
appveyor.yml
AUTHORS.md
changelog.md
Expand Down
1 change: 1 addition & 0 deletions .travis.yml
Expand Up @@ -78,6 +78,7 @@ install:
script:
# linting no longer works on node 0.10
- node bin/at-least-node-4.0.js && npm run lint || true
- npm run docs-diff
- node ./
- npm test

Expand Down
9 changes: 5 additions & 4 deletions CONTRIBUTING.md
Expand Up @@ -24,7 +24,7 @@ Python Version (if you're having trouble building serialport):


**Operating System:** (e.g Windows, OSX, Linux)
**NodeJS Version:**
**NodeJS Version:**
**SerialPort Version**
**Hardware you are having an issue with:** (e.g. arduino, another computer, etc)
**What your expectations are:**
Expand All @@ -49,11 +49,10 @@ All contributions must adhere to the eslint rules by maintaining the existing co

If you are contributing code, it must include unit tests that fail if the working code isn't present and succeed when it is.

When contributing new features you must include documentation.
When contributing new features you must include documentation.

It's very important that your pull requests include all of the above in order for users to be able to use your code. Pull requests with undocumented code will not be accepted.


<a name="writing-tests"></a>
## Writing Tests

Expand All @@ -64,9 +63,11 @@ Tests are written using [mocha](https://mochajs.org/), [chai](http://chaijs.com/

We are always looking to improve our docs. If you find that any are lacking information or have wrong information, fix and submit a PR. If you're looking for areas to start writing docs for, see the [docs](https://github.com/EmergingTechnologyAdvisors/node-serialport/labels/docs) label in issues.

We use [jsdoc](http://usejsdoc.org/) and [jsdoc-to-markdown](https://github.com/jsdoc2md/jsdoc-to-markdown) to generate our docs. Make your changes to `.README.hbs` or the documentation blocks in the JavaScript files and run `npm run docs` to update `README.md`.

Docs should have tested and working sample code. Many people using SerialPort are learning how to work with hardware for the first time, so write for a beginner audience.

<a name="sample-projects"></a>
## Sample Projects

Have you made something cool with SerialPort? Is it part of your latest product? Let us know! There are a lot of people out there hacking on similar projects and looking for ideas, help or code. It's great to share!
Have you made something cool with SerialPort? Is it part of your latest product? Let us know! There are a lot of people out there hacking on similar projects and looking for ideas, help or code. It's great to share!
257 changes: 164 additions & 93 deletions README.md

Large diffs are not rendered by default.

106 changes: 101 additions & 5 deletions lib/serialport.js
Expand Up @@ -74,6 +74,40 @@ function correctOptions(options) {
return options;
}

/**
* A callback called with an error or null.
* @typedef {function} SerialPort#errorCallback
* @param {?error} error
*/

/**
* @typedef {Object} SerialPort#openOptions
* @property {boolean} [autoOpen=true] - Automatically opens the port on `nextTick`
* @property {boolean} [lock=true] Prevent other processes from opening the port. false is not currently supported on windows.
* @property {number} [baudRate=9600] The baud rate of the port to be opened. This should match one of commonly available baud rates, such as 110, 300, 1200, 2400, 4800, 9600, 14400, 19200, 38400, 57600, 115200. There is no guarantee, that the device connected to the serial port will support the requested baud rate, even if the port itself supports that baud rate.
* @property {number} [dataBits=8] Must be one of: 8, 7, 6, or 5.
* @property {number} [stopBits=1] Must be one of: 1 or 2.
* @property {string} [parity=none] Must be one of: 'none', 'even', 'mark', 'odd', 'space'
* @property {boolean} [rtscts=false] flow control setting
* @property {boolean} [xon=false] flow control setting
* @property {boolean} [xoff=false] flow control setting
* @property {boolean} [xany=false] flow control setting
* @property {number} [bufferSize=65536] Size of read buffer
* @property {function} [parser=Parsers.raw] The parser to transform read data, defaults to the `raw` parser that emits data as it's received.
* @property {object=} platformOptions sets platform specific options
* @property {number} [platformOptions.vmin=1] see [`man termios`](http://linux.die.net/man/3/termios)
* @property {number} [platformOptions.vtime=0] see [`man termios`](http://linux.die.net/man/3/termios)
*/

/**
* Creates a SerialPort Object.
* @class
* @description Create a new serial port object for the `path`. In the case of invalid arguments or invalid options when constructing a new SerialPort it will throw an error. The port will open automatically by default which is the equivalent of calling `port.open(openCallback)` in the next tick. This can be disabled by setting the option `autoOpen` to false.
* @param {string} path - The system path of the serial port to open. For example, `/dev/tty.XXX` on Mac/Linux or `COM1` on Windows.
* @param {SerialPort#openOptions=} options - Port configuration options
* @param {SerialPort#errorCallback=} openCallback - Called when a connection has been opened. If this is not provided and an error occurs, it will be emitted on the ports `error` event. The callback will NOT be called if autoOpen is set to false in the openOptions as the open will not be performed.
* @throws {TypeError} When given invalid arguments a TypeError will be thrown.
*/
function SerialPort(path, options, callback) {
if (!(this instanceof SerialPort)) {
return new SerialPort(path, options, callback);
Expand Down Expand Up @@ -155,6 +189,12 @@ SerialPort.prototype._error = function(error, callback) {
}
};


/**
* Opens a connection to the given serial port.
* @param {SerialPort#errorCallback=} callback - Called when a connection has been opened. If this is not provided and an error occurs, it will be emitted on the ports `error` event.
* @fires SerialPort#open
*/
SerialPort.prototype.open = function(callback) {
if (this.isOpen()) {
return this._error(new Error('Port is already open'), callback);
Expand Down Expand Up @@ -194,6 +234,12 @@ SerialPort.prototype.open = function(callback) {
}.bind(this));
};

/**
* Changes the baud rate for an open port. Throws if you provide a bad argument. Emits an error or calls the callback if the baud rate isn't supported.
* @param {object=} options Only `baudRate` is currently supported
* @param {number=} [options.baudRate] The baud rate of the port to be opened. This should match one of commonly available baud rates, such as 110, 300, 1200, 2400, 4800, 9600, 14400, 19200, 38400, 57600, 115200. There is no guarantee, that the device connected to the serial port will support the requested baud rate, even if the port itself supports that baud rate.
* @param {SerialPort#errorCallback=} [callback] Called once the port's baud rate has been changed. If `.update` is called without an callback and there is an error, an error event will be emitted.
*/
SerialPort.prototype.update = function(options, callback) {
if (!this.isOpen()) {
debug('update attempted, but port is not open');
Expand All @@ -212,22 +258,33 @@ SerialPort.prototype.update = function(options, callback) {
}.bind(this));
};

/**
* Returns `true` if the port is open.
* @return {Boolean}
*/
SerialPort.prototype.isOpen = function() {
return this.fd !== null && !this.closing;
};

SerialPort.prototype.write = function(buffer, callback) {
/**
* Writes data to the given serial port.
* @param {(string|array|buffer)} data Accepts a [`Buffer` ](http://nodejs.org/api/buffer.html) object, or a type that is accepted by the `Buffer` constructor (ex. an array of bytes or a string).
* @param {SerialPort#errorCallback=} callback Called once the write operation returns.
* @description The write operation is non-blocking. When it returns, data may still have not actually been written to the serial port. See `drain()`.
* @description Some devices like the Arduino reset when you open a connection to them. In these cases if you immediately write to the device they wont be ready to receive the data. This is often worked around by having the Arduino send a "ready" byte that your node program waits for before writing. You can also often get away with waiting around 400ms.
*/
SerialPort.prototype.write = function(data, callback) {
if (!this.isOpen()) {
debug('write attempted, but port is not open');
return this._error(new Error('Port is not open'), callback);
}

if (!Buffer.isBuffer(buffer)) {
buffer = new Buffer(buffer);
if (!Buffer.isBuffer(data)) {
data = new Buffer(data);
}

debug('write ' + buffer.length + ' bytes of data');
SerialPortBinding.write(this.fd, buffer, function(err) {
debug('write ' + data.length + ' bytes of data');
SerialPortBinding.write(this.fd, data, function(err) {
if (err) {
debug('SerialPortBinding.write had an error', err);
return this._error(err, callback);
Expand Down Expand Up @@ -314,10 +371,17 @@ if (process.platform !== 'win32') {
this.options.dataCallback(data);
};


/**
* Pauses an open connection (unix only)
*/
SerialPort.prototype.pause = function() {
this.paused = true;
};

/**
* Resumes a paused connection (unix only)
*/
SerialPort.prototype.resume = function() {
this.paused = false;

Expand Down Expand Up @@ -363,6 +427,10 @@ SerialPort.prototype._disconnected = function(err) {
}.bind(this));
};

/**
* Closes an open connection
* @param {errorCallback} callback Called once a connection is closed.
*/
SerialPort.prototype.close = function(callback) {
this.paused = true;

Expand Down Expand Up @@ -396,6 +464,10 @@ SerialPort.prototype.close = function(callback) {
}.bind(this));
};

/**
* Flushes data received but not read. See [`tcflush()`](http://linux.die.net/man/3/tcflush) for Mac/Linux and [`FlushFileBuffers`](http://msdn.microsoft.com/en-us/library/windows/desktop/aa364439) for Windows.
* @param {SerialPort#errorCallback=} callback Called once the flush operation finishes.
*/
SerialPort.prototype.flush = function(callback) {
if (!this.isOpen()) {
debug('flush attempted, but port is not open');
Expand All @@ -411,6 +483,16 @@ SerialPort.prototype.flush = function(callback) {
}.bind(this));
};

/**
* Sets flags on an open port. Uses [`SetCommMask`](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363257(v=vs.85).aspx) for windows and [`ioctl`](http://linux.die.net/man/4/tty_ioctl) for mac and linux.
* @param {object=} options All options are operating system default when the port is opened. Every flag is set on each call to the provided or default values. If options isn't provided default options will be used.
* @param {Boolean} [options.brk=false]
* @param {Boolean} [options.cts=false]
* @param {Boolean} [options.dsr=false]
* @param {Boolean} [options.dtr=true]
* @param {Boolean} [options.rts=true]
* @param {SerialPort#errorCallback=} callback Called once the port's flags have been set.
*/
SerialPort.prototype.set = function(options, callback) {
if (!this.isOpen()) {
debug('set attempted, but port is not open');
Expand Down Expand Up @@ -442,6 +524,20 @@ SerialPort.prototype.set = function(options, callback) {
}.bind(this));
};

/**
* Waits until all output data has been transmitted to the serial port. See [`tcdrain()`](http://linux.die.net/man/3/tcdrain) or [FlushFileBuffers()](https://msdn.microsoft.com/en-us/library/windows/desktop/aa364439(v=vs.85).aspx) for more information.
* @param {SerialPort#errorCallback=} callback Called once the drain operation returns.
* @example
Writes `data` and waits until it has finish transmitting to the target serial port before calling the callback.
```
function writeAndDrain (data, callback) {
sp.write(data, function () {
sp.drain(callback);
});
}
```
*/
SerialPort.prototype.drain = function(callback) {
if (!this.isOpen()) {
debug('drain attempted, but port is not open');
Expand Down
3 changes: 3 additions & 0 deletions package.json
Expand Up @@ -69,6 +69,7 @@
"eslint-plugin-promise": "^1.1.0",
"eslint-plugin-standard": "^1.3.2",
"istanbul": "^0.4.4",
"jsdoc-to-markdown": "^1.3.6",
"mocha": "^2.4.5",
"node-pre-gyp-github": "^1.1.2",
"sandboxed-module": "^2.0.3",
Expand All @@ -86,6 +87,8 @@
},
"license": "MIT",
"scripts": {
"docs": "jsdoc2md -t .README.hbs -r table --separators --name-format lib/* > README.md",
"docs-diff": "jsdoc2md -t .README.hbs -r table --separators --name-format lib/* | diff README.md - || (echo 'Docs out of date, run `npm run docs` and commit the new README.md' && false)",
"install": "node-pre-gyp install --fallback-to-build",
"rebuild-all": "npm rebuild && node-gyp rebuild",
"stress": "mocha --no-timeouts test/arduinoTest/stress.js",
Expand Down

0 comments on commit 3d509b1

Please sign in to comment.