From d6a2e48c488b9d35edcf732e269cb471e12b919d Mon Sep 17 00:00:00 2001 From: Francisco Baio Dias Date: Thu, 21 Jan 2016 21:57:18 +0100 Subject: [PATCH] Run tests in the browser --- .travis.yml | 4 + karma.conf.js | 73 +++++++++++++ package.json | 20 +++- src/index.js | 24 +---- tests/browser-tests.js | 55 ++++++++++ tests/node-tests.js | 42 ++++++++ tests/repo-test.js | 237 ++++++++++++++++++----------------------- 7 files changed, 298 insertions(+), 157 deletions(-) create mode 100644 karma.conf.js create mode 100644 tests/browser-tests.js create mode 100644 tests/node-tests.js diff --git a/.travis.yml b/.travis.yml index c215b403..59456ac8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,3 +12,7 @@ before_install: # Workaround for a permissions issue with Travis virtual machine images script: - npm test + +before_script: + - export DISPLAY=:99.0 + - sh -e /etc/init.d/xvfb start diff --git a/karma.conf.js b/karma.conf.js new file mode 100644 index 00000000..4d3a7a5f --- /dev/null +++ b/karma.conf.js @@ -0,0 +1,73 @@ +module.exports = function (config) { + config.set({ + + // base path, that will be used to resolve files and exclude + basePath: '', + + // frameworks to use + frameworks: ['mocha'], + + // list of files / patterns to load in the browser + files: [ + 'tests/browser-tests.js' + ], + + // list of preprocessors + preprocessors: { + 'tests/*': ['webpack'] + }, + + webpack: { + resolve: { + extensions: ['', '.js'] + }, + externals: { + fs: '{}' + }, + node: { + Buffer: true + } + }, + + webpackMiddleware: { + noInfo: true, + stats: { + colors: true + } + }, + + // test results reporter to use + // possible values: 'dots', 'progress', 'junit', 'growl', 'coverage' + reporters: ['spec'], + + // web server port + port: 9876, + + // enable / disable colors in the output (reporters and logs) + colors: true, + + // level of logging + // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG + logLevel: config.LOG_INFO, + + // enable / disable watching file and executing tests whenever any file changes + autoWatch: false, + + // Start these browsers, currently available: + // - Chrome + // - ChromeCanary + // - Firefox + // - Opera (has to be installed with `npm install karma-opera-launcher`) + // - Safari (only Mac; has to be installed with `npm install karma-safari-launcher`) + // - PhantomJS + // - IE (only Windows; has to be installed with `npm install karma-ie-launcher`) + browsers: process.env.TRAVIS ? ['Firefox'] : ['Chrome'], + + // If browser does not capture in given timeout [ms], kill it + captureTimeout: 60000, + + // Continuous Integration mode + // if true, it capture browsers, run tests and exit + singleRun: true + }) +} diff --git a/package.json b/package.json index 6fb46fbc..741f1f7f 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,9 @@ "description": "IPFS Repo implementation", "main": "src/index.js", "scripts": { - "test": "mocha tests/*-test.js", + "test": "npm run test:node && npm run test:browser", + "test:node": "mocha tests/node-tests.js", + "test:browser": "karma start karma.conf.js", "coverage": "istanbul cover --print both -- _mocha tests/*-test.js", "lint": "standard" }, @@ -21,20 +23,32 @@ ], "homepage": "https://github.com/ipfs/js-ipfs-repo", "devDependencies": { + "async": "^1.5.2", "bl": "^1.0.0", "bs58": "^3.0.0", "chai": "^3.4.1", + "fs-blob-store": "^5.2.1", "istanbul": "^0.4.1", + "karma": "^0.13.19", + "karma-chrome-launcher": "^0.2.2", + "karma-cli": "^0.1.2", + "karma-firefox-launcher": "^0.1.7", + "karma-mocha": "^0.2.1", + "karma-spec-reporter": "0.0.23", + "karma-webpack": "^1.7.0", + "local-storage-blob-store": "0.0.2", + "lodash": "^4.0.0", "mocha": "^2.3.4", "ncp": "^2.0.0", "pre-commit": "^1.1.1", + "raw-loader": "^0.5.1", "rimraf": "^2.4.4", - "standard": "^5.1.1" + "standard": "^5.1.1", + "webpack": "^1.12.11" }, "dependencies": { "bl": "^1.0.0", "concat-stream": "^1.5.1", - "fs-blob-store": "^5.2.0", "level-js": "^2.2.2", "lockfile": "^1.0.1", "multihashes": "^0.2.0", diff --git a/src/index.js b/src/index.js index d41bf6eb..3f7e9da7 100644 --- a/src/index.js +++ b/src/index.js @@ -1,35 +1,17 @@ const stores = require('./stores') -const extend = require('xtend') -const fs = require('fs-blob-store') exports = module.exports = Repo function Repo (repoPath, options) { - const base = { - stores: { - keys: fs, - config: fs, - datastore: fs, - // datastoreLegacy: needs https://github.com/ipfs/js-ipfs-repo/issues/6#issuecomment-164650642 - logs: fs, - locks: fs, - version: fs - } - } - - options = extend(base, options) - this.init = (config, callback) => { if (this.exists()) { throw new Error('Repo already exists') } - - // TODO - // 1. load remaining stores - // 2. init all of them } - this.locks = require('./stores').locks.setUp(repoPath, options.stores.locks) + this.locks = stores + .locks + .setUp(repoPath, options.stores.locks) this.exists = callback => { this.version.get((err, version) => { diff --git a/tests/browser-tests.js b/tests/browser-tests.js new file mode 100644 index 00000000..815f1588 --- /dev/null +++ b/tests/browser-tests.js @@ -0,0 +1,55 @@ +/* globals describe, before */ + +// const expect = require('chai').expect +const async = require('async') +const store = require('local-storage-blob-store') +const tests = require('./repo-test') +const _ = require('lodash') +const IPFSRepo = require('../src') + +var repoContext = require.context('raw!./test-repo', true) + +describe('IPFS Repo Testson on the Browser', function () { + before(function (done) { + window.localStorage.clear() + + var repoData = [] + repoContext.keys().forEach(function (key) { + repoData.push({ + key: key.replace('./', ''), + value: repoContext(key) + }) + }) + + var mainBlob = store('ipfs') + var blocksBlob = store('ipfs/') + + async.eachSeries(repoData, (file, cb) => { + if (_.startsWith(file.key, 'datastore/')) { + return cb() + } + + const blob = _.startsWith(file.key, 'blocks/') + ? blocksBlob + : mainBlob + + blob.createWriteStream({ + key: file.key + }).end(file.value, cb) + }, done) + }) + + const options = { + stores: { + keys: store, + config: store, + datastore: store, + // datastoreLegacy: needs https://github.com/ipfs/js-ipfs-repo/issues/6#issuecomment-164650642 + logs: store, + locks: store, + version: store + } + } + const repo = new IPFSRepo('ipfs', options) + tests(repo) +}) diff --git a/tests/node-tests.js b/tests/node-tests.js new file mode 100644 index 00000000..e3bd9855 --- /dev/null +++ b/tests/node-tests.js @@ -0,0 +1,42 @@ +/* globals describe, before, after */ + +const expect = require('chai').expect +const ncp = require('ncp').ncp +const rimraf = require('rimraf') + +const IPFSRepo = require('../src') + +describe('IPFS Repo Testson on Node.js', () => { + const testRepoPath = __dirname + '/test-repo' + const date = Date.now().toString() + const repoPath = testRepoPath + date + + before(done => { + ncp(testRepoPath, repoPath, err => { + expect(err).to.not.exist + done() + }) + }) + + after(done => { + rimraf(repoPath, err => { + expect(err).to.not.exist + done() + }) + }) + + const fs = require('fs-blob-store') + const options = { + stores: { + keys: fs, + config: fs, + datastore: fs, + // datastoreLegacy: needs https://github.com/ipfs/js-ipfs-repo/issues/6#issuecomment-164650642 + logs: fs, + locks: fs, + version: fs + } + } + const repo = new IPFSRepo(repoPath, options) + require('./repo-test')(repo) +}) diff --git a/tests/repo-test.js b/tests/repo-test.js index 015ca94a..de89f8a2 100644 --- a/tests/repo-test.js +++ b/tests/repo-test.js @@ -1,69 +1,28 @@ -/* globals describe, before, after, it*/ +/* globals describe, it*/ const expect = require('chai').expect -const ncp = require('ncp').ncp -const rimraf = require('rimraf') const base58 = require('bs58') const bl = require('bl') const fs = require('fs') -const IPFSRepo = require('./../src') +const isNode = !global.window -describe('IPFS Repo Tests', () => { - var repo - const testRepoPath = __dirname + '/test-repo' - const date = Date.now().toString() - const repoPath = testRepoPath + date +const fileA = isNode + ? fs.readFileSync(process.cwd() + '/tests/test-repo/blocks/12207028/122070286b9afa6620a66f715c7020d68af3d10e1a497971629c07606bfdb812303d.data') + : new Buffer(require('raw!./test-repo/blocks/12207028/122070286b9afa6620a66f715c7020d68af3d10e1a497971629c07606bfdb812303d.data')) - before(done => { - ncp(testRepoPath, repoPath, err => { - expect(err).to.not.exist - done() - }) - }) - - after(done => { - rimraf(repoPath, err => { - expect(err).to.not.exist - done() - }) - }) - - it('check if Repo exists', done => { - repo = new IPFSRepo(repoPath) - repo.exists((err, exists) => { - expect(err).to.not.exist - expect(exists).to.equal(true) - done() - }) - }) - - it.skip('init another Repo', done => { - const tmpRepoPath = __dirname + '/tmp-repo' - const tmpRepo = new IPFSRepo(tmpRepoPath) - tmpRepo.init({ ID: 'ID' }, err => { - expect(err).to.not.exist - rimraf(tmpRepoPath, err => { +module.exports = function (repo) { + describe('IPFS Repo Tests', () => { + it('check if Repo exists', done => { + repo.exists((err, exists) => { expect(err).to.not.exist + expect(exists).to.equal(true) done() }) }) - }) - - describe('locks', () => { - it('lock, unlock', done => { - repo.locks.lock(err => { - expect(err).to.not.exist - repo.locks.unlock(err => { - expect(err).to.not.exist - done() - }) - }) - }) - it('lock, lock', done => { - repo.locks.lock(err => { - expect(err).to.not.exist + describe('locks', () => { + it('lock, unlock', done => { repo.locks.lock(err => { expect(err).to.not.exist repo.locks.unlock(err => { @@ -71,127 +30,139 @@ describe('IPFS Repo Tests', () => { done() }) }) + }) - setTimeout(() => { - repo.locks.unlock(err => { + it('lock, lock', done => { + repo.locks.lock(err => { + expect(err).to.not.exist + repo.locks.lock(err => { expect(err).to.not.exist + repo.locks.unlock(err => { + expect(err).to.not.exist + done() + }) }) - }, 500) - }) - }) - }) - describe('keys', () => { - it('get PrivKey', done => { - repo.keys.get((err, privKey) => { - expect(err).to.not.exist - expect(privKey).to.be.a('string') - done() + setTimeout(() => { + repo.locks.unlock(err => { + expect(err).to.not.exist + }) + }, 500) + }) }) }) - }) - describe('config', () => { - it('get config', done => { - repo.config.get((err, config) => { - expect(err).to.not.exist - expect(config).to.be.a('object') - done() + describe('keys', () => { + it('get PrivKey', done => { + repo.keys.get((err, privKey) => { + expect(err).to.not.exist + expect(privKey).to.be.a('string') + done() + }) }) }) - it('set config', done => { - repo.config.set({a: 'b'}, err => { - expect(err).to.not.exist + describe('config', () => { + it('get config', done => { repo.config.get((err, config) => { expect(err).to.not.exist - expect(config).to.deep.equal({a: 'b'}) + expect(config).to.be.a('object') done() }) }) - }) - }) - describe('version', () => { - it('get version', done => { - repo.version.get((err, version) => { - expect(err).to.not.exist - expect(version).to.be.a('string') - expect(Number(version)).to.be.a('number') - done() + it('set config', done => { + repo.config.set({a: 'b'}, err => { + expect(err).to.not.exist + repo.config.get((err, config) => { + expect(err).to.not.exist + expect(config).to.deep.equal({a: 'b'}) + done() + }) + }) }) }) - it('set version', done => { - repo.version.set('9000', err => { - expect(err).to.not.exist + describe('version', () => { + it('get version', done => { repo.version.get((err, version) => { expect(err).to.not.exist - expect(version).to.equal('9000') + expect(version).to.be.a('string') + expect(Number(version)).to.be.a('number') done() }) }) - }) - }) - - describe('datastore', () => { - const baseFileHash = 'QmVtU7ths96fMgZ8YSZAbKghyieq7AjxNdcqyVzxTt3qVe' - it('reads block', done => { - const buf = new Buffer(base58.decode(baseFileHash)) - repo.datastore.createReadStream(buf) - .pipe(bl((err, data) => { + it('set version', done => { + repo.version.set('9000', err => { expect(err).to.not.exist - const eq = fs.readFileSync(process.cwd() + '/tests/test-repo/blocks/12207028/122070286b9afa6620a66f715c7020d68af3d10e1a497971629c07606bfdb812303d.data').equals(data) - expect(eq).to.equal(true) - done() - })) + repo.version.get((err, version) => { + expect(err).to.not.exist + expect(version).to.equal('9000') + done() + }) + }) + }) }) - it('write a block', done => { - const rnd = 'QmVtU7ths96fMgZ8YSZAbKghyieq7AjxNdcqyVtesthash' - const mh = new Buffer(base58.decode(rnd)) - const data = new Buffer('Oh the data') + describe('datastore', () => { + const baseFileHash = 'QmVtU7ths96fMgZ8YSZAbKghyieq7AjxNdcqyVzxTt3qVe' - repo.datastore.createWriteStream(mh, (err, metadata) => { - expect(err).to.not.exist - expect(metadata.key).to.equal('12207028/122070286b9afa6620a66f715c7020d68af3d10e1a497971629c07605f55537ce990.data') - done() - }).end(data) - }) + it('reads block', done => { + const buf = new Buffer(base58.decode(baseFileHash)) + repo.datastore.createReadStream(buf) + .pipe(bl((err, data) => { + expect(err).to.not.exist + expect(data.equals(fileA)).to.equal(true) + done() + })) + }) - it('block exists', done => { - const buf = new Buffer(base58.decode(baseFileHash)) + it('write a block', done => { + const rnd = 'QmVtU7ths96fMgZ8YSZAbKghyieq7AjxNdcqyVtesthash' + const mh = new Buffer(base58.decode(rnd)) + const data = new Buffer('Oh the data') - repo.datastore.exists(buf, (err, exists) => { - expect(err).to.not.exist - expect(exists).to.equal(true) - done() + repo.datastore.createWriteStream(mh, (err, metadata) => { + expect(err).to.not.exist + expect(metadata.key).to.equal('12207028/122070286b9afa6620a66f715c7020d68af3d10e1a497971629c07605f55537ce990.data') + done() + }).end(data) }) - }) - it('check for non existent block', done => { - const buf = new Buffer('random buffer') + it('block exists', done => { + const buf = new Buffer(base58.decode(baseFileHash)) - repo.datastore.exists(buf, (err, exists) => { - expect(err).to.not.exist - expect(exists).to.equal(false) - done() + repo.datastore.exists(buf, (err, exists) => { + expect(err).to.not.exist + expect(exists).to.equal(true) + done() + }) }) - }) - it('remove a block', done => { - const buf = new Buffer(base58.decode(baseFileHash)) - repo.datastore.remove(buf, (err) => { - expect(err).to.not.exist + it('check for non existent block', done => { + const buf = new Buffer('random buffer') + repo.datastore.exists(buf, (err, exists) => { expect(err).to.not.exist expect(exists).to.equal(false) done() }) }) + + it('remove a block', done => { + const buf = new Buffer(base58.decode(baseFileHash)) + repo.datastore.remove(buf, (err) => { + expect(err).to.not.exist + repo.datastore.exists(buf, (err, exists) => { + expect(err).to.not.exist + expect(exists).to.equal(false) + done() + }) + }) + }) }) - }) - describe('datastore-legacy', () => {}) -}) + describe('datastore-legacy', () => {}) + }) +}