Comparing version 0.5.2 to 0.6.0
{ | ||
"name": "rpi-gpio", | ||
"version": "0.5.2", | ||
"version": "0.6.0", | ||
"description": "Control Raspberry Pi GPIO pins with node.js", | ||
@@ -33,4 +33,5 @@ "main": "rpi-gpio.js", | ||
"async": "~0.8.0", | ||
"debug": "~0.8.1" | ||
"debug": "~0.8.1", | ||
"epoll": "^0.1.13" | ||
} | ||
} |
@@ -10,3 +10,3 @@ rpi-gpio.js | ||
## Setup | ||
See this guide on how to get [node.js running on Raspberry Pi](http://joshondesign.com/2013/10/23/noderpi). | ||
See this guide on how to get [node.js running on Raspberry Pi](https://learn.adafruit.com/node-embedded-development/installing-node-dot-js). | ||
@@ -31,7 +31,9 @@ This module can then be installed with npm: | ||
#### setup(channel [, direction], callback) | ||
#### setup(channel [, direction, edge], callback) | ||
Sets up a channel for read or write. Must be done before the channel can be used. | ||
* channel: Reference to the pin in the current mode's schema. | ||
* direction: The pin direction, pass either DIR_IN for read mode or DIR_OUT for write mode. Defaults to DIR_OUT. | ||
* callback: Provides Error as the first argument if an error occured. | ||
* edge: Interrupt generating GPIO chip setting, pass in EDGE_NONE for no interrupts, EDGE_RISING for interrupts on rising values, EDGE_FALLING for interrupts on falling values or EDGE_BOTH for all interrupts. | ||
Defaults to EDGE_NONE. | ||
* callback: Provides Error as the first argument if an error occurred. | ||
@@ -53,6 +55,2 @@ #### read(channel, callback) | ||
#### setPollFrequency(value) | ||
Sets the poll frequency for checking whether pin values have changed. | ||
* value: The polling frequency in milliseconds, defaults to 5007. | ||
#### input() | ||
@@ -122,3 +120,3 @@ Alias of read(). | ||
}); | ||
gpio.setup(7, gpio.DIR_IN); | ||
gpio.setup(7, gpio.DIR_IN, gpio.EDGE_BOTH); | ||
``` | ||
@@ -145,3 +143,2 @@ | ||
console.log('All pins unexported'); | ||
return process.exit(0); | ||
}); | ||
@@ -162,5 +159,2 @@ } | ||
gpio.on('change', function(channel, value) { | ||
console.log('Channel ' + channel + ' value is now ' + value); | ||
}); | ||
gpio.setup(pin, gpio.DIR_OUT, on); | ||
@@ -172,3 +166,2 @@ | ||
console.log('Closed pins, now exit'); | ||
return process.exit(0); | ||
}); | ||
@@ -197,6 +190,2 @@ return; | ||
gpio.on('change', function(channel, value) { | ||
console.log('Channel ' + channel + ' value is now ' + value); | ||
}); | ||
async.parallel([ | ||
@@ -242,3 +231,2 @@ function(callback) { | ||
console.log('Closed pins, now exit'); | ||
return process.exit(0); | ||
}); | ||
@@ -245,0 +233,0 @@ }, 500); |
165
rpi-gpio.js
@@ -6,4 +6,6 @@ var fs = require('fs'); | ||
var debug = require('debug')('rpi-gpio'); | ||
var Epoll = require('epoll').Epoll; | ||
var PATH = '/sys/class/gpio'; | ||
var POLLERS = []; | ||
var PINS = { | ||
@@ -86,6 +88,5 @@ v1: { | ||
var currentPins; | ||
var exportedInputPins = {}; | ||
var exportedInputPins = {}; | ||
var exportedOutputPins = {}; | ||
var getPinForCurrentMode = getPinRpi; | ||
var pollFrequency = 5007; | ||
@@ -97,2 +98,7 @@ this.DIR_IN = 'in'; | ||
this.EDGE_NONE = 'none'; | ||
this.EDGE_RISING = 'rising'; | ||
this.EDGE_FALLING = 'falling'; | ||
this.EDGE_BOTH = 'both'; | ||
/** | ||
@@ -116,13 +122,2 @@ * Set pin reference mode. Defaults to 'mode_rpi'. | ||
/** | ||
* Set a custom polling frequency for watching pin changes | ||
* | ||
* @param {number} value The frequency to poll at, in milliseconds | ||
*/ | ||
this.setPollFrequency = function(value) { | ||
if (typeof value === 'number') { | ||
pollFrequency = value; | ||
} | ||
}; | ||
/** | ||
* Setup a channel for use as an input or output | ||
@@ -132,11 +127,17 @@ * | ||
* @param {string} direction The pin direction, either 'in' or 'out' | ||
* @param edge edge Informs the GPIO chip if it needs to generate interrupts. Either 'none', 'rising', 'falling' or 'both'. Defaults to 'none' | ||
* @param {function} onSetup Optional callback | ||
*/ | ||
this.setup = function(channel, direction, onSetup /*err*/) { | ||
this.setup = function(channel, direction, edge, onSetup /*err*/) { | ||
if (arguments.length === 2 && typeof direction == 'function') { | ||
onSetup = direction; | ||
direction = this.DIR_OUT; | ||
edge = this.EDGE_NONE; | ||
} else if (arguments.length === 3 && typeof edge == 'function') { | ||
onSetup = edge; | ||
edge = this.EDGE_NONE; | ||
} | ||
direction = direction || this.DIR_OUT; | ||
edge = edge || this.EDGE_NONE; | ||
onSetup = onSetup || function() {}; | ||
@@ -156,2 +157,8 @@ | ||
if (edge !== this.EDGE_NONE && edge !== this.EDGE_RISING && edge !== this.EDGE_FALLING && edge !== this.EDGE_BOTH) { | ||
return process.nextTick(function() { | ||
onSetup(new Error('Cannot set invalid edge')); | ||
}); | ||
} | ||
var pinForSetup; | ||
@@ -178,4 +185,6 @@ async.waterfall([ | ||
function(next) { | ||
setEdge(pinForSetup, edge, next); | ||
}, | ||
function(next) { | ||
this.emit('export', channel); | ||
createListener.call(this, channel, pinForSetup); | ||
@@ -189,2 +198,5 @@ if (direction === this.DIR_IN) { | ||
setDirection(pinForSetup, direction, next); | ||
}.bind(this), | ||
function(next) { | ||
this.listen(channel, next); | ||
}.bind(this) | ||
@@ -201,3 +213,3 @@ ], onSetup); | ||
*/ | ||
this.write = this.output = function(channel, value, cb /*err*/ ) { | ||
this.write = this.output = function(channel, value, cb /*err*/) { | ||
var pin = getPinForCurrentMode(channel); | ||
@@ -219,3 +231,3 @@ | ||
value = (!!value && value !== '0') ? '1' : '0'; | ||
fs.writeFile(PATH + '/gpio' + pin + '/value', value, cb || function () {}); | ||
fs.writeFile(PATH + '/gpio' + pin + '/value', value, cb || function() {}); | ||
}; | ||
@@ -245,2 +257,58 @@ | ||
/** | ||
* Listen for interrupts on a channel | ||
* | ||
* @param {number} channel The channel to watch | ||
* @param {function} cb Callback which receives the channel's err | ||
*/ | ||
this.listen = function(channel, cb /*err*/) { | ||
var _this = this; | ||
var pin = getPinForCurrentMode(channel); | ||
if (!exportedInputPins[pin] && !exportedOutputPins[pin]) { | ||
return process.nextTick(function() { | ||
cb(new Error('Pin has not been exported')); | ||
}); | ||
} | ||
POLLERS.forEach(function(map) { | ||
if (map.pin == pin) { | ||
return process.nextTick(function() { | ||
cb(new Error('Already watching that pin!')); | ||
}); | ||
} | ||
}); | ||
createListener(channel, pin, function(readChannel) { | ||
_this.read(readChannel, function(err, value) { | ||
debug( | ||
'failed to read value after a change on channel %d', | ||
readChannel | ||
); | ||
_this.emit('change', readChannel, value); | ||
}); | ||
}); | ||
return cb(null) | ||
}; | ||
/** | ||
* Stop listening for interrupts on a channel | ||
* | ||
* @param {number} channel The channel to stop watching | ||
* @param {function} cb Callback which receives the channel's err | ||
*/ | ||
this.stopListening = function(channel, cb /*err*/) { | ||
pin = getPinForCurrentMode(channel); | ||
cb = cb || function() {}; | ||
if (!exportedInputPins[pin] && !exportedOutputPins[pin]) { | ||
return process.nextTick(function() { | ||
cb(new Error('Pin has not been exported')); | ||
}); | ||
} | ||
removeListener(pin, cb) | ||
}; | ||
/** | ||
* Unexport any pins setup by this module | ||
@@ -251,2 +319,3 @@ * | ||
this.destroy = function(cb) { | ||
var _this = this; | ||
var tasks = Object.keys(exportedOutputPins) | ||
@@ -256,2 +325,3 @@ .concat(Object.keys(exportedInputPins)) | ||
return function(done) { | ||
removeListener(pin, function() { }) | ||
unexportPin(pin, done); | ||
@@ -269,3 +339,3 @@ } | ||
exportedOutputPins = {}; | ||
exportedInputPins = {}; | ||
exportedInputPins = {}; | ||
this.removeAllListeners(); | ||
@@ -275,3 +345,3 @@ | ||
getPinForCurrentMode = getPinRpi; | ||
pollFrequency = 5007; | ||
POLLERS = [] | ||
}; | ||
@@ -345,25 +415,12 @@ | ||
}; | ||
function createListener(channel, pin) { | ||
debug('listen for pin %d', pin); | ||
var Gpio = this; | ||
fs.watchFile( | ||
PATH + '/gpio' + pin + '/value', | ||
{ persistent: true, interval: pollFrequency }, | ||
function(current, previous) { | ||
if (current.mtime > previous.mtime) { | ||
Gpio.read(channel, function(err, value) { | ||
debug( | ||
'failed to read value after a change on channel %d', | ||
channel | ||
); | ||
Gpio.emit('change', channel, value); | ||
}); | ||
} | ||
} | ||
); | ||
}; | ||
} | ||
util.inherits(Gpio, EventEmitter); | ||
function setEdge(pin, edge, cb) { | ||
debug('set edge %s on pin %d', edge.toUpperCase(), pin); | ||
fs.writeFile(PATH + '/gpio' + pin + '/edge', edge, function(err) { | ||
if (cb) return cb(err); | ||
}); | ||
} | ||
function setDirection(pin, direction, cb) { | ||
@@ -385,3 +442,2 @@ debug('set direction %s on pin %d', direction.toUpperCase(), pin); | ||
debug('unexport pin %d', pin); | ||
fs.unwatchFile(PATH + '/gpio' + pin + '/value'); | ||
fs.writeFile(PATH + '/unexport', pin, function(err) { | ||
@@ -398,2 +454,31 @@ if (cb) return cb(err); | ||
function createListener(channel, pin, cb) { | ||
debug('listen for pin %d', pin); | ||
var fd = fs.openSync(PATH + '/gpio' + pin + '/value', 'r+'); | ||
var poller = new Epoll(function(err, fd, events) { | ||
clearInterrupt(fd); | ||
cb(channel); | ||
}); | ||
clearInterrupt(fd); | ||
poller.add(fd, Epoll.EPOLLPRI); | ||
POLLERS.push({pin: pin, poller: poller, fd: fd}); | ||
} | ||
function removeListener(pin, cb) { | ||
POLLERS.forEach(function(map, index) { | ||
if (map.pin == pin) { | ||
map.poller.remove(map.fd).close(); | ||
POLLERS.splice(index, 1); | ||
return cb(null); | ||
} | ||
}); | ||
} | ||
function clearInterrupt(fd) { | ||
fs.readSync(fd, new Buffer(1), 0, 1, 0); | ||
} | ||
module.exports = new Gpio; |
281
test/main.js
@@ -5,4 +5,25 @@ var assert = require('assert'); | ||
var sinon = require('sinon'); | ||
var gpio = require('../rpi-gpio.js'); | ||
var sandbox; | ||
// Store current listeners | ||
var listeners = [] | ||
// Stub epoll module | ||
epoll = {} | ||
require('epoll').Epoll = function(callback) { | ||
callback(null, 'fakeFd2') | ||
var listener = { | ||
add: sandbox.spy(), | ||
remove: sandbox.stub().returnsThis(), | ||
close: sandbox.stub() | ||
} | ||
listeners.push(listener) | ||
return listener | ||
} | ||
// Only load module after Epoll is stubbed | ||
var gpio = require('../rpi-gpio.js'); | ||
var PATH = '/sys/class/gpio'; | ||
@@ -17,21 +38,20 @@ | ||
before(function() { | ||
sinon.stub(fs, 'writeFile').yieldsAsync(); | ||
sinon.stub(fs, 'exists').yieldsAsync(false); | ||
sinon.stub(fs, 'watchFile').yieldsAsync({ mtime: 2000 }, { mtime: 1000 }); | ||
sinon.stub(fs, 'readFile') | ||
beforeEach(function() { | ||
sandbox = sinon.sandbox.create() | ||
sandbox.stub(fs, 'writeFile').yieldsAsync(); | ||
sandbox.stub(fs, 'exists').yieldsAsync(false); | ||
sandbox.stub(fs, 'openSync').returns('fakeFd') | ||
sandbox.stub(fs, 'readSync') | ||
sandbox.stub(fs, 'readFile') | ||
.withArgs('/proc/cpuinfo').yieldsAsync(null, getCpuInfo()); | ||
sinon.spy(fs, 'unwatchFile'); | ||
}); | ||
beforeEach(function() { | ||
gpio.reset(); | ||
gpio.setMode(gpio.MODE_BCM); | ||
gpio.version = 1; | ||
}); | ||
fs.writeFile.reset(); | ||
fs.exists.reset(); | ||
fs.watchFile.reset(); | ||
fs.readFile.reset(); | ||
fs.unwatchFile.reset(); | ||
afterEach(function() { | ||
sandbox.restore() | ||
listeners = [] | ||
}); | ||
@@ -44,3 +64,3 @@ | ||
beforeEach(function() { | ||
listener = sinon.spy(); | ||
listener = sandbox.spy(); | ||
gpio.on('modeChange', listener); | ||
@@ -61,3 +81,3 @@ | ||
beforeEach(function() { | ||
listener = sinon.spy(); | ||
listener = sandbox.spy(); | ||
gpio.on('modeChange', listener); | ||
@@ -89,21 +109,2 @@ | ||
describe('setPollFrequency()', function() { | ||
context('when poll frequency is set to 1000', function() { | ||
beforeEach(function() { | ||
gpio.setPollFrequency(1000); | ||
}); | ||
context('and a channel is set up', function() { | ||
beforeEach(function(done) { | ||
gpio.setup(7, null, done); | ||
}); | ||
it('should set up a file watcher with the specified poll frequency', function() { | ||
var args = fs.watchFile.lastCall.args; | ||
assert.deepEqual(args[1], { persistent: true, interval: 1000 }); | ||
}); | ||
}); | ||
}); | ||
}); | ||
describe('setup()', function() { | ||
@@ -114,3 +115,3 @@ context('when given an invalid channel', function() { | ||
beforeEach(function(done) { | ||
callback = sinon.spy(onSetupComplete); | ||
callback = sandbox.spy(onSetupComplete); | ||
function onSetupComplete() { | ||
@@ -133,3 +134,3 @@ done(); | ||
beforeEach(function(done) { | ||
callback = sinon.spy(onSetupComplete); | ||
callback = sandbox.spy(onSetupComplete); | ||
function onSetupComplete() { | ||
@@ -152,3 +153,3 @@ done(); | ||
beforeEach(function(done) { | ||
callback = sinon.spy(onSetupComplete); | ||
callback = sandbox.spy(onSetupComplete); | ||
function onSetupComplete() { | ||
@@ -167,2 +168,20 @@ done(); | ||
context('when given an invalid edge', function() { | ||
var callback; | ||
beforeEach(function(done) { | ||
callback = sandbox.spy(onSetupComplete); | ||
function onSetupComplete() { | ||
done(); | ||
} | ||
gpio.setup(7, gpio.DIR_IN, 'foo', callback); | ||
}); | ||
it('should run the callback with an error', function() { | ||
sinon.assert.calledOnce(callback); | ||
assert.ok(callback.getCall(0).args[0]); | ||
}); | ||
}); | ||
context('when the channel is already exported', function() { | ||
@@ -199,6 +218,6 @@ beforeEach(function(done) { | ||
beforeEach(function(done) { | ||
listener = sinon.spy(); | ||
listener = sandbox.spy(); | ||
gpio.on('export', listener); | ||
onSetup = sinon.spy(done); | ||
onSetup = sandbox.spy(done); | ||
gpio.setup(7, null, onSetup); | ||
@@ -224,12 +243,28 @@ }); | ||
it('should set the channel direction to out by default', function() { | ||
it('should set the channel edge to none by default', function() { | ||
sinon.assert.called(fs.writeFile); | ||
var args1 = fs.writeFile.getCall(1).args; | ||
assert.equal(args1[0], PATH + '/gpio7/direction'); | ||
assert.equal(args1[1], 'out'); | ||
assert.equal(args1[0], PATH + '/gpio7/edge'); | ||
assert.equal(args1[1], 'none'); | ||
}); | ||
it('should set up a file watcher for the value', function() { | ||
var args = fs.watchFile.lastCall.args; | ||
assert.equal(args[0], PATH + '/gpio7/value'); | ||
it('should set the channel direction to out by default', function() { | ||
sinon.assert.called(fs.writeFile); | ||
var args2 = fs.writeFile.getCall(2).args; | ||
assert.equal(args2[0], PATH + '/gpio7/direction'); | ||
assert.equal(args2[1], 'out'); | ||
}); | ||
it('should set up a listener', function() { | ||
assert.equal(listeners.length, 1) | ||
var listener = listeners[0] | ||
sinon.assert.calledWith(listener.add, 'fakeFd') | ||
}); | ||
it('should clear the interupt twice', function() { | ||
sinon.assert.calledTwice(fs.readSync) | ||
}); | ||
}); | ||
@@ -261,2 +296,20 @@ | ||
var edge_modes = ['none', 'rising', 'falling', 'both'] | ||
edge_modes.forEach(function(edge_mode) { | ||
var edgeConstant = 'EDGE_' + edge_mode.toUpperCase() | ||
context('and the edge is specified as ' + edge_mode, function() { | ||
beforeEach(function(done) { | ||
gpio.setup(7, gpio.DIR_OUT, gpio[edgeConstant], done); | ||
}); | ||
it('should set the channel edge to ' + edge_mode, function() { | ||
sinon.assert.called(fs.writeFile); | ||
var args1 = fs.writeFile.getCall(1).args; | ||
assert.equal(args1[0], PATH + '/gpio7/edge'); | ||
assert.equal(args1[1], edge_mode); | ||
}); | ||
}); | ||
}); | ||
context('and callback is specified', function() { | ||
@@ -266,3 +319,3 @@ var callback; | ||
beforeEach(function(done) { | ||
callback = sinon.spy(done); | ||
callback = sandbox.spy(done); | ||
gpio.setup(7, callback); | ||
@@ -285,3 +338,3 @@ }); | ||
beforeEach(function(done) { | ||
onSetup = sinon.spy(done); | ||
onSetup = sandbox.spy(done); | ||
gpio.setup(7, gpio.DIR_OUT, onSetup); | ||
@@ -366,3 +419,3 @@ }); | ||
} | ||
onWrite = sinon.spy(write); | ||
onWrite = sandbox.spy(write); | ||
gpio.write(3, true, onWrite); | ||
@@ -383,3 +436,3 @@ }); | ||
beforeEach(function(done) { | ||
onSetup = sinon.spy(done); | ||
onSetup = sandbox.spy(done); | ||
gpio.setup(7, gpio.DIR_IN, onSetup); | ||
@@ -392,4 +445,4 @@ }); | ||
done(); | ||
} | ||
onWrite = sinon.spy(callback); | ||
}; | ||
onWrite = sandbox.spy(callback); | ||
gpio.write(7, true, onWrite); | ||
@@ -423,3 +476,3 @@ }); | ||
beforeEach(function(done) { | ||
callback = sinon.spy(done); | ||
callback = sandbox.spy(done); | ||
gpio.read(7, callback); | ||
@@ -446,3 +499,3 @@ }); | ||
beforeEach(function(done) { | ||
callback = sinon.spy(done); | ||
callback = sandbox.spy(done); | ||
gpio.read(7, callback); | ||
@@ -467,3 +520,3 @@ }); | ||
} | ||
callback = sinon.spy(onRead); | ||
callback = sandbox.spy(onRead); | ||
gpio.read(3, callback); | ||
@@ -493,3 +546,3 @@ }); | ||
beforeEach(function(done) { | ||
callback = sinon.spy(done); | ||
callback = sandbox.spy(done); | ||
gpio.read(7, callback); | ||
@@ -510,2 +563,39 @@ }); | ||
describe('stopListening', function() { | ||
context('when pin 7 is setup for input', function() { | ||
beforeEach(function(done) { | ||
gpio.setup(7, gpio.DIR_IN, done); | ||
}); | ||
context('and stopListening is called with pin 7', function() { | ||
beforeEach(function(done) { | ||
gpio.stopListening(7, done); | ||
}); | ||
it('should stop listening to pin 7', function() { | ||
var listener = listeners[0] | ||
sinon.assert.calledOnce(listener.remove) | ||
sinon.assert.calledWith(listener.remove, 'fakeFd') | ||
}); | ||
}); | ||
}); | ||
context('when stopListening is called on a non-exported pin', function() { | ||
var onStopListening | ||
beforeEach(function(done) { | ||
var callback = function() { | ||
done(); | ||
}; | ||
onStopListening = sandbox.spy(callback); | ||
gpio.stopListening(7, onStopListening); | ||
}); | ||
it('should run the callback with an error', function() { | ||
sinon.assert.calledOnce(onStopListening); | ||
assert.ok(onStopListening.getCall(0).args[0]); | ||
}); | ||
}); | ||
}); | ||
describe('destroy', function() { | ||
@@ -520,35 +610,52 @@ context('when pins 7, 8 and 10 have been exported', function() { | ||
if (--i === 0) { | ||
onSetupComplete(); | ||
done() | ||
} | ||
}); | ||
}); | ||
}); | ||
function onSetupComplete() { | ||
it('should have created 3 listeners', function() { | ||
assert.equal(listeners.length, 3) | ||
}); | ||
context('and destroy() is run', function() { | ||
beforeEach(function(done) { | ||
fs.writeFile.reset(); | ||
gpio.destroy(done); | ||
} | ||
}); | ||
}) | ||
it('should unexport pin 7', function() { | ||
sinon.assert.calledWith(fs.writeFile, unexportPath, '7'); | ||
}); | ||
it('should unexport pin 7', function() { | ||
sinon.assert.calledWith(fs.writeFile, unexportPath, '7'); | ||
}); | ||
it('should unexport pin 8', function() { | ||
sinon.assert.calledWith(fs.writeFile, unexportPath, '8'); | ||
}); | ||
it('should unexport pin 8', function() { | ||
sinon.assert.calledWith(fs.writeFile, unexportPath, '8'); | ||
}); | ||
it('should unexport pin 10', function() { | ||
sinon.assert.calledWith(fs.writeFile, unexportPath, '10'); | ||
}); | ||
it('should unexport pin 10', function() { | ||
sinon.assert.calledWith(fs.writeFile, unexportPath, '10'); | ||
}); | ||
it('should unwatch pin 7', function() { | ||
sinon.assert.calledWith(fs.unwatchFile, PATH + '/gpio7/value'); | ||
}); | ||
it('should unwatch pin 7', function() { | ||
var listener = listeners[0] | ||
sinon.assert.calledOnce(listener.remove) | ||
sinon.assert.calledWith(listener.remove, 'fakeFd') | ||
sinon.assert.calledOnce(listener.close) | ||
}); | ||
it('should unwatch pin 8', function() { | ||
sinon.assert.calledWith(fs.unwatchFile, PATH + '/gpio8/value'); | ||
}); | ||
it('should unwatch pin 8', function() { | ||
var listener = listeners[1] | ||
sinon.assert.calledOnce(listener.remove) | ||
sinon.assert.calledWith(listener.remove, 'fakeFd') | ||
sinon.assert.calledOnce(listener.close) | ||
}); | ||
it('should unwatch pin 10', function() { | ||
sinon.assert.calledWith(fs.unwatchFile, PATH + '/gpio10/value'); | ||
it('should unwatch pin 9', function() { | ||
var listener = listeners[2] | ||
sinon.assert.calledOnce(listener.remove) | ||
sinon.assert.calledWith(listener.remove, 'fakeFd') | ||
sinon.assert.calledOnce(listener.close) | ||
}); | ||
}); | ||
@@ -566,6 +673,4 @@ | ||
// Remove previous stub so that we can control when watchFile triggers | ||
fs.watchFile.restore(); | ||
sinon.stub(fs, 'watchFile'); | ||
listener = sinon.spy(); | ||
listener = sandbox.spy(); | ||
gpio.on('change', listener); | ||
@@ -578,17 +683,6 @@ | ||
beforeEach(function(done) { | ||
fs.readFile.yieldsAsync(null, '1'); | ||
gpio.on('change', function() { | ||
done(); | ||
}); | ||
// Trigger voltage change | ||
var cb = fs.watchFile.lastCall.args[2]; | ||
cb({ mtime: 2000 }, { mtime: 1000 }); | ||
// this is erroring out due to watchFile not working as expected. Please fix | ||
}); | ||
it('should emit a change event', function() { | ||
sinon.assert.calledWith(listener, 7, true); | ||
}); | ||
}); | ||
@@ -602,5 +696,2 @@ }); | ||
// Remove previous stub so that we can control when watchFile triggers | ||
fs.watchFile.restore(); | ||
sinon.stub(fs, 'watchFile'); | ||
gpio.setup(7, gpio.DIR_IN); | ||
@@ -607,0 +698,0 @@ }); |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
49670
1083
3
250
+ Addedepoll@^0.1.13
+ Addedbindings@1.2.1(transitive)
+ Addedepoll@0.1.22(transitive)
+ Addednan@2.6.2(transitive)