diff --git a/src/context.test.ts b/src/context.test.ts
index 7f8619121..579ea8f4c 100644
--- a/src/context.test.ts
+++ b/src/context.test.ts
@@ -43,6 +43,20 @@ describe('Context', () => {
expect(res.headers.get('X-Custom')).toBe('Message')
})
+ it('c.html() with async', async () => {
+ const res = await c.html(
+ new Promise((resolve) => setTimeout(() => resolve('
Hello! Hono!
'), 0)),
+ 201,
+ {
+ 'X-Custom': 'Message',
+ }
+ )
+ expect(res.status).toBe(201)
+ expect(res.headers.get('Content-Type')).toMatch('text/html')
+ expect(await res.text()).toBe('Hello! Hono!
')
+ expect(res.headers.get('X-Custom')).toBe('Message')
+ })
+
it('c.redirect()', async () => {
let res = c.redirect('/destination')
expect(res.status).toBe(302)
@@ -67,6 +81,18 @@ describe('Context', () => {
expect(foo).toBe('Bar, Buzz')
})
+ it('c.set() and c.get()', async () => {
+ expect(c.get('foo')).toBe(undefined)
+ c.set('foo', 'bar')
+ expect(c.get('foo')).toBe('bar')
+ expect(c.get('foo2')).toBe(undefined)
+ })
+
+ it('c.notFound()', async () => {
+ const res = c.notFound()
+ expect(res).instanceOf(Response)
+ })
+
it('Should set headers if already this.#headers is created by `c.header()`', async () => {
c.header('X-Foo', 'Bar')
c.header('X-Foo', 'Buzz', { append: true })
@@ -96,6 +122,12 @@ describe('Context', () => {
expect(res.headers.get('X-Foo2')).toBe(null)
})
+ it('c.header() - clear the header when append is true', async () => {
+ c.header('X-Foo', 'Bar', { append: true })
+ c.header('X-Foo', undefined)
+ expect(c.res.headers.get('X-Foo')).toBe(null)
+ })
+
it('c.body() - multiple header', async () => {
const res = c.body('Hi', 200, {
'X-Foo': ['Bar', 'Buzz'],
@@ -210,17 +242,64 @@ describe('Context', () => {
})
})
+describe('event and executionCtx', () => {
+ const req = new HonoRequest(new Request('http://localhost/'))
+
+ it('Should return the event if accessing c.event', () => {
+ const respondWith = vi.fn()
+ const c = new Context(req, {
+ // @ts-expect-error the type is not correct
+ executionCtx: {
+ respondWith: respondWith,
+ },
+ })
+ expect(() => c.event).not.toThrowError()
+ c.event.respondWith(new Response())
+ expect(respondWith).toHaveBeenCalled()
+ })
+
+ it('Should throw an error if accessing c.event', () => {
+ const c = new Context(req)
+ expect(() => c.event).toThrowError()
+ })
+
+ it('Should return the executionCtx if accessing c.executionCtx', () => {
+ const pathThroughOnException = vi.fn()
+ const waitUntil = vi.fn()
+ const c = new Context(req, {
+ executionCtx: {
+ passThroughOnException: pathThroughOnException,
+ waitUntil: waitUntil,
+ },
+ env: {},
+ })
+ expect(() => c.executionCtx).not.toThrowError()
+ c.executionCtx.passThroughOnException()
+ expect(pathThroughOnException).toHaveBeenCalled()
+ const asyncFunc = async () => {}
+ c.executionCtx.waitUntil(asyncFunc())
+ expect(waitUntil).toHaveBeenCalled()
+ })
+
+ it('Should throw an error if accessing c.executionCtx', () => {
+ const c = new Context(req)
+ expect(() => c.executionCtx).toThrowError()
+ })
+})
+
describe('Context header', () => {
const req = new HonoRequest(new Request('http://localhost/'))
let c: Context
beforeEach(() => {
c = new Context(req)
})
+
it('Should return only one content-type value', async () => {
c.header('Content-Type', 'foo')
const res = await c.html('foo')
expect(res.headers.get('Content-Type')).toBe('text/html; charset=UTF-8')
})
+
it('Should rewrite header values correctly', async () => {
c.res = await c.html('foo')
const res = c.text('foo')
@@ -238,12 +317,20 @@ describe('Context header', () => {
})
it('Should set cookie headers when re-assigning Response to `c.res`', () => {
- c.res = new Response(null)
+ const cookies = ['foo=bar; Path=/', 'foo2=bar2; Path=/']
const res = new Response(null)
- res.headers.append('set-cookie', 'foo=bar; Path=/')
- res.headers.append('set-cookie', 'foo2=bar2; Path=/')
+ res.headers.append('set-cookie', cookies[0])
+ res.headers.append('set-cookie', cookies[1])
c.res = res
expect(c.res.headers.getSetCookie().length).toBe(2)
+
+ // Re-assign
+ const newCookies = ['foo3=bar3; Path=/']
+ const newResponse = new Response(null)
+ newResponse.headers.append('set-cookie', newCookies[0])
+ c.res = newResponse
+ expect(c.res.headers.getSetCookie().length).toBe(cookies.length)
+ expect(c.res.headers.getSetCookie()).toEqual(cookies)
})
it('Should keep previous cookies in response headers', () => {
diff --git a/src/context.ts b/src/context.ts
index e5eaa5815..51702aa08 100644
--- a/src/context.ts
+++ b/src/context.ts
@@ -237,7 +237,7 @@ export class Context<
* ```
*/
env: E['Bindings'] = {}
- private _var: E['Variables'] = {}
+ private _var: E['Variables'] | undefined
finalized: boolean = false
/**
* `.error` can get the error object from the middleware if the Handler throws an error.
@@ -467,9 +467,9 @@ export class Context<
/**
* `.set()` can set the value specified by the key.
- *
+ *
* @see {@link https://hono.dev/api/context#set-get}
- *
+ *
* @example
* ```ts
* app.use('*', async (c, next) => {