Skip to content

Commit

Permalink
Move utils tests to sibling files
Browse files Browse the repository at this point in the history
  • Loading branch information
jsumners committed Aug 28, 2023
1 parent 5733343 commit 065fc99
Show file tree
Hide file tree
Showing 27 changed files with 941 additions and 928 deletions.
3 changes: 3 additions & 0 deletions .taprc.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
coverage: true
coverage-map: 'coverage-map.js'

reporter: terse

files:
- 'lib/**/*.test.js'
- 'test/**/*.test.js'
9 changes: 9 additions & 0 deletions coverage-map.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
'use strict'

module.exports = testFile => {
// Ignore coverage on files that do not have a direct corollary.
if (testFile.startsWith('test/')) return false

// Indicate the matching name, sans '.test.js', should be checked for coverage.
return testFile.replace(/\.test\.js$/, '.js')
}
4 changes: 2 additions & 2 deletions test/lib/colors.test.js → lib/colors.test.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
'use strict'

const { test } = require('tap')
const getColorizerPrivate = require('../../lib/colors')
const { colorizerFactory: getColorizerPublic } = require('../../index')
const getColorizerPrivate = require('./colors')
const { colorizerFactory: getColorizerPublic } = require('../index')

const testDefaultColorizer = getColorizer => async t => {
const colorizer = getColorizer()
Expand Down
47 changes: 47 additions & 0 deletions lib/utils/build-safe-sonic-boom.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
'use strict'

const tap = require('tap')
const rimraf = require('rimraf')
const fs = require('fs')
const { join } = require('path')

const buildSafeSonicBoom = require('./build-safe-sonic-boom')

function noop () {}

const file = () => {
const dest = join(__dirname, `${process.pid}-${process.hrtime().toString()}`)
const fd = fs.openSync(dest, 'w')
return { dest, fd }
}

tap.test('should not write when error emitted and code is "EPIPE"', async t => {
t.plan(1)

const { fd, dest } = file()
const stream = buildSafeSonicBoom({ sync: true, fd, mkdir: true })
t.teardown(() => rimraf(dest, noop))

stream.emit('error', { code: 'EPIPE' })
stream.write('will not work')

const dataFile = fs.readFileSync(dest)
t.equal(dataFile.length, 0)
})

tap.test('should stream.write works when error code is not "EPIPE"', async t => {
t.plan(3)
const { fd, dest } = file()
const stream = buildSafeSonicBoom({ sync: true, fd, mkdir: true })

t.teardown(() => rimraf(dest, noop))

stream.on('error', () => t.pass('error emitted'))

stream.emit('error', 'fake error description')

t.ok(stream.write('will work'))

const dataFile = fs.readFileSync(dest)
t.equal(dataFile.toString(), 'will work')
})
20 changes: 20 additions & 0 deletions lib/utils/create-date.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
'use strict'

const tap = require('tap')
const createDate = require('./create-date')

const wanted = 1624450038567

tap.test('accepts arguments the Date constructor would accept', async t => {
t.plan(2)
t.same(createDate(1624450038567).getTime(), wanted)
t.same(createDate('2021-06-23T12:07:18.567Z').getTime(), wanted)
})

tap.test('accepts epoch as a string', async t => {
// If Date() accepts this argument, the createDate function is not needed
// and can be replaced with Date()
t.plan(2)
t.notSame(new Date('16244500385-67').getTime(), wanted)
t.same(createDate('1624450038567').getTime(), wanted)
})
31 changes: 31 additions & 0 deletions lib/utils/delete-log-property.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
'use strict'

const tap = require('tap')
const { createCopier } = require('fast-copy')
const fastCopy = createCopier({})
const deleteLogProperty = require('./delete-log-property')

const logData = {
level: 30,
data1: {
data2: { 'data-3': 'bar' }
}
}

tap.test('deleteLogProperty deletes property of depth 1', async t => {
const log = fastCopy(logData)
deleteLogProperty(log, 'data1')
t.same(log, { level: 30 })
})

tap.test('deleteLogProperty deletes property of depth 2', async t => {
const log = fastCopy(logData)
deleteLogProperty(log, 'data1.data2')
t.same(log, { level: 30, data1: { } })
})

tap.test('deleteLogProperty deletes property of depth 3', async t => {
const log = fastCopy(logData)
deleteLogProperty(log, 'data1.data2.data-3')
t.same(log, { level: 30, data1: { data2: { } } })
})
117 changes: 117 additions & 0 deletions lib/utils/filter-log.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
'use strict'

const tap = require('tap')
const filterLog = require('./filter-log')

const logData = {
level: 30,
time: 1522431328992,
data1: {
data2: { 'data-3': 'bar' },
error: new Error('test')
}
}
const logData2 = Object.assign({
'logging.domain.corp/operation': {
id: 'foo',
producer: 'bar'
}
}, logData)

tap.test('#filterLog with an ignoreKeys option', t => {
t.test('filterLog removes single entry', async t => {
const result = filterLog({ log: logData, ignoreKeys: ['data1.data2.data-3'] })
t.same(result, { level: 30, time: 1522431328992, data1: { data2: { }, error: new Error('test') } })
})

t.test('filterLog removes multiple entries', async t => {
const result = filterLog({ log: logData, ignoreKeys: ['time', 'data1'] })
t.same(result, { level: 30 })
})

t.test('filterLog keeps error instance', async t => {
const result = filterLog({ log: logData, ignoreKeys: [] })
t.equal(logData.data1.error, result.data1.error)
})

t.test('filterLog removes entry with escape sequence', async t => {
const result = filterLog({ log: logData2, ignoreKeys: ['data1', 'logging\\.domain\\.corp/operation'] })
t.same(result, { level: 30, time: 1522431328992 })
})

t.test('filterLog removes entry with escape sequence nested', async t => {
const result = filterLog({ log: logData2, ignoreKeys: ['data1', 'logging\\.domain\\.corp/operation.producer'] })
t.same(result, { level: 30, time: 1522431328992, 'logging.domain.corp/operation': { id: 'foo' } })
})

t.end()
})

const ignoreKeysArray = [
undefined,
['level'],
['level', 'data1.data2.data-3']
]
ignoreKeysArray.forEach(ignoreKeys => {
tap.test(`#filterLog with an includeKeys option when the ignoreKeys being ${ignoreKeys}`, t => {
t.test('filterLog include nothing', async t => {
const result = filterLog({ log: logData, ignoreKeys, includeKeys: [] })
t.same(result, {})
})

t.test('filterLog include single entry', async t => {
const result = filterLog({ log: logData, ignoreKeys, includeKeys: ['time'] })
t.same(result, { time: 1522431328992 })
})

t.test('filterLog include multiple entries', async t => {
const result = filterLog({ log: logData, ignoreKeys, includeKeys: ['time', 'data1'] })
t.same(result, {
time: 1522431328992,
data1: {
data2: { 'data-3': 'bar' },
error: new Error('test')
}
})
})

t.end()
})
})

tap.test('#filterLog with circular references', t => {
const logData = {
level: 30,
time: 1522431328992,
data1: 'test'
}
logData.circular = logData

t.test('filterLog removes single entry', async t => {
const result = filterLog({ log: logData, ignoreKeys: ['data1'] })

t.same(result.circular.level, result.level)
t.same(result.circular.time, result.time)

delete result.circular
t.same(result, { level: 30, time: 1522431328992 })
})

t.test('filterLog includes single entry', async t => {
const result = filterLog({ log: logData, includeKeys: ['data1'] })

t.same(result, { data1: 'test' })
})

t.test('filterLog includes circular keys', async t => {
const result = filterLog({ log: logData, includeKeys: ['level', 'circular'] })

t.same(result.circular.level, logData.level)
t.same(result.circular.time, logData.time)

delete result.circular
t.same(result, { level: 30 })
})

t.end()
})
65 changes: 65 additions & 0 deletions lib/utils/format-time.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
'use strict'

process.env.TZ = 'UTC'

const tap = require('tap')
const formatTime = require('./format-time')

const dateStr = '2019-04-06T13:30:00.000-04:00'
const epoch = new Date(dateStr)
const epochMS = epoch.getTime()

tap.test('passes through epoch if `translateTime` is `false`', async t => {
const formattedTime = formatTime(epochMS)
t.equal(formattedTime, epochMS)
})

tap.test('translates epoch milliseconds if `translateTime` is `true`', async t => {
const formattedTime = formatTime(epochMS, true)
t.equal(formattedTime, '17:30:00.000')
})

tap.test('translates epoch milliseconds to UTC string given format', async t => {
const formattedTime = formatTime(epochMS, 'd mmm yyyy H:MM')
t.equal(formattedTime, '6 Apr 2019 17:30')
})

tap.test('translates epoch milliseconds to SYS:STANDARD', async t => {
const formattedTime = formatTime(epochMS, 'SYS:STANDARD')
t.match(formattedTime, /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3} [-+]?\d{4}/)
})

