Skip to content

Commit

Permalink
Merge pull request #2 from GeorgeCht/tests/v1
Browse files Browse the repository at this point in the history
Tests/v1
  • Loading branch information
GeorgeCht authored Oct 23, 2024
2 parents 57423dc + a58d9de commit fa49c5b
Show file tree
Hide file tree
Showing 5 changed files with 205 additions and 1 deletion.
43 changes: 43 additions & 0 deletions tests/dispatching.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { z } from 'zod'
import { EventController } from '../src'

describe('EventController Event Dispatching', () => {
const schema = z.object({ name: z.string() })
let controller: EventController<typeof schema>

beforeEach(() => {
controller = new EventController(schema, 'testEvent')
})

test('should dispatch an event with valid payload', async () => {
const listener = jest.fn()
controller.subscribe(listener)
await controller.dispatch({ name: 'Test' })
expect(listener).toHaveBeenCalledWith(expect.any(CustomEvent))
})

test('should not dispatch an event with invalid payload', async () => {
const listener = jest.fn()
controller.subscribe(listener)
await expect(controller.dispatch({ name: 123 } as any)).rejects.toThrow()
expect(listener).not.toHaveBeenCalled()
})

test('should dispatch event with bubbling', async () => {
const listener = jest.fn()
controller.subscribe(listener)
await controller.dispatch({ name: 'Test' }, { bubbles: true })
expect(listener).toHaveBeenCalledWith(
expect.objectContaining({ bubbles: true }),
)
})

test('should dispatch event with cancellation', async () => {
const listener = jest.fn()
controller.subscribe(listener)
await controller.dispatch({ name: 'Test' }, { cancelable: true })
expect(listener).toHaveBeenCalledWith(
expect.objectContaining({ cancelable: true }),
)
})
})
88 changes: 88 additions & 0 deletions tests/edge.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { z } from 'zod'
import { EventController } from '../src'

describe('EventController Advanced Scenarios and Edge Cases', () => {
test('should handle high-frequency event dispatches', async () => {
const schema = z.object({ value: z.number() })
const controller = new EventController(schema, 'testEvent')
const listener = jest.fn()
controller.subscribe(listener)

const dispatches = Array.from({ length: 1000 }, (_, i) => ({ value: i }))
await Promise.all(dispatches.map((payload) => controller.dispatch(payload)))

expect(listener).toHaveBeenCalledTimes(1000)
})

test('should handle concurrent dispatches from multiple controllers', async () => {
const schema = z.object({ value: z.number() })
const controller1 = new EventController(schema, 'testEvent1')
const controller2 = new EventController(schema, 'testEvent2')

const listener1 = jest.fn()
const listener2 = jest.fn()

controller1.subscribe(listener1)
controller2.subscribe(listener2)

await Promise.all([
controller1.dispatch({ value: 1 }),
controller2.dispatch({ value: 2 }),
controller1.dispatch({ value: 3 }),
controller2.dispatch({ value: 4 }),
])

expect(listener1).toHaveBeenCalledTimes(2)
expect(listener2).toHaveBeenCalledTimes(2)
})

test('should handle recursive schema', async () => {
type TreeNode = { value: number; children?: TreeNode[] }
const treeSchema: z.ZodType<TreeNode> = z.lazy(() =>
z.object({
value: z.number(),
children: z.array(treeSchema).optional(),
}),
)

const controller = new EventController(treeSchema, 'treeEvent')
const listener = jest.fn()
controller.subscribe(listener)

await controller.dispatch({
value: 1,
children: [{ value: 2 }, { value: 3, children: [{ value: 4 }] }],
})

expect(listener).toHaveBeenCalled()
})

test('should handle error in middleware without breaking the system', async () => {
const schema = z.object({ value: z.number() })
const controller = new EventController(schema, 'testEvent')

controller.use(() => {
throw new Error('Middleware error')
})

const listener = jest.fn()
controller.subscribe(listener)

await expect(controller.dispatch({ value: 1 })).rejects.toThrow(
'Middleware error',
)
expect(listener).not.toHaveBeenCalled()
})

test('should prevent multiple calls to next() in middleware', async () => {
const schema = z.object({ value: z.number() })
const controller = new EventController(schema, 'testEvent')

controller.use(async (_, next) => {
await next()
await expect(next()).rejects.toThrow('next() called multiple times')
})

await controller.dispatch({ value: 1 })
})
})
41 changes: 41 additions & 0 deletions tests/lifecycle.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { z } from 'zod'
import { EventController } from '../src'

describe('EventController Lifecycle Callbacks', () => {
const schema = z.object({ name: z.string() })

test('should execute onError callback when dispatching invalid payload', async () => {
const onError = jest.fn()
const controller = new EventController(schema, 'testEvent', { onError })
await controller.dispatch({ name: 123 } as any)
expect(onError).toHaveBeenCalled()
})

test('should execute onDispatch callback before dispatching event', async () => {
const onDispatch = jest.fn()
const controller = new EventController(schema, 'testEvent', { onDispatch })
await controller.dispatch({ name: 'Test' })
expect(onDispatch).toHaveBeenCalledWith(
expect.objectContaining({
payload: { name: 'Test' },
}),
)
})

test('should execute onSubscribe callback when subscribing', () => {
const onSubscribe = jest.fn()
const controller = new EventController(schema, 'testEvent', { onSubscribe })
controller.subscribe(() => {})
expect(onSubscribe).toHaveBeenCalled()
})

test('should execute onUnsubscribe callback when unsubscribing', () => {
const onUnsubscribe = jest.fn()
const controller = new EventController(schema, 'testEvent', {
onUnsubscribe,
})
controller.subscribe(() => {})
controller.unsubscribe()
expect(onUnsubscribe).toHaveBeenCalled()
})
})
2 changes: 1 addition & 1 deletion tests/middleware.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { createPipeline } from '../src/middleware'

import type { Middleware, Pipeline } from '../src/middleware'

describe('createPipeline', () => {
describe('Middleware Pipeline', () => {
const TestSchema = z.object({
id: z.number(),
name: z.string(),
Expand Down
32 changes: 32 additions & 0 deletions tests/refine.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { z } from 'zod'
import { EventController } from '../src'

describe('EventController Refinement', () => {
const schema = z.object({ value: z.number() })
let controller: EventController<typeof schema>

beforeEach(() => {
controller = new EventController(schema, 'testEvent')
})

afterEach(() => {
controller.unsubscribe()
controller.update({})
})

test('should apply refinement condition', async () => {
controller.refine((payload) => payload.value > 0)
const listener = jest.fn()
controller.subscribe(listener)
await controller.dispatch({ value: 10 })
await controller.dispatch({ value: -5 })
expect(listener).toHaveBeenCalledTimes(1)
})

test('should execute refinement callback when condition is not met', async () => {
const callback = jest.fn()
controller.refine((payload) => payload.value > 0, callback)
await controller.dispatch({ value: -5 })
expect(callback).toHaveBeenCalled()
})
})

0 comments on commit fa49c5b

Please sign in to comment.