Skip to content
Open
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
33 changes: 26 additions & 7 deletions src/add-elements.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { Storage } from './jest-chrome'
* @template T Type of namespace member
*/
interface SchemaData<
T extends 'event' | 'function' | 'property'
T extends 'event' | 'function' | 'property',
> {
name: string
type: T
Expand Down Expand Up @@ -62,11 +62,30 @@ export const addEvent = (
return event
}

/** As of Manifest v3, all the Chrome API functions that accepted a callback
* now return promises when the callback is not supplied.
*/
const makeAsyncMock = (callbackArgIndex: number) =>
jest
.fn()
.mockImplementation(
(...args: any[]): Promise<void> | void => {
if (!args[callbackArgIndex]) {
return Promise.resolve()
}
},
)

export const addFunction = (
{ name }: SchemaData<'function'>,
{ name, parameters }: SchemaData<'function'>,
target: any,
) => {
const fn = jest.fn()
const fn =
parameters?.length &&
parameters[parameters.length - 1]?.name === 'callback' &&
parameters[parameters.length - 1]?.type === 'function'
? makeAsyncMock(parameters.length - 1)
: jest.fn()
Object.assign(target, { [name]: fn })

return fn
Expand All @@ -93,10 +112,10 @@ export const addProperty = (

export function addStorageArea(): Storage.StorageArea {
return {
clear: jest.fn(),
get: jest.fn(),
clear: makeAsyncMock(0),
get: makeAsyncMock(1),
getBytesInUse: jest.fn(),
remove: jest.fn(),
set: jest.fn(),
remove: makeAsyncMock(1),
set: makeAsyncMock(1),
}
}
22 changes: 21 additions & 1 deletion src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,16 @@ test('get: function', () => {
expect(chrome.runtime.getManifest).toBeCalled()
})

test('async: undefined with callback', () => {
expect(chrome.runtime.openOptionsPage(() => 1)).toBeUndefined()
})

test('async: promise without callback', () => {
expect(chrome.runtime.openOptionsPage()).toBeInstanceOf(
Promise,
)
})

test('get: event', () => {
expect(chrome.runtime.onMessage).toMatchObject<
CallableEvent<
Expand Down Expand Up @@ -77,6 +87,16 @@ test('ownKeys: storage', () => {
})
})

test('storage: undefined with callback', () => {
expect(
chrome.storage.local.get('key', () => 1),
).toBeUndefined()
})

test('storage: promise without callback', () => {
expect(chrome.storage.local.get('key')).toBeInstanceOf(Promise)
})

test('set: lastError correctly', () => {
const lastErrorSpy = jest.fn(() => 'test')
const lastError = {
Expand All @@ -92,7 +112,7 @@ test('set: lastError correctly', () => {
})

test('set: lastError incorrectly', () => {
const lastError = ('error' as unknown) as Runtime.LastError
const lastError = 'error' as unknown as Runtime.LastError

const setter = () => (chrome.runtime.lastError = lastError)

Expand Down