tap.test('translates epoch milliseconds to SYS:<FORMAT>', async t => {
const formattedTime = formatTime(epochMS, 'SYS:d mmm yyyy H:MM')
t.match(formattedTime, /\d{1} \w{3} \d{4} \d{1,2}:\d{2}/)
})

tap.test('passes through date string if `translateTime` is `false`', async t => {
const formattedTime = formatTime(dateStr)
t.equal(formattedTime, dateStr)
})

tap.test('translates date string if `translateTime` is `true`', async t => {
const formattedTime = formatTime(dateStr, true)
t.equal(formattedTime, '17:30:00.000')
})

tap.test('translates date string to UTC string given format', async t => {
const formattedTime = formatTime(dateStr, 'd mmm yyyy H:MM')
t.equal(formattedTime, '6 Apr 2019 17:30')
})

tap.test('translates date string to SYS:STANDARD', async t => {
const formattedTime = formatTime(dateStr, 'SYS:STANDARD')
t.match(formattedTime, /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3} [-+]?\d{4}/)
})

tap.test('translates date string to UTC:<FORMAT>', async t => {
const formattedTime = formatTime(dateStr, 'UTC:d mmm yyyy H:MM')
t.equal(formattedTime, '6 Apr 2019 17:30')
})

tap.test('translates date string to SYS:<FORMAT>', async t => {
const formattedTime = formatTime(dateStr, 'SYS:d mmm yyyy H:MM')
t.match(formattedTime, /\d{1} \w{3} \d{4} \d{1,2}:\d{2}/)
})
31 changes: 31 additions & 0 deletions lib/utils/get-property-value.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
'use strict'

