Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sw precaching #76

Merged
merged 20 commits into from
Dec 2, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 5 additions & 14 deletions gulp-tasks/serve.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,12 @@
/* eslint-disable no-console, valid-jsdoc */

const gulp = require('gulp');
const path = require('path');
const express = require('express');
const serveIndex = require('serve-index');
const serveStatic = require('serve-static');
const testServer = require('../utils/test-server.js');

gulp.task('serve', (unusedCallback) => {
const app = express();
const rootDirectory = global.projectOrStar === '*' ?
'packages' :
path.join('packages', global.projectOrStar);

app.use(serveStatic(rootDirectory));
app.use(serveIndex(rootDirectory, {view: 'details'}));
app.listen(global.port, () => {
console.log(`Serving '${rootDirectory}' at ` +
`http://localhost:${global.port}/`);
return testServer.start('.', global.port)
.then((port) => {
console.log(`Primary Server http://localhost:${port}/`);
console.log(`Secondary Server http://localhost:${port + 1}/`);
});
});
230 changes: 123 additions & 107 deletions lib/idb-helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,123 +19,139 @@ import idb from 'idb';
* A wrapper to store for an IDB connection to a particular ObjectStore.
*
* @private
* @class
*/
function IDBHelper(name, version, storeName) {
if (name == undefined || version == undefined || storeName == undefined) {
throw Error('name, version, storeName must be passed to the constructor.');
class IDBHelper {
constructor(name, version, storeName) {
if (name == undefined || version == undefined || storeName == undefined) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Strict === are being used elsewhere. Is there a reason the IDB helper is preferring ==?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's my (somewhat old) code.

It's == to catch null as well as undefined, since they both would be treated the same way. Not sure how likely it is for someone to explicitly pass in null...

throw Error('name, version, storeName must be passed to the ' +
'constructor.');
}

this._name = name;
this._version = version;
this._storeName = storeName;
}

this._name = name;
this._version = version;
this._storeName = storeName;
}
/**
* Returns a promise that resolves with an open connection to IndexedDB,
* either existing or newly opened.
*
* @private
* @return {Promise<DB>}
*/
_getDb() {
if (this._dbPromise) {
return this._dbPromise;
}

/**
* Returns a promise that resolves with an open connection to IndexedDB, either
* existing or newly opened.
*
* @private
* @return {Promise<DB>}
*/
IDBHelper.prototype._getDb = function() {
if (this._db) {
return Promise.resolve(this._db);
this._dbPromise = idb.open(this._name, this._version, (upgradeDB) => {
upgradeDB.createObjectStore(this._storeName);
})
.then((db) => {
return db;
});

return this._dbPromise;
}

return idb.open(this._name, this._version, (upgradeDB) => {
upgradeDB.createObjectStore(this._storeName);
}).then((db) => {
this._db = db;
return db;
});
};
close() {
if (!this._dbPromise) {
return;
}

/**
* Wrapper on top of the idb wrapper, which simplifies saving the key/value
* pair to the object store.
* Returns a Promise that fulfills when the transaction completes.
*
* @private
* @param {String} key
* @param {Object} value
* @return {Promise<T>}
*/
IDBHelper.prototype.put = function(key, value) {
return this._getDb().then((db) => {
const tx = db.transaction(this._storeName, 'readwrite');
const objectStore = tx.objectStore(this._storeName);
objectStore.put(value, key);
return tx.complete;
});
};
return this._dbPromise
.then((db) => {
db.close();
this._dbPromise = null;
});
}

/**
* Wrapper on top of the idb wrapper, which simplifies deleting an entry
* from the object store.
* Returns a Promise that fulfills when the transaction completes.
*
* @private
* @param {String} key
* @return {Promise<T>}
*/
IDBHelper.prototype.delete = function(key) {
return this._getDb().then((db) => {
const tx = db.transaction(this._storeName, 'readwrite');
const objectStore = tx.objectStore(this._storeName);
objectStore.delete(key);
return tx.complete;
});
};
/**
* Wrapper on top of the idb wrapper, which simplifies saving the key/value
* pair to the object store.
* Returns a Promise that fulfills when the transaction completes.
*
* @private
* @param {String} key
* @param {Object} value
* @return {Promise<T>}
*/
put(key, value) {
return this._getDb().then((db) => {
const tx = db.transaction(this._storeName, 'readwrite');
const objectStore = tx.objectStore(this._storeName);
objectStore.put(value, key);
return tx.complete;
});
}

/**
* Wrapper on top of the idb wrapper, which simplifies getting a key's value
* from the object store.
* Returns a promise that fulfills with the value.
*
* @private
* @param {String} key
* @return {Promise<Object>}
*/
IDBHelper.prototype.get = function(key) {
return this._getDb().then((db) => {
return db.transaction(this._storeName)
.objectStore(this._storeName)
.get(key);
});
};
/**
* Wrapper on top of the idb wrapper, which simplifies deleting an entry
* from the object store.
* Returns a Promise that fulfills when the transaction completes.
*
* @private
* @param {String} key
* @return {Promise<T>}
*/
delete(key) {
return this._getDb().then((db) => {
const tx = db.transaction(this._storeName, 'readwrite');
const objectStore = tx.objectStore(this._storeName);
objectStore.delete(key);
return tx.complete;
});
}

/**
* Wrapper on top of the idb wrapper, which simplifies getting all the values
* in an object store.
* Returns a promise that fulfills with all the values.
*
* @private
* @return {Promise<Array<Object>>}
*/
IDBHelper.prototype.getAllValues = function() {
return this._getDb().then((db) => {
return db.transaction(this._storeName)
.objectStore(this._storeName)
.getAll();
});
};
/**
* Wrapper on top of the idb wrapper, which simplifies getting a key's value
* from the object store.
* Returns a promise that fulfills with the value.
*
* @private
* @param {String} key
* @return {Promise<Object>}
*/
get(key) {
return this._getDb().then((db) => {
return db.transaction(this._storeName)
.objectStore(this._storeName)
.get(key);
});
}

/**
* Wrapper on top of the idb wrapper, which simplifies getting all the keys
* in an object store.
* Returns a promise that fulfills with all the keys.
*
* @private
* @param {String} storeName
* @return {Promise<Array<Object>>}
*/
IDBHelper.prototype.getAllKeys = function() {
return this._getDb().then((db) => {
return db.transaction(this._storeName)
.objectStore(this._storeName)
.getAllKeys();
});
};
/**
* Wrapper on top of the idb wrapper, which simplifies getting all the values
* in an object store.
* Returns a promise that fulfills with all the values.
*
* @private
* @return {Promise<Array<Object>>}
*/
getAllValues() {
return this._getDb().then((db) => {
return db.transaction(this._storeName)
.objectStore(this._storeName)
.getAll();
});
}

/**
* Wrapper on top of the idb wrapper, which simplifies getting all the keys
* in an object store.
* Returns a promise that fulfills with all the keys.
*
* @private
* @param {String} storeName
* @return {Promise<Array<Object>>}
*/
getAllKeys() {
return this._getDb().then((db) => {
return db.transaction(this._storeName)
.objectStore(this._storeName)
.getAllKeys();
});
}
}

export default IDBHelper;
12 changes: 8 additions & 4 deletions packages/sw-appcache-behavior/test/automated-suite.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ const parseManifest = require('parse-appcache-manifest');
const path = require('path');
const promisify = require('promisify-node');
const seleniumAssistant = require('selenium-assistant');
const swTestingHelpers = require('sw-testing-helpers');
const fs = require('fs');
const testServer = require('../../../utils/test-server');

// Ensure the selenium drivers are added Node scripts path.
require('geckodriver');
Expand All @@ -37,7 +37,6 @@ require('operadriver');

const fsePromise = promisify('fs-extra');

const testServer = new swTestingHelpers.TestServer();
const expect = chai.expect;
const TIMEOUT = 10 * 1000;
const RETRIES = 3;
Expand Down Expand Up @@ -93,7 +92,7 @@ const configureTestSuite = function(browser) {

return generateInitialManifests()
.then(() => {
return testServer.startServer('.');
return testServer.start('.');
})
.then((portNumber) => {
baseTestUrl = `http://localhost:${portNumber}/packages/sw-appcache-behavior/test/`;
Expand All @@ -106,7 +105,7 @@ const configureTestSuite = function(browser) {
after(function() {
return seleniumAssistant.killWebDriver(globalDriverReference)
.then(() => {
return testServer.killServer();
return testServer.stop();
})
.then(() => {
return fsePromise.remove(tempDirectory);
Expand Down Expand Up @@ -285,6 +284,11 @@ seleniumAssistant.getAvailableBrowsers().forEach(function(browser) {
case 'chrome':
case 'firefox':
case 'opera':
if (browser.getSeleniumBrowserId() === 'opera' &&
browser.getVersionNumber() <= 43) {
console.log(`Skipping Opera <= 43 due to driver issues.`);
return;
}
configureTestSuite(browser);
break;
default:
Expand Down
6 changes: 3 additions & 3 deletions packages/sw-lib/test/automated-test-suite.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

const seleniumAssistant = require('selenium-assistant');
const swTestingHelpers = require('sw-testing-helpers');
const testServer = new swTestingHelpers.TestServer();
const testServer = require('../../../utils/test-server.js');

require('chromedriver');
require('operadriver');
Expand All @@ -34,14 +34,14 @@ const setupTestSuite = (assistantDriver) => {

// Set up the web server before running any tests in this suite.
before(function() {
return testServer.startServer('.').then((portNumber) => {
return testServer.start('.').then((portNumber) => {
baseTestUrl = `http://localhost:${portNumber}/packages/sw-lib`;
});
});

// Kill the web server once all tests are complete.
after(function() {
return testServer.killServer();
return testServer.stop();
});

afterEach(function() {
Expand Down
2 changes: 2 additions & 0 deletions packages/sw-lib/test/browser-unit/library-namespace.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ describe('Test Behaviors of Loading the Script', function() {
this.timeout(5 * 60 * 1000);

it('should print an error when added to the window.', function() {
this.timeout(2000);

return new Promise((resolve, reject) => {
window.onerror = (msg, url, lineNo, columnNo, error) => {
window.onerror = null;
Expand Down
8 changes: 0 additions & 8 deletions packages/sw-lib/test/utils/dev-server.js

This file was deleted.

Loading