Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add tests for logger #5

Merged
merged 3 commits into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading