Skip to content

Commit

Permalink
(#4402) - fix Firefox FileReader in a WW
Browse files Browse the repository at this point in the history
This also re-enables the web worker tests for Firefox. Web worker
tests should only be running in Chrome and Firefox now.
  • Loading branch information
nolanlawson authored and daleharvey committed Oct 6, 2015
1 parent 87c60b6 commit 2457a2b
Show file tree
Hide file tree
Showing 7 changed files with 134 additions and 130 deletions.
3 changes: 2 additions & 1 deletion .jshintrc
Expand Up @@ -38,6 +38,7 @@
"IDBKeyRange",
"openDatabase",
"sqlitePlugin",
"chrome"
"chrome",
"FileReaderSync"
]
}
23 changes: 11 additions & 12 deletions .travis.yml
Expand Up @@ -17,6 +17,7 @@ git:
# - /tmp/phantomjs

addons:
firefox: "41.0.1"
apt:
sources:
- ubuntu-toolchain-r-test
Expand Down Expand Up @@ -58,29 +59,27 @@ env:

# Test against pouchdb-server
- CLIENT=node SERVER=pouchdb-server COMMAND=test
- CLIENT=selenium:firefox SERVER=pouchdb-server COMMAND=test
- CLIENT=selenium:firefox:41.0.1 SERVER=pouchdb-server COMMAND=test
- SERVER_ADAPTER=memdown LEVEL_ADAPTER=memdown SERVER=pouchdb-server COMMAND=test

# Test against pouchdb-express-router
- CLIENT=node SERVER=pouchdb-express-router COMMAND=test

# Test in firefox/phantomjs running on travis
- CLIENT=selenium:firefox COMMAND=test
- CLIENT=selenium:firefox:41.0.1 COMMAND=test
- CLIENT=selenium:phantomjs ES5_SHIM=true COMMAND=test

# Test auto-compaction in Node, Phantom, and Firefox
- AUTO_COMPACTION=true CLIENT=node COMMAND=test
- AUTO_COMPACTION=true CLIENT=selenium:firefox COMMAND=test
- AUTO_COMPACTION=true CLIENT=selenium:firefox:41.0.1 COMMAND=test
- AUTO_COMPACTION=true CLIENT=selenium:phantomjs ES5_SHIM=true COMMAND=test

# Test map/reduce
- TYPE=mapreduce CLIENT=node COMMAND=test
- TYPE=mapreduce CLIENT=selenium:firefox COMMAND=test
- TYPE=mapreduce CLIENT=selenium:firefox:41.0.1 COMMAND=test
- TYPE=mapreduce CLIENT=selenium:phantomjs ES5_SHIM=true COMMAND=test

# Testing in saucelabs
- CLIENT=saucelabs:chrome:36 COMMAND=test
- CLIENT=saucelabs:chrome:37 COMMAND=test
- CLIENT=saucelabs:chrome COMMAND=test
- CLIENT=saucelabs:safari:6 COMMAND=test
- CLIENT="saucelabs:internet explorer:10:Windows 8" COMMAND=test
Expand All @@ -93,18 +92,18 @@ env:
- GREP=suite2 CLIENT="saucelabs:Android:5.1:Linux" COMMAND=test
- GREP=suite2 INVERT=true CLIENT="saucelabs:Android:5.1:Linux" COMMAND=test

- CLIENT=selenium:firefox ADAPTERS=memory COMMAND=test
- CLIENT=selenium:firefox ADAPTERS=localstorage COMMAND=test
- CLIENT=selenium:firefox:41.0.1 ADAPTERS=memory COMMAND=test
- CLIENT=selenium:firefox:41.0.1 ADAPTERS=localstorage COMMAND=test

# Test CouchDB master (aka bigcouch branch)
- CLIENT=node SERVER=couchdb-master COMMAND=test
- SKIP_MIGRATION=true CLIENT=selenium:firefox SERVER=couchdb-master COMMAND=test
- SKIP_MIGRATION=true CLIENT=selenium:firefox:41.0.1 SERVER=couchdb-master COMMAND=test

# Test Couchbase Sync Gateway
- GREP=test.replication.js CLIENT=node SERVER=sync-gateway BAIL=0 COMMAND=test

# Performance tests
- CLIENT=selenium:firefox PERF=1 COMMAND=test
- CLIENT=selenium:firefox:41.0.1 PERF=1 COMMAND=test
- PERF=1 COMMAND=test

- COMMAND=test-unit
Expand All @@ -121,12 +120,12 @@ matrix:

