-
Notifications
You must be signed in to change notification settings - Fork 339
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #233 from reficul31/util-tests
Tests for `src/util` modules
- Loading branch information
Showing
13 changed files
with
875 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import PouchDB from 'pouchdb-core' | ||
|
||
import PouchDBMemory from 'pouchdb-adapter-memory' | ||
import mapreduce from 'pouchdb-mapreduce' | ||
import replication from 'pouchdb-replication' | ||
|
||
PouchDB.plugin(PouchDBMemory) | ||
.plugin(mapreduce) | ||
.plugin(replication) | ||
|
||
const pouchdbOptions = { | ||
name: 'testdb', | ||
auto_compaction: true, | ||
adapter: 'memory', | ||
} | ||
|
||
const db = PouchDB(pouchdbOptions) | ||
export default db |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/* eslint-env jest */ | ||
|
||
import delay from './delay' | ||
|
||
jest.useFakeTimers() | ||
|
||
describe('delay', () => { | ||
test('should set a timer with the given delay', () => { | ||
delay(1000) | ||
expect(setTimeout.mock.calls.length).toBe(1) | ||
expect(setTimeout.mock.calls[0][1]).toBe(1000) | ||
}) | ||
|
||
test('should return a promise which resolves after the timer finishes', async () => { | ||
const assertFunc = jest.fn() | ||
delay(1000) | ||
.then(assertFunc) | ||
.catch(err => {}) | ||
|
||
await null | ||
expect(assertFunc).not.toHaveBeenCalled() | ||
|
||
jest.runAllTimers() | ||
|
||
await null | ||
expect(assertFunc).toHaveBeenCalled() | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
/* eslint-env jest */ | ||
|
||
import 'core-js/fn/object/entries' // shim Object.entries | ||
import pull from 'lodash/pull' | ||
|
||
import eventToPromise from './event-to-promise' | ||
|
||
class MockEvent { | ||
constructor() { | ||
this.listeners = [] | ||
} | ||
|
||
addListener(listener) { | ||
this.listeners.push(listener) | ||
} | ||
|
||
removeListener(listener) { | ||
pull(this.listeners, listener) | ||
} | ||
|
||
trigger(...args) { | ||
this.listeners.forEach(listener => listener.apply(null, args)) | ||
} | ||
} | ||
|
||
describe('eventToPromise', () => { | ||
test('should return a promise', () => { | ||
const promise = eventToPromise({}) | ||
expect(promise).toBeInstanceOf(Promise) | ||
}) | ||
|
||
test('should listen and unlisten to the events', async () => { | ||
// We try both passing multiple events (for resolveOpts) and a single event (for rejectOpts). | ||
const resolveOpts = [ | ||
{ event: new MockEvent() }, | ||
{ event: new MockEvent() }, | ||
] | ||
const rejectOpts = { event: new MockEvent() } | ||
eventToPromise({ | ||
resolve: resolveOpts, | ||
reject: rejectOpts, | ||
}) | ||
|
||
// We use a bogus await statement to let any resolved promises invoke their callbacks. | ||
// XXX Not sure if we can rely on this in every ES implementation. | ||
await null | ||
expect(resolveOpts[0].event.listeners.length).toBe(1) | ||
expect(resolveOpts[1].event.listeners.length).toBe(1) | ||
expect(rejectOpts.event.listeners.length).toBe(1) | ||
|
||
// Trigger any of the events. | ||
resolveOpts[1].event.trigger() | ||
|
||
await null | ||
expect(resolveOpts[0].event.listeners.length).toBe(0) | ||
expect(resolveOpts[1].event.listeners.length).toBe(0) | ||
expect(rejectOpts.event.listeners.length).toBe(0) | ||
}) | ||
|
||
describe('should resolve with given value when a resolve-event occurs', () => { | ||
const values = { | ||
object: { someKey: 'someValue' }, | ||
function: () => ({ someKey: 'someValue' }), | ||
} | ||
Object.entries(values).forEach(([type, value]) => { | ||
test(`when value is a: ${type}`, async () => { | ||
const resolveOpts = { event: new MockEvent(), value } | ||
const resolveHandler = jest.fn() | ||
eventToPromise({ | ||
resolve: resolveOpts, | ||
}) | ||
.then(resolveHandler) | ||
.catch() | ||
|
||
await null | ||
expect(resolveHandler).not.toBeCalled() | ||
|
||
resolveOpts.event.trigger() | ||
|
||
await null | ||
expect(resolveHandler).toBeCalledWith({ someKey: 'someValue' }) | ||
}) | ||
}) | ||
}) | ||
|
||
const reasons = { | ||
string: 'something', | ||
function: () => 'something else', | ||
object: { someKey: 'something' }, | ||
} | ||
describe('should reject with Error(string) if a reject-event occurs', () => { | ||
Object.entries(reasons).forEach(([type, reason]) => { | ||
test(`when reason is a: ${type}`, async () => { | ||
const rejectOpts = { | ||
event: new MockEvent(), | ||
reason, | ||
} | ||
const rejectHandler = jest.fn() | ||
eventToPromise({ | ||
reject: rejectOpts, | ||
}).catch(rejectHandler) | ||
|
||
await null | ||
expect(rejectHandler).not.toBeCalled() | ||
|
||
rejectOpts.event.trigger() | ||
|
||
await null | ||
expect(rejectHandler).toBeCalled() | ||
const error = rejectHandler.mock.calls[0][0] | ||
expect(error).toBeInstanceOf(Error) | ||
expect(error.message).toMatch(/.*something.*/) | ||
}) | ||
}) | ||
}) | ||
|
||
test('should apply filter to events', async () => { | ||
const resolveOpts = { | ||
event: new MockEvent(), | ||
filter: jest.fn(), | ||
} | ||
const resolveHandler = jest.fn() | ||
eventToPromise({ | ||
resolve: resolveOpts, | ||
}) | ||
.then(resolveHandler) | ||
.catch() | ||
|
||
await null | ||
expect(resolveHandler).not.toBeCalled() | ||
|
||
resolveOpts.filter.mockReturnValueOnce(false) | ||
resolveOpts.event.trigger() | ||
|
||
await null | ||
expect(resolveHandler).not.toBeCalled() | ||
|
||
resolveOpts.filter.mockReturnValueOnce(true) | ||
resolveOpts.event.trigger() | ||
|
||
await null | ||
expect(resolveHandler).toBeCalled() | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
/* eslint-env jest */ | ||
|
||
import { | ||
makeRangeTransform, | ||
makeNonlinearTransform, | ||
} from './make-range-transform' | ||
|
||
describe('makeRangeTransform', () => { | ||
test('should work for basic cases', () => { | ||
const transformFunction = makeRangeTransform({ | ||
domain: [66, 100], | ||
range: [9, 200], | ||
}) | ||
expect(transformFunction(79)).toBeCloseTo(82.029, 2) | ||
expect(transformFunction(43)).toBeCloseTo(-120.205, 2) | ||
expect(transformFunction(170)).toBeCloseTo(593.235, 2) | ||
}) | ||
|
||
test('should clamp its outputs with clampOutput true', () => { | ||
const transformFunction = makeRangeTransform({ | ||
domain: [93, 117], | ||
range: [3, 10], | ||
clampOutput: true, | ||
}) | ||
expect(transformFunction(99)).toBeCloseTo(4.75, 2) | ||
expect(transformFunction(83)).toBe(3) | ||
expect(transformFunction(150)).toBe(10) | ||
}) | ||
|
||
test('should work with descending domain and/or range', () => { | ||
const transformFunction1 = makeRangeTransform({ | ||
domain: [100, 0], | ||
range: [0, 10], | ||
}) | ||
expect(transformFunction1(80)).toBe(2) | ||
expect(transformFunction1(-40)).toBe(14) | ||
expect(transformFunction1(120)).toBe(-2) | ||
const transformFunction2 = makeRangeTransform({ | ||
domain: [0, 100], | ||
range: [10, 0], | ||
}) | ||
expect(transformFunction2(80)).toBe(2) | ||
expect(transformFunction2(-40)).toBe(14) | ||
expect(transformFunction2(120)).toBe(-2) | ||
const transformFunction3 = makeRangeTransform({ | ||
domain: [100, 0], | ||
range: [10, 0], | ||
}) | ||
expect(transformFunction3(80)).toBe(8) | ||
expect(transformFunction3(-40)).toBe(-4) | ||
expect(transformFunction3(120)).toBe(12) | ||
}) | ||
|
||
test('should work with descending domain and/or range with clamping', () => { | ||
const transformFunction1 = makeRangeTransform({ | ||
domain: [100, 0], | ||
range: [0, 10], | ||
clampOutput: true, | ||
}) | ||
expect(transformFunction1(80)).toBe(2) | ||
expect(transformFunction1(-40)).toBe(10) | ||
expect(transformFunction1(120)).toBe(0) | ||
const transformFunction2 = makeRangeTransform({ | ||
domain: [0, 100], | ||
range: [10, 0], | ||
clampOutput: true, | ||
}) | ||
expect(transformFunction2(80)).toBe(10) | ||
expect(transformFunction2(-40)).toBe(10) | ||
expect(transformFunction2(120)).toBe(10) | ||
const transformFunction3 = makeRangeTransform({ | ||
domain: [100, 0], | ||
range: [10, 0], | ||
clampOutput: true, | ||
}) | ||
expect(transformFunction3(80)).toBe(10) | ||
expect(transformFunction3(-40)).toBe(10) | ||
expect(transformFunction3(120)).toBe(10) | ||
}) | ||
}) | ||
|
||
describe('makeNonlinearTransform', () => { | ||
test('should work for basic cases', () => { | ||
const transformFunction = makeNonlinearTransform({ | ||
domain: [5, 5603], | ||
range: [0, 100], | ||
nonlinearity: Math.log, | ||
}) | ||
expect(transformFunction(5)).toBe(0) | ||
expect(transformFunction(5603)).toBe(100) | ||
expect(transformFunction(3)).toBeCloseTo(-7.275, 2) | ||
expect(transformFunction(1997)).toBeCloseTo(85.3074, 2) | ||
expect(transformFunction(6000)).toBeCloseTo(100.974, 2) | ||
}) | ||
|
||
test('should clamp its outputs with clampOutput true', () => { | ||
const transformFunction = makeNonlinearTransform({ | ||
domain: [5, 5603], | ||
range: [0, 100], | ||
clampOutput: true, | ||
nonlinearity: Math.log, | ||
}) | ||
expect(transformFunction(5)).toBe(0) | ||
expect(transformFunction(5603)).toBe(100) | ||
expect(transformFunction(3)).toBe(0) | ||
expect(transformFunction(1997)).toBeCloseTo(85.3074, 2) | ||
expect(transformFunction(6000)).toBe(100) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
/* eslint-env jest */ | ||
|
||
import niceTime from './nice-time' | ||
|
||
describe('niceTime', () => { | ||
test('should return now for timeperiod of less than 90 seconds', () => { | ||
const date = new Date() | ||
expect(niceTime(date)).toBe('now') | ||
}) | ||
|
||
test('should return minutes for timeperiod of less than 600 seconds', () => { | ||
const date = new Date(2016, 7, 2, 14, 25) | ||
const now = new Date(2016, 7, 2, 14, 45) | ||
expect(niceTime(date, { now })).toBe('20 minutes ago') | ||
}) | ||
|
||
test('should return timeperiod stamp for timeperiod less than 24 hours', () => { | ||
const date = new Date(2016, 7, 2, 14, 25) | ||
const now = new Date(2016, 7, 2, 18, 55) | ||
expect(niceTime(date, { now })).toBe('14:25') | ||
}) | ||
|
||
test('should return the timeperiod stamp and the day for timeperiod less than 24 hours but not on the same day', () => { | ||
const date = new Date(2016, 7, 2, 14, 25) | ||
const now = new Date(2016, 7, 3, 10, 55) | ||
expect(niceTime(date, { now })).toBe('Yesterday 14:25') | ||
}) | ||
|
||
test('should return the day and timestamp for timeperiod less than 3 days', () => { | ||
const date = new Date(2016, 7, 2, 14, 25) | ||
const now = new Date(2016, 7, 4, 18, 55) | ||
expect(niceTime(date, { now })).toBe('Tue 14:25') | ||
}) | ||
|
||
test('should return the date and the month for timeperiod in the same year', () => { | ||
const date = new Date(2016, 7, 2, 14, 25) | ||
const now = new Date(2016, 9, 2, 18, 55) | ||
expect(niceTime(date, { now })).toBe('2 Aug') | ||
}) | ||
|
||
test('should return the date, month and year for timeperiod not in the same year', () => { | ||
const date = new Date(2016, 7, 2, 14, 25) | ||
const now = new Date(2017, 7, 2, 18, 55) | ||
expect(niceTime(date, { now })).toBe('2 Aug 2016') | ||
}) | ||
|
||
test('should return the placeholder for invalid date', () => { | ||
const date = new Date(2016, 7, 3, 14, 25) | ||
const now = new Date(2016, 7, 2, 18, 55) | ||
expect(niceTime(date, { now })).toBe('soon?!') | ||
}) | ||
}) |
Oops, something went wrong.