1const t = require('tap') 2const { resolve, join } = require('path') 3const fs = require('graceful-fs') 4const mockLogs = require('../../fixtures/mock-logs') 5const tmock = require('../../fixtures/tmock') 6 7const mockTimers = (t, options) => { 8 const { logs, logMocks } = mockLogs() 9 const Timers = tmock(t, '{LIB}/utils/timers', { 10 ...logMocks, 11 }) 12 const timers = new Timers(options) 13 t.teardown(() => timers.off()) 14 return { timers, logs } 15} 16 17t.test('getters', async (t) => { 18 const { timers } = mockTimers(t) 19 t.match(timers.unfinished, new Map()) 20 t.match(timers.finished, {}) 21}) 22 23t.test('listens/stops on process', async (t) => { 24 const { timers } = mockTimers(t) 25 process.emit('time', 'foo') 26 process.emit('time', 'bar') 27 process.emit('timeEnd', 'bar') 28 t.match(timers.unfinished, new Map([['foo', Number]])) 29 t.match(timers.finished, { bar: Number }) 30 timers.off() 31 process.emit('time', 'baz') 32 t.notOk(timers.unfinished.get('baz')) 33}) 34 35t.test('convenience time method', async (t) => { 36 const { timers } = mockTimers(t) 37 38 const end = timers.time('later') 39 timers.time('sync', () => {}) 40 await timers.time('async', () => new Promise(r => setTimeout(r, 10))) 41 end() 42 43 t.match(timers.finished, { later: Number, sync: Number, async: Number }) 44}) 45 46t.test('initial timer', async (t) => { 47 const { timers } = mockTimers(t, { start: 'foo' }) 48 process.emit('timeEnd', 'foo') 49 t.match(timers.finished, { foo: Number }) 50}) 51 52t.test('initial listener', async (t) => { 53 const events = [] 54 const listener = (...args) => events.push(args) 55 const { timers } = mockTimers(t, { listener }) 56 process.emit('time', 'foo') 57 process.emit('time', 'bar') 58 process.emit('timeEnd', 'bar') 59 timers.off(listener) 60 process.emit('timeEnd', 'foo') 61 t.equal(events.length, 1) 62 t.match(events, [['bar', Number]]) 63}) 64 65t.test('finish unstarted timer', async (t) => { 66 const { logs } = mockTimers(t) 67 process.emit('timeEnd', 'foo') 68 t.match(logs.silly, [['timing', /^Tried to end timer/, 'foo']]) 69}) 70 71t.test('writes file', async (t) => { 72 const { timers } = mockTimers(t) 73 const dir = t.testdir() 74 process.emit('time', 'foo') 75 process.emit('timeEnd', 'foo') 76 timers.load({ path: resolve(dir, `TIMING_FILE-`) }) 77 timers.writeFile({ some: 'data' }) 78 const data = JSON.parse(fs.readFileSync(resolve(dir, 'TIMING_FILE-timing.json'))) 79 t.match(data, { 80 metadata: { some: 'data' }, 81 timers: { foo: Number }, 82 unfinishedTimers: { 83 npm: [Number, Number], 84 }, 85 }) 86}) 87 88t.test('fails to write file', async (t) => { 89 const { logs, timers } = mockTimers(t) 90 const dir = t.testdir() 91 92 timers.load({ path: join(dir, 'does', 'not', 'exist') }) 93 timers.writeFile() 94 95 t.match(logs.warn, [['timing', 'could not write timing file']]) 96 t.equal(timers.file, null) 97}) 98 99t.test('no dir and no file', async (t) => { 100 const { logs, timers } = mockTimers(t) 101 102 timers.load() 103 timers.writeFile() 104 105 t.strictSame(logs, []) 106 t.equal(timers.file, null) 107}) 108