# Allowed failures
- env: CLIENT=node SERVER=couchdb-master COMMAND=test
- env: SKIP_MIGRATION=true CLIENT=selenium:firefox SERVER=couchdb-master COMMAND=test
- env: SKIP_MIGRATION=true CLIENT=selenium:firefox:41.0.1 SERVER=couchdb-master COMMAND=test
- env: CLIENT=node SERVER=pouchdb-express-router COMMAND=test
- node_js: "iojs"
env: CLIENT=node COMMAND=test
- env: CLIENT=node SERVER=pouchdb-server COMMAND=test
- env: CLIENT=selenium:firefox SERVER=pouchdb-server COMMAND=test
- env: CLIENT=selenium:firefox:41.0.1 SERVER=pouchdb-server COMMAND=test
- env: SERVER_ADAPTER=memdown LEVEL_ADAPTER=memdown SERVER=pouchdb-server COMMAND=test
- env: COMMAND=report-coverage

Expand Down
2 changes: 1 addition & 1 deletion bin/test-browser.js
Expand Up @@ -16,7 +16,7 @@ var testTimeout = 30 * 60 * 1000;
var username = process.env.SAUCE_USERNAME;
var accessKey = process.env.SAUCE_ACCESS_KEY;

var SELENIUM_VERSION = process.env.SELENIUM_VERSION || '2.46.0';
var SELENIUM_VERSION = process.env.SELENIUM_VERSION || '2.45.0';

// BAIL=0 to disable bailing
var bail = process.env.BAIL !== '0';
Expand Down
6 changes: 6 additions & 0 deletions lib/deps/binary/readAsArrayBuffer.js
Expand Up @@ -2,6 +2,12 @@

