Skip to content

Commit

Permalink
Merge pull request #5 from frytg/dev/logger-test
Browse files Browse the repository at this point in the history
feat: add tests for logger
  • Loading branch information
frytg authored Dec 12, 2024
2 parents c879848 + df3f85c commit 964cb1b
Show file tree
Hide file tree
Showing 7 changed files with 202 additions and 38 deletions.
12 changes: 8 additions & 4 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ on:
permissions:
contents: read

env:
JSR_DEPENDENCIES: "@cross/test @std/assert @frytg/logger"
NPM_DEPENDENCIES: "luxon sinon"

jobs:
test-on-deno-and-lint:
runs-on: ${{ matrix.os }}
Expand Down Expand Up @@ -83,10 +87,10 @@ jobs:
run: bun --version

- name: Install JSR dependencies
run: bunx jsr add @cross/test @std/assert @frytg/logger
run: bunx jsr add ${{ env.JSR_DEPENDENCIES }}

- name: Install NPM dependencies
run: bun add luxon
run: bun add ${{ env.NPM_DEPENDENCIES }}

- name: Test
run: bun test
Expand Down Expand Up @@ -121,10 +125,10 @@ jobs:
run: node --version

- name: Install JSR dependencies
run: npx jsr add @cross/test @std/assert @frytg/logger
run: npx jsr add ${{ env.JSR_DEPENDENCIES }}

- name: Install NPM dependencies
run: npm install luxon
run: npm install ${{ env.NPM_DEPENDENCIES }}

- name: Set up package.json
run: 'echo ''{ "type": "module" }'' > package.json'
Expand Down
36 changes: 15 additions & 21 deletions check-required-env/check-required-env.test.ts
Original file line number Diff line number Diff line change
@@ -1,45 +1,39 @@
import process from 'node:process'
import { test } from '@cross/test'
import { assertEquals, assertExists } from '@std/assert'
import { assertExists } from '@std/assert'
import sinon from 'sinon'

import { checkRequiredEnv } from './check-required-env.ts'

test('checkRequiredEnv - returns when env variable exists', () => {
// Setup
const testVarName = 'TEST_ENV_VAR'
process.env[testVarName] = 'test-value'
const envStub = sinon.stub(process, 'env').value({
TEST_ENV_VAR: 'test-value',
})

// Test
checkRequiredEnv(testVarName)
checkRequiredEnv('TEST_ENV_VAR')

// Verify
assertExists(process.env[testVarName])
assertExists(process.env.TEST_ENV_VAR)

// Cleanup
delete process.env[testVarName]
envStub.restore()
})

test('checkRequiredEnv - exits when env variable is missing', () => {
// Setup
const testVarName = 'MISSING_ENV_VAR'
const originalExit = process.exit
let exitCalled = false
let exitCode: number | undefined

// Mock process.exit
process.exit = ((code?: number) => {
exitCalled = true
exitCode = code
// Don't actually exit
}) as typeof process.exit
const envStub = sinon.stub(process, 'env').value({})
const exitStub = sinon.stub(process, 'exit')

// Test
checkRequiredEnv(testVarName)
checkRequiredEnv('MISSING_ENV_VAR')

// Verify
assertEquals(exitCalled, true)
assertEquals(exitCode, 1)
sinon.assert.calledOnce(exitStub)
sinon.assert.calledWith(exitStub, 1)

// Cleanup
process.exit = originalExit
exitStub.restore()
envStub.restore()
})
3 changes: 2 additions & 1 deletion deno.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"@biomejs/biome": "npm:@biomejs/biome@^1.9.4",
"@types/node": "npm:@types/node@^22.10.2",
"@cross/test": "jsr:@cross/test@^0.0.10",
"@std/assert": "jsr:@std/assert@^1.0.9"
"@std/assert": "jsr:@std/assert@^1.0.9",
"sinon": "npm:sinon@^17.0.1"
}
}
75 changes: 74 additions & 1 deletion deno.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

61 changes: 61 additions & 0 deletions logger/logger-context.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import process from 'node:process'
import { test } from '@cross/test'
import { assertEquals, assertExists } from '@std/assert'
import sinon from 'sinon'

import logger from './logger.ts'

test('logger - includes global context in log events', () => {
// Setup
const envStub = sinon.stub(process, 'env').value({
K_REVISION: 'test-revision',
SERVICE_NAME: 'test-service',
STAGE: 'test',
npm_package_version: '1.0.0',
})

const writeStub = sinon.stub(process.stdout, 'write')
let loggedOutput = ''
writeStub.callsFake((str: string) => {
loggedOutput = str
return true
})

// Test
logger.info('test message', {
source: 'test-source',
data: { test: 'data' },
})

// Verify
const loggedData = JSON.parse(loggedOutput)
assertEquals(loggedData.host, 'test-revision')
assertEquals(loggedData.serviceName, 'test-service')
assertEquals(loggedData.stage, 'test')
assertEquals(loggedData.version, '1.0.0')
assertExists(loggedData.runtime)

// Cleanup
writeStub.restore()
envStub.restore()
})

test('logger - sets debug level correctly', () => {
// Test & Verify
assertEquals(logger.level, process.env.STAGE === 'dev' ? 'debug' : 'info')
})

test('logger - has correct syslog levels', () => {
const expectedLevels = {
emerg: 0,
alert: 1,
crit: 2,
error: 3,
warning: 4,
notice: 5,
info: 6,
debug: 7,
}

assertEquals(logger.levels, expectedLevels)
})
33 changes: 33 additions & 0 deletions logger/logger-format.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import process from 'node:process'
import { test } from '@cross/test'
import { assertEquals, assertExists } from '@std/assert'
import sinon from 'sinon'

import logger from './logger.ts'

test('logger - formats errors correctly', () => {
// Setup
const testError = new Error('test error')
const writeStub = sinon.stub(process.stdout, 'write')
let loggedOutput = ''
writeStub.callsFake((str: string) => {
loggedOutput = str
return true
})

// Test
logger.error('error occurred', {
source: 'test-source',
error: testError,
})

// Verify
const loggedData = JSON.parse(loggedOutput)
assertExists(loggedData.error.message)
assertExists(loggedData.error.stack)
assertEquals(loggedData.error.message, 'test error')
assertExists(loggedData.runtime)

// Cleanup
writeStub.restore()
})
20 changes: 9 additions & 11 deletions logger/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,14 @@ const convertGlobals = format((event) => {
})

// Set up format based on environment
let formatConfig: Logform.Format = format.combine(convertError(), convertGlobals(), format.json())
if (process.env.IS_LOCAL === 'true') {
formatConfig = format.combine(
convertError(),
convertGlobals(),
format.timestamp(),
format.json({ space: 4 }),
format.colorize({ all: true }),
)
}
const formatConfig: Logform.Format = format.combine(convertError(), convertGlobals(), format.json())
const formatConfigLocal: Logform.Format = format.combine(
convertError(),
convertGlobals(),
format.timestamp(),
format.json({ space: 4 }),
format.colorize({ all: true }),
)

/**
* Use the exported logger to log messages.
Expand Down Expand Up @@ -97,7 +95,7 @@ export const logger: Logger = createLogger({
level: process.env.STAGE === 'dev' ? 'debug' : 'info',
levels: config.syslog.levels,
exitOnError: false,
format: formatConfig,
format: process.env.IS_LOCAL === 'true' ? formatConfigLocal : formatConfig,
transports: [new transports.Console()],
})

Expand Down

0 comments on commit 964cb1b

Please sign in to comment.