const tap = require('tap')
const getPropertyValue = require('./get-property-value')

tap.test('getPropertyValue returns the value of the property', async t => {
const result = getPropertyValue({
foo: 'bar'
}, 'foo')
t.same(result, 'bar')
})

tap.test('getPropertyValue returns the value of the nested property', async t => {
const result = getPropertyValue({ extra: { foo: { value: 'bar' } } }, 'extra.foo.value')
t.same(result, 'bar')
})

tap.test('getPropertyValue returns the value of the nested property using the array of nested property keys', async t => {
const result = getPropertyValue({ extra: { foo: { value: 'bar' } } }, ['extra', 'foo', 'value'])
t.same(result, 'bar')
})

tap.test('getPropertyValue returns undefined for non-existing properties', async t => {
const result = getPropertyValue({ extra: { foo: { value: 'bar' } } }, 'extra.foo.value-2')
t.same(result, undefined)
})

tap.test('getPropertyValue returns undefined for non-existing properties using the array of nested property keys', async t => {
const result = getPropertyValue({ extra: { foo: { value: 'bar' } } }, ['extra', 'foo', 'value-2'])
t.same(result, undefined)
})
31 changes: 31 additions & 0 deletions lib/utils/handle-custom-levels-names-opts.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
'use strict'

const tap = require('tap')
const handleCustomLevelsNamesOpts = require('./handle-custom-levels-names-opts')

tap.test('returns a empty object `{}` for unknown parameter', async t => {
const handledCustomLevelNames = handleCustomLevelsNamesOpts(123)
t.same(handledCustomLevelNames, {})
})

tap.test('returns a filled object for string parameter', async t => {
const handledCustomLevelNames = handleCustomLevelsNamesOpts('ok:10,warn:20,error:35')
t.same(handledCustomLevelNames, {
ok: 10,
warn: 20,
error: 35
})
})

tap.test('returns a filled object for object parameter', async t => {
const handledCustomLevelNames = handleCustomLevelsNamesOpts({
ok: 10,
warn: 20,
error: 35
})
t.same(handledCustomLevelNames, {
ok: 10,
warn: 20,
error: 35
})
})
Loading

0 comments on commit 065fc99

Please sign in to comment.