// simplified API. universal browser support is assumed
module.exports = function (blob, callback) {
if (typeof FileReader === 'undefined') {
// fix for Firefox in a web worker:
// https://bugzilla.mozilla.org/show_bug.cgi?id=901097
return callback(new FileReaderSync().readAsArrayBuffer(blob));
}

var reader = new FileReader();
reader.onloadend = function (e) {
var result = e.target.result || new ArrayBuffer(0);
Expand Down
7 changes: 7 additions & 0 deletions lib/deps/binary/readAsBinaryString.js
Expand Up @@ -4,6 +4,13 @@ var arrayBufferToBinaryString = require('./arrayBufferToBinaryString');

// shim for browsers that don't support it
module.exports = function (blob, callback) {
if (typeof FileReader === 'undefined') {
// fix for Firefox in a web worker
// https://bugzilla.mozilla.org/show_bug.cgi?id=901097
return callback(arrayBufferToBinaryString(
new FileReaderSync().readAsArrayBuffer(blob)));
}

var reader = new FileReader();
var hasBinaryString = typeof reader.readAsBinaryString === 'function';
reader.onloadend = function (e) {
Expand Down
120 changes: 54 additions & 66 deletions tests/integration/browser.worker.js
Expand Up @@ -8,12 +8,38 @@ if (!sourceFile) {
sourceFile = '../../dist/' + sourceFile[1];
}

if (typeof window.Worker === 'function' && window.chrome) {
// only running in Chrome and Firefox due to various bugs.
// IE: https://connect.microsoft.com/IE/feedback/details/866495
// Safari: doesn't have IndexedDB or WebSQL in a WW
// NodeWebkit: not sure what the issue is

var isNodeWebkit = typeof window !== 'undefined' &&
typeof process !== 'undefined';

if (typeof window.Worker === 'function' &&
!isNodeWebkit &&
(window.chrome || /Firefox/.test(navigator.userAgent))) {
runTests();
}

function runTests() {

function workerPromise(message) {
return new Promise(function (resolve, reject) {
var worker = new Worker('worker.js');
worker.addEventListener('error', function (e) {
worker.terminate();
reject(new Error(e.message + ": " + e.filename + ': ' + e.lineno));
});
worker.addEventListener('message', function (e) {
worker.terminate();
resolve(e.data);
});
worker.postMessage(['source', sourceFile]);
worker.postMessage(message);
});
}

describe('browser.worker.js', function () {

var dbs = {};
Expand All @@ -28,82 +54,44 @@ function runTests() {
testUtils.cleanup([dbs.name, dbs.remote], done);
});

it('add doc with blob attachemnt', function (done) {
var worker = new Worker('worker.js');
worker.addEventListener('error', function (e) {
throw e;
it('create it', function () {
return workerPromise('ping').then(function (data) {
data.should.equal('pong');
});
worker.addEventListener('message', function (e) {
e.data.title.should.equal('lalaa');
worker.terminate();
done();
});

it('check pouch version', function () {
return workerPromise('version').then(function (data) {
PouchDB.version.should.equal(data);
});
worker.postMessage(sourceFile);
worker.postMessage(['allDocs', 'testdb']);
});

it('create it', function (done) {
var worker = new Worker('worker.js');
worker.addEventListener('message', function (e) {
e.data.should.equal('pong');
worker.terminate();
done();
it('create remote db', function () {
return workerPromise(['create', dbs.remote]).then(function (data) {
data.should.equal('lala');
});
worker.postMessage(sourceFile);
worker.postMessage('ping');
});

it('check pouch version', function (done) {
var worker = new Worker('worker.js');
worker.addEventListener('message', function (e) {
PouchDB.version.should.equal(e.data);
worker.terminate();
done();
it('create local db', function () {
return workerPromise(['create', dbs.name]).then(function (data) {
data.should.equal('lala');
});
worker.postMessage(sourceFile);
worker.postMessage('version');
});

var isNodeWebkit = typeof window !== 'undefined' &&
typeof process !== 'undefined';

// does not work in NodeWebkit
if (!isNodeWebkit) {
it('create remote db', function (done) {
var worker = new Worker('worker.js');
worker.addEventListener('error', function (e) {
throw e;
});
worker.addEventListener('message', function (e) {
e.data.should.equal('lala');
worker.terminate();
done();
});
worker.postMessage(sourceFile);
worker.postMessage(['create', dbs.remote]);
it('add doc with blob attachment', function () {
return workerPromise(['allDocs', dbs.name]).then(function (data) {
data.title.should.equal('lalaa');
});
}


// Mozilla bug: https://bugzilla.mozilla.org/show_bug.cgi?id=701634
// IE bug: https://connect.microsoft.com/IE/feedback/details/866495
// NodeWebkit bug... who knows
if (!('mozIndexedDB' in window) &&
!('msIndexedDB' in window) &&
!isNodeWebkit) {
it('create local db', function (done) {
var worker = new Worker('worker.js');
worker.addEventListener('error', function (e) {
throw e;
});
worker.addEventListener('message', function (e) {
e.data.should.equal('lala');
worker.terminate();
done();
});
worker.postMessage(sourceFile);
worker.postMessage(['create', dbs.name]);
});

it('put an attachment', function () {
var blob = new Blob(['foobar'], {type: 'text/plain'});
var message = ['putAttachment', dbs.name, 'doc', 'att.txt', blob,
'text/plain'];
return workerPromise(message).then(function (blob) {
blob.type.should.equal('text/plain');
blob.size.should.equal(6);
});
}
});
});
}
103 changes: 53 additions & 50 deletions tests/integration/worker.js
@@ -1,69 +1,72 @@
/* jshint worker: true */
'use strict';

function onError(err) {
setTimeout(function () {
throw err; // can catch this in the worker's 'error' listener
}, 0);
}

function bigTest(name) {
new PouchDB(name, function (err, db) {
if (err) {
throw err;
}
db.post({
_id: 'blablah',
key: 'lala'
}, function (err) {
if (err) {
throw err;
}
db.get('blablah', function (err, doc) {
if (err) {
throw err;
}
self.postMessage(doc.key);
db.destroy();
});
var db = new PouchDB(name);
db.post({
_id: 'blablah',
key: 'lala'
}).then(function () {
return db.get('blablah');
}).then(function (doc) {
return db.destroy().then(function () {
self.postMessage(doc.key);
});
});
}).catch(onError);
}

function allDocs(name) {
new PouchDB(name, function (err, db) {
if (err) {
throw err;
}
db.post({
_id: 'blah',
title: 'lalaa',
_attachments: {
'test': {
data: new Blob(),
content_type: ''
}
var db = new PouchDB(name);
db.post({
_id: 'blah',
title: 'lalaa',
_attachments: {
'test': {
data: new Blob(),
content_type: ''
}
}, function(err, doc) {
db.get(doc.id, function (err, doc) {
if (err) {
throw err;
}
self.postMessage(doc);
db.destroy();
});
}
}).then(function () {
return db.get('blah');
}).then(function (doc) {
return db.destroy().then(function () {
self.postMessage(doc);
});
}).catch(onError);
}

function putAttachment(name, docId, attId, att, type) {
var db = new PouchDB(name);
db.putAttachment(docId, attId, att, type).then(function () {
return db.getAttachment(docId, attId);
}).then(function (fetchedAtt) {
return db.destroy().then(function () {
self.postMessage(fetchedAtt);
});
});
}).catch(onError);
}

self.addEventListener('message', function (e) {
if (typeof e.data === 'string' && e.data.indexOf('/dist/') > -1) {
importScripts(e.data);
}
if (e.data === 'ping') {
if (Array.isArray(e.data) && e.data[0] === 'source') {
importScripts(e.data[1]);
} else if (e.data === 'ping') {
self.postMessage('pong');
}
if (e.data === 'version') {
} else if (e.data === 'version') {
self.postMessage(PouchDB.version);
}
if (Array.isArray(e.data) && e.data[0] === 'create') {
} else if (Array.isArray(e.data) && e.data[0] === 'create') {
bigTest(e.data[1]);
}
if (Array.isArray(e.data) && e.data[0] === 'allDocs') {
} else if (Array.isArray(e.data) && e.data[0] === 'allDocs') {
allDocs(e.data[1]);
} else if (Array.isArray(e.data) && e.data[0] === 'putAttachment') {
putAttachment(e.data[1], e.data[2], e.data[3], e.data[4], e.data[5]);
} else {
onError(new Error('unknown message: ' + JSON.stringify(e.data)));
}

});

0 comments on commit 2457a2b

Please sign in to comment.