Skip to content

Commit

Permalink
test: add test for common and utils
Browse files Browse the repository at this point in the history
  • Loading branch information
GrinZero committed Jul 19, 2024
1 parent 54f1c5a commit 486fd8f
Show file tree
Hide file tree
Showing 5 changed files with 248 additions and 2 deletions.
4 changes: 2 additions & 2 deletions packages/network-debugger/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
}
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"test": "vitest",
"build": "vite build",
"dev": "vite build --watch"
},
Expand Down Expand Up @@ -47,7 +47,7 @@
"tslib": "2.6.2",
"vite": "^5.2.10",
"vite-plugin-dts": "^3.8.3",
"vitest": "^1.5.0"
"vitest": "^2.0.3"
},
"dependencies": {
"iconv-lite": "^0.6.3",
Expand Down
25 changes: 25 additions & 0 deletions packages/network-debugger/src/common.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { vi, describe, beforeEach, test, expect } from 'vitest'
import { RequestDetail, __filename, __dirname } from './common'

describe('RequestDetail', () => {
beforeEach(() => {
vi.clearAllMocks()
})

describe('constructor', () => {
test('should initialize with a unique id and default properties', () => {
const requestDetail = new RequestDetail()

expect(requestDetail.id).toBeDefined()
expect(requestDetail.responseInfo).toEqual({})
expect(requestDetail.initiator).not.toBeUndefined()
})

test('should increment id for each new instance', () => {
const requestDetail1 = new RequestDetail()
const requestDetail2 = new RequestDetail()

expect(Number(requestDetail2.id)).toBe(Number(requestDetail1.id) + 1)
})
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { RequestHeaderPipe } from './request-header-transformer'
import { describe, test, expect } from 'vitest'

describe('RequestHeaderPipe', () => {
describe('constructor', () => {
test('should initialize with empty headers when no headers are provided', () => {
const requestHeaderPipe = new RequestHeaderPipe()
expect(requestHeaderPipe.getData()).toEqual({})
})

test('should initialize with provided headers', () => {
const headers = { 'Content-Type': 'application/json', Accept: 'application/json' }
const requestHeaderPipe = new RequestHeaderPipe(headers)
expect(requestHeaderPipe.getData()).toEqual(headers)
})
})

describe('getHeader', () => {
test('should return the value of the header if it exists (case-insensitive)', () => {
const headers = { 'Content-Type': 'application/json', Accept: 'application/json' }
const requestHeaderPipe = new RequestHeaderPipe(headers)

expect(requestHeaderPipe.getHeader('content-type')).toBe('application/json')
expect(requestHeaderPipe.getHeader('Content-Type')).toBe('application/json')
})

test('should return undefined if the header does not exist', () => {
const headers = { 'Content-Type': 'application/json', Accept: 'application/json' }
const requestHeaderPipe = new RequestHeaderPipe(headers)

expect(requestHeaderPipe.getHeader('Authorization')).toBeUndefined()
})
})

describe('getData', () => {
test('should return all headers', () => {
const headers = { 'Content-Type': 'application/json', Accept: 'application/json' }
const requestHeaderPipe = new RequestHeaderPipe(headers)

expect(requestHeaderPipe.getData()).toEqual(headers)
})
})

describe('valueOf', () => {
test('should return the headers object', () => {
const headers = { 'Content-Type': 'application/json', Accept: 'application/json' }
const requestHeaderPipe = new RequestHeaderPipe(headers)

expect(requestHeaderPipe.valueOf()).toEqual(headers)
})
})
})
97 changes: 97 additions & 0 deletions packages/network-debugger/src/utils/call-site.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { CallSite } from './call-site'
import { describe, test, expect } from 'vitest'

describe('CallSite', () => {
test('parses a simple stack trace line', () => {
const line = 'at Object.<anonymous> (/path/to/file.js:10:15)'
const callSite = new CallSite(line)

expect(callSite.fileName).toBe('/path/to/file.js')
expect(callSite.lineNumber).toBe(10)
expect(callSite.columnNumber).toBe(15)
expect(callSite.functionName).toBe(null)
expect(callSite.typeName).toBe('Object')
expect(callSite.methodName).toBe(null)
expect(callSite.native).toBe(false)
})

test('parses a stack trace line with a function name', () => {
const line = 'at functionName (/path/to/file.js:10:15)'
const callSite = new CallSite(line)

expect(callSite.fileName).toBe('/path/to/file.js')
expect(callSite.lineNumber).toBe(10)
expect(callSite.columnNumber).toBe(15)
expect(callSite.functionName).toBe('functionName')
expect(callSite.typeName).toBe(null)
expect(callSite.methodName).toBe(null)
expect(callSite.native).toBe(false)
})

test('parses a native stack trace line', () => {
const line = 'at native'
const callSite = new CallSite(line)

expect(callSite.fileName).toBe(null)
expect(callSite.lineNumber).toBe(null)
expect(callSite.columnNumber).toBe(null)
expect(callSite.functionName).toBe(null)
expect(callSite.typeName).toBe(null)
expect(callSite.methodName).toBe(null)
expect(callSite.native).toBe(true)
})

test('parses a line with object and method name', () => {
const line = 'at MyObject.myMethod (/path/to/file.js:10:15)'
const callSite = new CallSite(line)

expect(callSite.fileName).toBe('/path/to/file.js')
expect(callSite.lineNumber).toBe(10)
expect(callSite.columnNumber).toBe(15)
expect(callSite.functionName).toBe('MyObject.myMethod')
expect(callSite.typeName).toBe('MyObject')
expect(callSite.methodName).toBe('myMethod')
expect(callSite.native).toBe(false)
})

test('parses a line with anonymous function', () => {
const line = 'at <anonymous> (/path/to/file.js:10:15)'
const callSite = new CallSite(line)

expect(callSite.fileName).toBe('/path/to/file.js')
expect(callSite.lineNumber).toBe(10)
expect(callSite.columnNumber).toBe(15)
expect(callSite.functionName).toBe('<anonymous>')
expect(callSite.typeName).toBe(null)
expect(callSite.methodName).toBe(null)
expect(callSite.native).toBe(false)
})

test('copying properties from another CallSite instance', () => {
const site1 = new CallSite('at functionName (/path/to/file.js:10:15)')
const site2 = new CallSite(site1)

expect(site2.fileName).toBe('/path/to/file.js')
expect(site2.lineNumber).toBe(10)
expect(site2.columnNumber).toBe(15)
expect(site2.functionName).toBe('functionName')
expect(site2.typeName).toBe(null)
expect(site2.methodName).toBe(null)
expect(site2.native).toBe(false)
})

test('converts CallSite to string', () => {
const callSite = new CallSite('at MyObject.myMethod (/path/to/file.js:10:15)')
const expectedString = JSON.stringify({
fileName: '/path/to/file.js',
lineNumber: 10,
functionName: 'MyObject.myMethod',
typeName: 'MyObject',
methodName: 'myMethod',
columnNumber: 15,
native: false
})

expect(callSite.toString()).toBe(expectedString)
})
})
72 changes: 72 additions & 0 deletions packages/network-debugger/src/utils/stack.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { beforeEach, describe, expect, test, vi } from 'vitest'
import { CallSite } from './call-site'
import { getStackFrames, initiatorStackPipe } from './stack' // Adjust the path as needed

vi.mock('./call-site', () => {
return {
CallSite: vi.fn().mockImplementation((line) => {
const instance = {
fileName: null,
lineNumber: null,
functionName: null,
typeName: null,
methodName: null,
columnNumber: null,
native: false
}

const parseMock = vi.fn((l: string) => instance)

if (typeof line === 'string') {
parseMock(line)
}

return instance
})
}
})

describe('Stack Frame Utilities', () => {
beforeEach(() => {
;(CallSite as any).mockClear()
})

describe('getStackFrames', () => {
test('generates stack frames from an error stack', () => {
const stack =
'Error\n' +
' at functionName (/path/to/file.js:10:15)\n' +
' at Object.<anonymous> (/another/path/file.js:20:25)'
const frames = getStackFrames(stack)

expect(CallSite).toHaveBeenCalledTimes(2)
expect(frames.length).toBe(2)
})

test('captures stack frames when no stack is provided', () => {
const frames = getStackFrames()

// Expect the captureStackTrace to have been called
// Since we can't control the stack trace of the current environment in Jest,
// we'll just check that the frames are not empty.
expect(frames.length).toBeGreaterThan(0)
})
})

describe('initiatorStackPipe', () => {
test('filters out frames based on ignoreList', () => {
const mockFrames = [
{ fileName: '/path/to/file.js', lineNumber: 10 },
{ fileName: '(internal/async_hooks.js:1:1)', lineNumber: 1 },
{ fileName: '/node_modules/module/file.js', lineNumber: 5 },
{ fileName: '/another/path/file.js', lineNumber: 20 }
].map((frame) => Object.assign(new CallSite(''), frame))

const filteredFrames = initiatorStackPipe(mockFrames)

expect(filteredFrames.length).toBe(2)
expect(filteredFrames[0].fileName).toBe('/path/to/file.js')
expect(filteredFrames[1].fileName).toBe('/another/path/file.js')
})
})
})

0 comments on commit 486fd8f

Please sign in to comment.