Skip to content

Commit

Permalink
Add browser tests and use saucelabs to test them.
Browse files Browse the repository at this point in the history
This also finds and fixes errors related to string encoding and
some compatablity issues which allow it to work as far
back as IE 9 (probably IE 8 with an ES5 shm).
  • Loading branch information
calvinmetcalf committed Jun 22, 2015
1 parent 53b588e commit b681059
Show file tree
Hide file tree
Showing 51 changed files with 3,938 additions and 35 deletions.
41 changes: 35 additions & 6 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,38 @@
language: node_js
before_install:
- npm install -g npm
node_js:
- "0.8"
- "0.10"
- "0.11"
- "0.12"
- "iojs"
notifications:
email: false
matrix:
include:
- node_js: '0.8'
env: TASK=test
- node_js: '0.10'
env: TASK=test
- node_js: '0.11'
env: TASK=test
- node_js: '0.12'
env: TASK=test
- node_js: 'iojs'
env: TASK=test
- node_js: 'iojs'
env: TASK=browser BROWSER_NAME=opera BROWSER_VERSION="11..latest"
- node_js: 'iojs'
env: TASK=browser BROWSER_NAME=ie BROWSER_VERSION="9..latest"
- node_js: 'iojs'
env: TASK=browser BROWSER_NAME=chrome BROWSER_VERSION="39..beta"
- node_js: 'iojs'
env: TASK=browser BROWSER_NAME=firefox BROWSER_VERSION="34..beta"
- node_js: 'iojs'
env: TASK=browser BROWSER_NAME=ipad BROWSER_VERSION="6.0..latest"
- node_js: 'iojs'
env: TASK=browser BROWSER_NAME=iphone BROWSER_VERSION="6.0..latest"
- node_js: 'iojs'
env: TASK=browser BROWSER_NAME=safari BROWSER_VERSION="5..latest"
- node_js: 'iojs'
env: TASK=browser BROWSER_NAME=android BROWSER_VERSION="4.0..latest"
script: "npm run $TASK"
env:
global:
- secure: rE2Vvo7vnjabYNULNyLFxOyt98BoJexDqsiOnfiD6kLYYsiQGfr/sbZkPMOFm9qfQG7pjqx+zZWZjGSswhTt+626C0t/njXqug7Yps4c3dFblzGfreQHp7wNX5TFsvrxd6dAowVasMp61sJcRnB2w8cUzoe3RAYUDHyiHktwqMc=
- secure: g9YINaKAdMatsJ28G9jCGbSaguXCyxSTy+pBO6Ch0Cf57ZLOTka3HqDj8p3nV28LUIHZ3ut5WO43CeYKwt4AUtLpBS3a0dndHdY6D83uY6b2qh5hXlrcbeQTq2cvw2y95F7hm4D1kwrgZ7ViqaKggRcEupAL69YbJnxeUDKWEdI=
1 change: 1 addition & 0 deletions .zuul.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ui: tape
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
[![NPM](https://nodei.co/npm/readable-stream.png?downloads=true&downloadRank=true)](https://nodei.co/npm/readable-stream/)
[![NPM](https://nodei.co/npm-dl/readable-stream.png?&months=6&height=3)](https://nodei.co/npm/readable-stream/)


[![Sauce Test Status](https://saucelabs.com/browser-matrix/readable-stream.svg)](https://saucelabs.com/u/readable-stream)

```bash
npm install --save readable-stream
```
Expand Down
13 changes: 13 additions & 0 deletions build/common-replacements.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,16 @@ module.exports.altIndexOfUseReplacement = [
/(\W)([\w\.\(\),\[\]]+)(\.indexOf\()/gm
, '$1indexOf($2, '
]
module.exports.objectKeysDefine = [
/^('use strict';)$/m
, '$1\n\n/*<replacement>*/\nvar objectKeys = Object.keys || function (obj) {\n'
+ ' var keys = [];\n'
+ ' for (var key in obj) keys.push(key);\n'
+ ' return keys;\n'
+ '}\n/*</replacement>*/\n'
]

module.exports.objectKeysReplacement = [
/Object\.keys/g
, 'objectKeys'
]
26 changes: 11 additions & 15 deletions build/files.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,15 @@ const headRegexp = /(^module.exports = \w+;?)/m
]

, objectDefinePropertyReplacement = [
/Object.defineProperties/
/(Object\.defineProperties)/
, 'if (Object.defineProperties) $1'
]

, objectDefinePropertySingReplacement = [
/Object\.defineProperty\(([\w\W]+?)\}\);/
, '(function (){try {\n'
+ 'Object.defineProperty\($1});\n'
+ '}catch(_){}}());\n'
]

, isArrayDefine = [
headRegexp
Expand All @@ -78,19 +83,9 @@ const headRegexp = /(^module.exports = \w+;?)/m
, 'isArray'
]

, objectKeysDefine = [
headRegexp
, '$1\n\n/*<replacement>*/\nvar objectKeys = Object.keys || function (obj) {\n'
+ ' var keys = [];\n'
+ ' for (var key in obj) keys.push(key);\n'
+ ' return keys;\n'
+ '}\n/*</replacement>*/\n'
]
, objectKeysDefine = require('./common-replacements').objectKeysDefine

, objectKeysReplacement = [
/Object\.keys/g
, 'objectKeys'
]
, objectKeysReplacement = require('./common-replacements').objectKeysReplacement

, eventEmittterReplacement = [
/(require\('events'\)\.EventEmitter;)/
Expand Down Expand Up @@ -122,7 +117,7 @@ const headRegexp = /(^module.exports = \w+;?)/m
]

, isBufferReplacement = [
/(\w+) instanceof Buffer/
/(\w+) instanceof Buffer/g
, 'Buffer.isBuffer($1)'
]

Expand Down Expand Up @@ -202,6 +197,7 @@ module.exports['_stream_writable.js'] = [
, debugLogReplacement
, deprecateReplacement
, objectDefinePropertyReplacement
, objectDefinePropertySingReplacement
, bufferIsEncodingReplacement
, [ /^var assert = require\('assert'\);$/m, '' ]
, requireStreamReplacement
Expand Down
20 changes: 19 additions & 1 deletion build/test-replacements.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ const altForEachImplReplacement = require('./common-replacements').altForEachImp
, altForEachUseReplacement = require('./common-replacements').altForEachUseReplacement
, altIndexOfImplReplacement = require('./common-replacements').altIndexOfImplReplacement
, altIndexOfUseReplacement = require('./common-replacements').altIndexOfUseReplacement
, objectKeysDefine =
require('./common-replacements').objectKeysDefine
, objectKeysReplacement =
require('./common-replacements').objectKeysReplacement

module.exports.all = [
[
Expand Down Expand Up @@ -55,7 +59,9 @@ module.exports['test-stream-big-packet.js'] = [
]

module.exports['common.js'] = [
altForEachImplReplacement
objectKeysDefine
, objectKeysReplacement
, altForEachImplReplacement
, altForEachUseReplacement

, [
Expand Down Expand Up @@ -106,6 +112,18 @@ module.exports['common.js'] = [
+ '}\n'
+ '/*</replacement>*/\n'
]
, [
/^if \(global\.ArrayBuffer\) \{([^\}]+)\}$/m
, '/*<replacement>*/if (!process.browser) {'
+ '\nif \(global\.ArrayBuffer\) {$1}\n'
+ '}/*</replacement>*/\n'
]
, [
/^Object\.defineProperty\(([\w\W]+?)\}\)\;/mg
, '/*<replacement>*/if (!process.browser) {'
+ '\nObject\.defineProperty($1});\n'
+ '}/*</replacement>*/\n'
]
]

// this test has some trouble with the nextTick depth when run
Expand Down
14 changes: 7 additions & 7 deletions lib/_stream_duplex.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,6 @@

'use strict';

module.exports = Duplex;

/*<replacement>*/
var processNextTick = require('process-nextick-args');
/*</replacement>*/


/*<replacement>*/
var objectKeys = Object.keys || function (obj) {
var keys = [];
Expand All @@ -21,6 +14,13 @@ var objectKeys = Object.keys || function (obj) {
/*</replacement>*/


module.exports = Duplex;

/*<replacement>*/
var processNextTick = require('process-nextick-args');
/*</replacement>*/



/*<replacement>*/
var util = require('core-util-is');
Expand Down
7 changes: 5 additions & 2 deletions lib/_stream_writable.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,12 +143,15 @@ WritableState.prototype.getBuffer = function writableStateGetBuffer() {
return out;
};

(function (){try {

This comment has been minimized.

Copy link
@kumavis

kumavis Jun 27, 2015

Contributor

thank you for adding this-- streams were blowing up in sandboxed iframes b/c of a security error
TooTallNate/util-deprecate#2

This comment has been minimized.

Copy link
@calvinmetcalf

calvinmetcalf Jun 27, 2015

Author Contributor

haha was actually added to try to get it to work in IE8 but glad I left it in now :)

Object.defineProperty(WritableState.prototype, 'buffer', {
get: require('util-deprecate')(function() {
return this.getBuffer();
}, '_writableState.buffer is deprecated. Use ' +
'_writableState.getBuffer() instead.')
});
}catch(_){}}());


function Writable(options) {
var Duplex = require('./_stream_duplex');
Expand Down Expand Up @@ -217,7 +220,7 @@ Writable.prototype.write = function(chunk, encoding, cb) {
encoding = null;
}

if (chunk instanceof Buffer)
if (Buffer.isBuffer(chunk))
encoding = 'buffer';
else if (!encoding)
encoding = state.defaultEncoding;
Expand Down Expand Up @@ -282,7 +285,7 @@ function decodeChunk(state, chunk, encoding) {
function writeOrBuffer(stream, state, chunk, encoding, cb) {
chunk = decodeChunk(state, chunk, encoding);

if (chunk instanceof Buffer)
if (Buffer.isBuffer(chunk))
encoding = 'buffer';
var len = state.objectMode ? 1 : chunk.length;

Expand Down
9 changes: 6 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,20 @@
"main": "readable.js",
"dependencies": {
"core-util-is": "~1.0.0",
"process-nextick-args": "~1.0.0",
"inherits": "~2.0.1",
"isarray": "0.0.1",
"process-nextick-args": "~1.0.0",
"string_decoder": "~0.10.x",
"util-deprecate": "~1.0.1"
},
"devDependencies": {
"tap": "~0.2.6"
"tap": "~0.2.6",
"tape": "~4.0.0",
"zuul": "~3.0.0"
},
"scripts": {
"test": "tap test/parallel/*.js"
"test": "tap test/parallel/*.js",
"browser": "zuul --browser-name $BROWSER_NAME --browser-version $BROWSER_VERSION -- test/browser.js"
},
"repository": {
"type": "git",
Expand Down
61 changes: 61 additions & 0 deletions test/browser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
if (!global.console) {
global.console = {};
}
if (!global.console.log) {
global.console.log = function () {};
}
if (!global.console.error) {
global.console.error = global.console.log;
}
if (!global.console.info) {
global.console.info = global.console.log;
}
var test = require('tape');

test('streams', function (t) {
require('./browser/test-stream-big-packet')(t);
require('./browser/test-stream-big-push')(t);
require('./browser/test-stream-duplex')(t);
require('./browser/test-stream-end-paused')(t);
require('./browser/test-stream-ispaused')(t);
require('./browser/test-stream-pipe-after-end')(t);
require('./browser/test-stream-pipe-cleanup')(t);
require('./browser/test-stream-pipe-error-handling')(t);
require('./browser/test-stream-pipe-event')(t);
require('./browser/test-stream-push-order')(t);
require('./browser/test-stream-push-strings')(t);
require('./browser/test-stream-readable-constructor-set-methods')(t);
require('./browser/test-stream-readable-event')(t);
require('./browser/test-stream-transform-constructor-set-methods')(t);
require('./browser/test-stream-transform-objectmode-falsey-value')(t);
require('./browser/test-stream-transform-split-objectmode')(t);
require('./browser/test-stream-unshift-empty-chunk')(t);
require('./browser/test-stream-unshift-read-race')(t);
require('./browser/test-stream-writable-change-default-encoding')(t);
require('./browser/test-stream-writable-constructor-set-methods')(t);
require('./browser/test-stream-writable-decoded-encoding')(t);
require('./browser/test-stream-writev')(t);
});

test('streams 2', function (t) {
require('./browser/test-stream2-base64-single-char-read-end')(t);
require('./browser/test-stream2-compatibility')(t);
require('./browser/test-stream2-large-read-stall')(t);
require('./browser/test-stream2-objects')(t);
require('./browser/test-stream2-pipe-error-handling')(t);
require('./browser/test-stream2-pipe-error-once-listener')(t);
require('./browser/test-stream2-push')(t);
require('./browser/test-stream2-readable-empty-buffer-no-eof')(t);
require('./browser/test-stream2-readable-from-list')(t);
require('./browser/test-stream2-transform')(t);
require('./browser/test-stream2-set-encoding')(t);
require('./browser/test-stream2-readable-legacy-drain')(t);
require('./browser/test-stream2-readable-wrap-empty')(t);
require('./browser/test-stream2-readable-non-empty-end')(t);
require('./browser/test-stream2-readable-wrap')(t);
require('./browser/test-stream2-unpipe-drain')(t);
require('./browser/test-stream2-writable')(t);
});
test('streams 3', function (t) {
require('./browser/test-stream3-pause-then-read')(t);
});
62 changes: 62 additions & 0 deletions test/browser/test-stream-big-packet.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
'use strict';
var common = require('../common');
var inherits = require('inherits');
var stream = require('../../');

module.exports = function (t) {
t.test('big packet', function (t) {
t.plan(3);
var passed = false;

function PassThrough() {
stream.Transform.call(this);
};
inherits(PassThrough, stream.Transform);
PassThrough.prototype._transform = function(chunk, encoding, done) {
this.push(chunk);
done();
};

function TestStream() {
stream.Transform.call(this);
};
inherits(TestStream, stream.Transform);
TestStream.prototype._transform = function(chunk, encoding, done) {
if (!passed) {
// Char 'a' only exists in the last write
passed = indexOf(chunk.toString(), 'a') >= 0;
}
if (passed) {
t.ok(passed);
}
done();
};

var s1 = new PassThrough();
var s2 = new PassThrough();
var s3 = new TestStream();
s1.pipe(s3);
// Don't let s2 auto close which may close s3
s2.pipe(s3, {end: false});

// We must write a buffer larger than highWaterMark
var big = new Buffer(s1._writableState.highWaterMark + 1);
big.fill('x');

// Since big is larger than highWaterMark, it will be buffered internally.
t.ok(!s1.write(big));
// 'tiny' is small enough to pass through internal buffer.
t.ok(s2.write('tiny'));

// Write some small data in next IO loop, which will never be written to s3
// Because 'drain' event is not emitted from s1 and s1 is still paused
setImmediate(s1.write.bind(s1), 'later');

function indexOf (xs, x) {
for (var i = 0, l = xs.length; i < l; i++) {
if (xs[i] === x) return i;
}
return -1;
}
});
}
Loading

0 comments on commit b681059

Please sign in to comment.