chore(xo-collection): use jest instead of mocha/must/sinon

This commit is contained in:
Julien Fontanet 2017-01-11 16:22:04 +01:00
parent 5eb7119821
commit dc1bb8992f
7 changed files with 1047 additions and 282 deletions

View File

@ -1,3 +0,0 @@
try { require('clarify') } catch (_) {}
try { require('trace') } catch (_) {}
try { require('source-map-support/register') } catch (_) {}

View File

@ -1 +0,0 @@
--require ./.mocha.js

View File

@ -37,30 +37,25 @@
"babel-plugin-transform-runtime": "^6.15.0", "babel-plugin-transform-runtime": "^6.15.0",
"babel-preset-latest": "^6.16.0", "babel-preset-latest": "^6.16.0",
"babel-preset-stage-0": "^6.16.0", "babel-preset-stage-0": "^6.16.0",
"clarify": "^2.0.0",
"cross-env": "^3.1.3", "cross-env": "^3.1.3",
"dependency-check": "^2.6.0", "dependency-check": "^2.6.0",
"event-to-promise": "^0.7.0", "event-to-promise": "^0.7.0",
"mocha": "^3.1.2", "jest": "^18.1.0",
"must": "^0.13.2",
"rimraf": "^2.4.3", "rimraf": "^2.4.3",
"sinon": "^1.14.1", "standard": "^8.5.0"
"source-map-support": "^0.4.6",
"standard": "^8.5.0",
"trace": "^2.3.3"
}, },
"scripts": { "scripts": {
"build": "cross-env NODE_ENV=production babel --source-maps --out-dir=dist/ src/", "build": "cross-env NODE_ENV=production babel --source-maps --out-dir=dist/ src/",
"clean": "rimraf dist/", "clean": "rimraf dist/",
"depcheck": "dependency-check ./package.json --entry dist/collection.js index.js unique-index.js view.js", "depcheck": "dependency-check ./package.json --entry dist/collection.js index.js unique-index.js view.js",
"dev-test": "jest --bail --watch",
"dev": "cross-env NODE_ENV=development babel --watch --source-maps --out-dir=dist/ src/", "dev": "cross-env NODE_ENV=development babel --watch --source-maps --out-dir=dist/ src/",
"lint": "standard", "lint": "standard",
"posttest": "npm run lint && npm run depcheck", "posttest": "npm run lint && npm run depcheck",
"prebuild": "npm run clean", "prebuild": "npm run clean",
"predev": "npm run clean", "predev": "npm run clean",
"prepublish": "npm run build", "prepublish": "npm run build",
"test": "npm run lint && mocha --opts .mocha.opts \"dist/**/*.spec.js\"", "test": "jest"
"test-dev": "mocha --opts .mocha.opts --watch --reporter=min \"dist/**/*.spec.js\""
}, },
"babel": { "babel": {
"plugins": [ "plugins": [
@ -72,6 +67,12 @@
"stage-0" "stage-0"
] ]
}, },
"jest": {
"testPathDirs": [
"<rootDir>/src"
],
"testRegex": "\\.spec\\.js$"
},
"standard": { "standard": {
"ignore": [ "ignore": [
"dist" "dist"

View File

@ -1,17 +1,13 @@
/* eslint-env mocha */ /* eslint-env jest */
import eventToPromise from 'event-to-promise' import eventToPromise from 'event-to-promise'
import expect from 'must'
import sinon from 'sinon'
import { forEach } from 'lodash' import { forEach } from 'lodash'
// ===================================================================
import Collection, {DuplicateItem, NoSuchItem} from '..' import Collection, {DuplicateItem, NoSuchItem} from '..'
// =================================================================== // ===================================================================
function waitTicks (n = 1) { function waitTicks (n = 2) {
const {nextTick} = process const {nextTick} = process
return new Promise(function (resolve) { return new Promise(function (resolve) {
@ -37,16 +33,16 @@ describe('Collection', function () {
it('is iterable', function () { it('is iterable', function () {
const iterator = this.col[Symbol.iterator]() const iterator = this.col[Symbol.iterator]()
expect(iterator.next()).to.eql({done: false, value: ['bar', 0]}) expect(iterator.next()).toEqual({done: false, value: ['bar', 0]})
expect(iterator.next()).to.eql({done: true, value: undefined}) expect(iterator.next()).toEqual({done: true, value: undefined})
}) })
describe('#keys()', function () { describe('#keys()', function () {
it('returns an iterator over the keys', function () { it('returns an iterator over the keys', function () {
const iterator = this.col.keys() const iterator = this.col.keys()
expect(iterator.next()).to.eql({done: false, value: 'bar'}) expect(iterator.next()).toEqual({done: false, value: 'bar'})
expect(iterator.next()).to.eql({done: true, value: undefined}) expect(iterator.next()).toEqual({done: true, value: undefined})
}) })
}) })
@ -54,32 +50,32 @@ describe('Collection', function () {
it('returns an iterator over the values', function () { it('returns an iterator over the values', function () {
const iterator = this.col.values() const iterator = this.col.values()
expect(iterator.next()).to.eql({done: false, value: 0}) expect(iterator.next()).toEqual({done: false, value: 0})
expect(iterator.next()).to.eql({done: true, value: undefined}) expect(iterator.next()).toEqual({done: true, value: undefined})
}) })
}) })
describe('#add()', function () { describe('#add()', function () {
it('adds item to the collection', function () { it('adds item to the collection', function () {
const spy = sinon.spy() const spy = jest.fn()
this.col.on('add', spy) this.col.on('add', spy)
this.col.add('foo', true) this.col.add('foo', true)
expect(this.col.get('foo')).to.be.true() expect(this.col.get('foo')).toBe(true)
// No sync events. // No sync events.
sinon.assert.notCalled(spy) expect(spy).not.toHaveBeenCalled()
// Async event. // Async event.
return eventToPromise(this.col, 'add').then(function (added) { return eventToPromise(this.col, 'add').then(function (added) {
expect(added).to.have.keys(['foo']) expect(Object.keys(added)).toEqual([ 'foo' ])
expect(added.foo).to.be.true() expect(added.foo).toBe(true)
}) })
}) })
it('throws an exception if the item already exists', function () { it('throws an exception if the item already exists', function () {
expect(() => this.col.add('bar', true)).to.throw(DuplicateItem) expect(() => this.col.add('bar', true)).toThrowError(DuplicateItem)
}) })
it('accepts an object with an id property', function () { it('accepts an object with an id property', function () {
@ -87,32 +83,32 @@ describe('Collection', function () {
this.col.add(foo) this.col.add(foo)
expect(this.col.get(foo.id)).to.equal(foo) expect(this.col.get(foo.id)).toBe(foo)
}) })
}) })
describe('#update()', function () { describe('#update()', function () {
it('updates an item of the collection', function () { it('updates an item of the collection', function () {
const spy = sinon.spy() const spy = jest.fn()
this.col.on('update', spy) this.col.on('update', spy)
this.col.update('bar', 1) this.col.update('bar', 1)
expect(this.col.get('bar')).to.equal(1) // Will be forgotten by de-duplication expect(this.col.get('bar')).toBe(1) // Will be forgotten by de-duplication
this.col.update('bar', 2) this.col.update('bar', 2)
expect(this.col.get('bar')).to.equal(2) expect(this.col.get('bar')).toBe(2)
// No sync events. // No sync events.
sinon.assert.notCalled(spy) expect(spy).not.toHaveBeenCalled()
// Async event. // Async event.
return eventToPromise(this.col, 'update').then(function (updated) { return eventToPromise(this.col, 'update').then(function (updated) {
expect(updated).to.have.keys(['bar']) expect(Object.keys(updated)).toEqual(['bar'])
expect(updated.bar).to.equal(2) expect(updated.bar).toBe(2)
}) })
}) })
it('throws an exception if the item does not exist', function () { it('throws an exception if the item does not exist', function () {
expect(() => this.col.update('baz', true)).to.throw(NoSuchItem) expect(() => this.col.update('baz', true)).toThrowError(NoSuchItem)
}) })
it('accepts an object with an id property', function () { it('accepts an object with an id property', function () {
@ -120,31 +116,31 @@ describe('Collection', function () {
this.col.update(bar) this.col.update(bar)
expect(this.col.get(bar.id)).to.equal(bar) expect(this.col.get(bar.id)).toBe(bar)
}) })
}) })
describe('#remove()', function () { describe('#remove()', function () {
it('removes an item of the collection', function () { it('removes an item of the collection', function () {
const spy = sinon.spy() const spy = jest.fn()
this.col.on('remove', spy) this.col.on('remove', spy)
this.col.update('bar', 1) this.col.update('bar', 1)
expect(this.col.get('bar')).to.equal(1) // Will be forgotten by de-duplication expect(this.col.get('bar')).toBe(1) // Will be forgotten by de-duplication
this.col.remove('bar') this.col.remove('bar')
// No sync events. // No sync events.
sinon.assert.notCalled(spy) expect(spy).not.toHaveBeenCalled()
// Async event. // Async event.
return eventToPromise(this.col, 'remove').then(function (removed) { return eventToPromise(this.col, 'remove').then(function (removed) {
expect(removed).to.have.keys(['bar']) expect(Object.keys(removed)).toEqual(['bar'])
expect(removed.bar).to.not.exist() expect(removed.bar).toBeUndefined()
}) })
}) })
it('throws an exception if the item does not exist', function () { it('throws an exception if the item does not exist', function () {
expect(() => this.col.remove('baz', true)).to.throw(NoSuchItem) expect(() => this.col.remove('baz', true)).toThrowError(NoSuchItem)
}) })
it('accepts an object with an id property', function () { it('accepts an object with an id property', function () {
@ -152,44 +148,44 @@ describe('Collection', function () {
this.col.remove(bar) this.col.remove(bar)
expect(this.col.has(bar.id)).to.be.false() expect(this.col.has(bar.id)).toBe(false)
}) })
}) })
describe('#set()', function () { describe('#set()', function () {
it('adds item if collection has not key', function () { it('adds item if collection has not key', function () {
const spy = sinon.spy() const spy = jest.fn()
this.col.on('add', spy) this.col.on('add', spy)
this.col.set('foo', true) this.col.set('foo', true)
expect(this.col.get('foo')).to.be.true() expect(this.col.get('foo')).toBe(true)
// No sync events. // No sync events.
sinon.assert.notCalled(spy) expect(spy).not.toHaveBeenCalled()
// Async events. // Async events.
return eventToPromise(this.col, 'add').then(function (added) { return eventToPromise(this.col, 'add').then(function (added) {
expect(added).to.have.keys(['foo']) expect(Object.keys(added)).toEqual(['foo'])
expect(added.foo).to.be.true() expect(added.foo).toBe(true)
}) })
}) })
it('updates item if collection has key', function () { it('updates item if collection has key', function () {
const spy = sinon.spy() const spy = jest.fn()
this.col.on('udpate', spy) this.col.on('udpate', spy)
this.col.set('bar', 1) this.col.set('bar', 1)
expect(this.col.get('bar')).to.equal(1) expect(this.col.get('bar')).toBe(1)
// No sync events. // No sync events.
sinon.assert.notCalled(spy) expect(spy).not.toHaveBeenCalled()
// Async events. // Async events.
return eventToPromise(this.col, 'update').then(function (updated) { return eventToPromise(this.col, 'update').then(function (updated) {
expect(updated).to.have.keys(['bar']) expect(Object.keys(updated)).toEqual(['bar'])
expect(updated.bar).to.equal(1) expect(updated.bar).toBe(1)
}) })
}) })
@ -198,7 +194,7 @@ describe('Collection', function () {
this.col.set(foo) this.col.set(foo)
expect(this.col.get(foo.id)).to.equal(foo) expect(this.col.get(foo.id)).toBe(foo)
}) })
}) })
@ -206,11 +202,11 @@ describe('Collection', function () {
it('removes an existing item', function () { it('removes an existing item', function () {
this.col.unset('bar') this.col.unset('bar')
expect(this.col.has('bar')).to.be.false() expect(this.col.has('bar')).toBe(false)
return eventToPromise(this.col, 'remove').then(function (removed) { return eventToPromise(this.col, 'remove').then(function (removed) {
expect(removed).to.have.keys(['bar']) expect(Object.keys(removed)).toEqual(['bar'])
expect(removed.bar).to.not.exist() expect(removed.bar).toBeUndefined()
}) })
}) })
@ -221,11 +217,11 @@ describe('Collection', function () {
it('accepts an object with an id property', function () { it('accepts an object with an id property', function () {
this.col.unset({id: 'bar'}) this.col.unset({id: 'bar'})
expect(this.col.has('bar')).to.be.false() expect(this.col.has('bar')).toBe(false)
return eventToPromise(this.col, 'remove').then(function (removed) { return eventToPromise(this.col, 'remove').then(function (removed) {
expect(removed).to.have.keys(['bar']) expect(Object.keys(removed)).toEqual(['bar'])
expect(removed.bar).to.not.exist() expect(removed.bar).toBeUndefined()
}) })
}) })
}) })
@ -239,8 +235,8 @@ describe('Collection', function () {
this.col.touch(foo) this.col.touch(foo)
return eventToPromise(this.col, 'update', (items) => { return eventToPromise(this.col, 'update', (items) => {
expect(items).to.have.keys(['foo']) expect(Object.keys(items)).toEqual(['foo'])
expect(items.foo).to.equal(foo) expect(items.foo).toBe(foo)
}) })
}) })
}) })
@ -250,11 +246,11 @@ describe('Collection', function () {
it('removes all items from the collection', function () { it('removes all items from the collection', function () {
this.col.clear() this.col.clear()
expect(this.col.size).to.equal(0) expect(this.col.size).toBe(0)
return eventToPromise(this.col, 'remove').then((items) => { return eventToPromise(this.col, 'remove').then((items) => {
expect(items).to.have.keys(['bar']) expect(Object.keys(items)).toEqual(['bar'])
expect(items.bar).to.not.exist() expect(items.bar).toBeUndefined()
}) })
}) })
}) })
@ -326,17 +322,16 @@ describe('Collection', function () {
const spies = Object.create(null) const spies = Object.create(null)
forEach(['add', 'update', 'remove'], event => { forEach(['add', 'update', 'remove'], event => {
col.on(event, (spies[event] = sinon.spy())) col.on(event, (spies[event] = jest.fn()))
}) })
return waitTicks(2).then(() => { return waitTicks().then(() => {
forEach(spies, (spy, event) => { forEach(spies, (spy, event) => {
const items = results[event] const items = results[event]
if (items) { if (items) {
sinon.assert.calledOnce(spy) expect(spy.mock.calls).toEqual([ [ items ] ])
expect(spy.args[0][0]).to.eql(items)
} else { } else {
sinon.assert.notCalled(spy) expect(spy).not.toHaveBeenCalled()
} }
}) })
}) })

View File

@ -1,17 +1,14 @@
/* eslint-env mocha */ /* eslint-env jest */
import eventToPromise from 'event-to-promise' import eventToPromise from 'event-to-promise'
import expect from 'must'
import { forEach } from 'lodash' import { forEach } from 'lodash'
// ===================================================================
import Collection from '..' import Collection from '..'
import Index from '../index' import Index from '../index'
// =================================================================== // ===================================================================
const waitTicks = (n = 1) => { const waitTicks = (n = 2) => {
const {nextTick} = process const {nextTick} = process
return new Promise(resolve => { return new Promise(resolve => {
@ -60,7 +57,7 @@ describe('Index', function () {
}) })
it('works with existing items', function () { it('works with existing items', function () {
expect(col.indexes).to.eql({ expect(col.indexes).toEqual({
byGroup: { byGroup: {
foo: { foo: {
[item1.id]: item1, [item1.id]: item1,
@ -81,8 +78,8 @@ describe('Index', function () {
col.add(item5) col.add(item5)
return waitTicks(2).then(() => { return waitTicks().then(() => {
expect(col.indexes).to.eql({ expect(col.indexes).toEqual({
byGroup: { byGroup: {
foo: { foo: {
[item1.id]: item1, [item1.id]: item1,
@ -107,8 +104,8 @@ describe('Index', function () {
col.update(item1bis) col.update(item1bis)
return waitTicks(2).then(() => { return waitTicks().then(() => {
expect(col.indexes).to.eql({ expect(col.indexes).toEqual({
byGroup: { byGroup: {
foo: { foo: {
[item3.id]: item3 [item3.id]: item3
@ -125,8 +122,8 @@ describe('Index', function () {
it('works with removed items', function () { it('works with removed items', function () {
col.remove(item2) col.remove(item2)
return waitTicks(2).then(() => { return waitTicks().then(() => {
expect(col.indexes).to.eql({ expect(col.indexes).toEqual({
byGroup: { byGroup: {
foo: { foo: {
[item1.id]: item1, [item1.id]: item1,
@ -148,7 +145,7 @@ describe('Index', function () {
col.update(item1bis) col.update(item1bis)
return eventToPromise(col, 'finish').then(() => { return eventToPromise(col, 'finish').then(() => {
expect(col.indexes).to.eql({ expect(col.indexes).toEqual({
byGroup: { byGroup: {
foo: { foo: {
[item1.id]: item1bis, [item1.id]: item1bis,
@ -166,10 +163,10 @@ describe('Index', function () {
it('removes empty items lists', function () { it('removes empty items lists', function () {
col.remove(item2) col.remove(item2)
return waitTicks(2).then(() => { return waitTicks().then(() => {
byGroup.sweep() byGroup.sweep()
expect(col.indexes).to.eql({ expect(col.indexes).toEqual({
byGroup: { byGroup: {
foo: { foo: {
[item1.id]: item1, [item1.id]: item1,

View File

@ -1,17 +1,14 @@
/* eslint-env mocha */ /* eslint-env jest */
import eventToPromise from 'event-to-promise' import eventToPromise from 'event-to-promise'
import expect from 'must'
import { forEach } from 'lodash' import { forEach } from 'lodash'
// ===================================================================
import Collection from '..' import Collection from '..'
import Index from '../unique-index' import Index from '../unique-index'
// =================================================================== // ===================================================================
const waitTicks = (n = 1) => { const waitTicks = (n = 2) => {
const {nextTick} = process const {nextTick} = process
return new Promise(resolve => { return new Promise(resolve => {
@ -56,7 +53,7 @@ describe('UniqueIndex', function () {
}) })
it('works with existing items', function () { it('works with existing items', function () {
expect(col.indexes).to.eql({ expect(col.indexes).toEqual({
byKey: { byKey: {
[item1.key]: item1, [item1.key]: item1,
[item2.key]: item2 [item2.key]: item2
@ -72,8 +69,8 @@ describe('UniqueIndex', function () {
col.add(item4) col.add(item4)
return waitTicks(2).then(() => { return waitTicks().then(() => {
expect(col.indexes).to.eql({ expect(col.indexes).toEqual({
byKey: { byKey: {
[item1.key]: item1, [item1.key]: item1,
[item2.key]: item2, [item2.key]: item2,
@ -91,8 +88,8 @@ describe('UniqueIndex', function () {
col.update(item1bis) col.update(item1bis)
return waitTicks(2).then(() => { return waitTicks().then(() => {
expect(col.indexes).to.eql({ expect(col.indexes).toEqual({
byKey: { byKey: {
[item1bis.key]: item1bis, [item1bis.key]: item1bis,
[item2.key]: item2 [item2.key]: item2
@ -104,8 +101,8 @@ describe('UniqueIndex', function () {
it('works with removed items', function () { it('works with removed items', function () {
col.remove(item2) col.remove(item2)
return waitTicks(2).then(() => { return waitTicks().then(() => {
expect(col.indexes).to.eql({ expect(col.indexes).toEqual({
byKey: { byKey: {
[item1.key]: item1 [item1.key]: item1
} }
@ -123,7 +120,7 @@ describe('UniqueIndex', function () {
col.update(item1bis) col.update(item1bis)
return eventToPromise(col, 'finish').then(() => { return eventToPromise(col, 'finish').then(() => {
expect(col.indexes).to.eql({ expect(col.indexes).toEqual({
byKey: { byKey: {
[item1.key]: item1bis, [item1.key]: item1bis,
[item2.key]: item2 [item2.key]: item2

File diff suppressed because it is too large Load Diff