Skip to content
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
46 changes: 17 additions & 29 deletions src/__tests__/lib/command/command-util.test.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
import { jest } from '@jest/globals'

import inquirer from 'inquirer'
import type { sort } from '../../../lib/command/output.js'
import type { ListDataFunction, Sorting } from '../../../lib/command/io-defs.js'
import { stringInput } from '../../../lib/user-query.js'
import type { SimpleType } from '../../test-lib/simple-type.js'

import { sort } from '../../../lib/command/output.js'
import { ListDataFunction, Sorting } from '../../../lib/command/io-defs.js'
import { SimpleType } from '../../test-lib/simple-type.js'


const promptMock = jest.fn<typeof inquirer.prompt>()
jest.unstable_mockModule('inquirer', () => ({
default: {
prompt: promptMock,
},
const stringInputMock = jest.fn<typeof stringInput>()
jest.unstable_mockModule('../../../lib/user-query.js', () => ({
stringInput: stringInputMock,
}))

const sortMock = jest.fn<typeof sort>()
Expand Down Expand Up @@ -162,55 +159,46 @@ describe('convertToId', () => {

describe('stringGetIdFromUser', () => {
it('accepts id input from user', async () => {
promptMock.mockResolvedValue({ itemIdOrIndex: 'string-id-a' })
stringInputMock.mockResolvedValue('string-id-a')

const chosenId = await stringGetIdFromUser(config, list)

expect(chosenId).toBe('string-id-a')

expect(promptMock).toHaveBeenCalledExactlyOnceWith({
type: 'input', name: 'itemIdOrIndex',
message: 'Enter id or index', validate: expect.anything(),
})
const validateFunction = (promptMock.mock.calls[0][0] as { validate: (input: string) => true | string }).validate
expect(stringInputMock).toHaveBeenCalledExactlyOnceWith('Enter id or index', { validate: expect.anything() })
const validateFunction = (stringInputMock.mock.calls[0][1] as { validate: (input: string) => true | string }).validate

expect(validateFunction('string-id-a')).toBe(true)
})

it('validation returns error when unable to convert', async () => {
promptMock.mockResolvedValue({ itemIdOrIndex: 'string-id-a' })
stringInputMock.mockResolvedValue('string-id-a')

const chosenId = await stringGetIdFromUser(config, list)

expect(chosenId).toBe('string-id-a')

expect(promptMock).toHaveBeenCalledExactlyOnceWith({
type: 'input', name: 'itemIdOrIndex',
message: 'Enter id or index', validate: expect.anything(),
})
const validateFunction = (promptMock.mock.calls[0][0] as { validate: (input: string) => true | string }).validate
expect(stringInputMock).toHaveBeenCalledExactlyOnceWith('Enter id or index', { validate: expect.anything() })
const validateFunction = (stringInputMock.mock.calls[0][1] as { validate: (input: string) => true | string }).validate

expect(validateFunction('invalid-id')).toBe('Invalid id or index "invalid-id". Please enter an index or valid id.')
})

it('throws error when unable to convert entered value to a valid id', async () => {
promptMock.mockResolvedValue({ itemIdOrIndex: 'invalid-id' })
stringInputMock.mockResolvedValue('invalid-id')

await expect(stringGetIdFromUser(config, list)).rejects.toThrow('unable to convert invalid-id to id')
})

it('handles non-default prompt', async () => {
promptMock.mockResolvedValue({ itemIdOrIndex: 'string-id-a' })
stringInputMock.mockResolvedValue('string-id-a')

const chosenId = await stringGetIdFromUser(config, list, 'give me an id')

expect(chosenId).toBe('string-id-a')

expect(promptMock).toHaveBeenCalledExactlyOnceWith({
type: 'input', name: 'itemIdOrIndex',
message: 'give me an id', validate: expect.anything(),
})
const validateFunction = (promptMock.mock.calls[0][0] as { validate: (input: string) => true | string }).validate
expect(stringInputMock).toHaveBeenCalledExactlyOnceWith('give me an id', { validate: expect.anything() })
const validateFunction = (stringInputMock.mock.calls[0][1] as { validate: (input: string) => true | string }).validate

expect(validateFunction('string-id-a')).toBe(true)
})
Expand Down
49 changes: 24 additions & 25 deletions src/__tests__/lib/command/select.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { jest } from '@jest/globals'

import inquirer from 'inquirer'
import type { select } from '@inquirer/prompts'
import log4js from 'log4js'

import type {
Expand All @@ -25,13 +25,12 @@ import type {
import type { SimpleType } from '../../test-lib/simple-type.js'


const promptMock = jest.fn<typeof inquirer.prompt>()
jest.unstable_mockModule('inquirer', () => ({
default: {
prompt: promptMock,
},
const selectMock = jest.fn<typeof select>()
jest.unstable_mockModule('@inquirer/prompts', () => ({
select: selectMock,
}))


const resetManagedConfigKeyMock = jest.fn<typeof resetManagedConfigKey>()
const setConfigKeyMock = jest.fn<typeof setConfigKey>()
jest.unstable_mockModule('../../../lib/cli-config.js', () => ({
Expand Down Expand Up @@ -235,7 +234,7 @@ describe('selectFromList', () => {
expect(stringGetIdFromUserMock).not.toHaveBeenCalled()

expect(booleanConfigValueMock).not.toHaveBeenCalled()
expect(promptMock).not.toHaveBeenCalled()
expect(selectMock).not.toHaveBeenCalled()
expect(setConfigKeyMock).not.toHaveBeenCalled()
expect(getItemMock).not.toHaveBeenCalled()
expect(userMessageMock).not.toHaveBeenCalled()
Expand All @@ -251,7 +250,7 @@ describe('selectFromList', () => {
expect(stringGetIdFromUserMock).toHaveBeenCalledTimes(1)

expect(booleanConfigValueMock).not.toHaveBeenCalled()
expect(promptMock).not.toHaveBeenCalled()
expect(selectMock).not.toHaveBeenCalled()
expect(setConfigKeyMock).not.toHaveBeenCalled()
expect(getItemMock).not.toHaveBeenCalled()
expect(userMessageMock).not.toHaveBeenCalled()
Expand All @@ -275,7 +274,7 @@ describe('selectFromList', () => {
expect(stringGetIdFromUserMock).not.toHaveBeenCalled()

expect(booleanConfigValueMock).not.toHaveBeenCalled()
expect(promptMock).not.toHaveBeenCalled()
expect(selectMock).not.toHaveBeenCalled()
expect(setConfigKeyMock).not.toHaveBeenCalled()
expect(userMessageMock).toHaveBeenCalledExactlyOnceWith(item1)
expect(resetManagedConfigKeyMock).not.toHaveBeenCalled()
Expand All @@ -286,7 +285,7 @@ describe('selectFromList', () => {
defaultItem: 'default-item-id',
})
getItemMock.mockResolvedValueOnce(undefined as unknown as SimpleType)
promptMock.mockResolvedValue({ answer: 'No' })
selectMock.mockResolvedValue('no')

const options = { listItems: listItemsMock, defaultValue }
expect(await selectFromList(commandWithDefault, config, options)).toBe('chosen-id')
Expand All @@ -296,7 +295,7 @@ describe('selectFromList', () => {
expect(stringGetIdFromUserMock).toHaveBeenCalledTimes(1)

expect(booleanConfigValueMock).toHaveBeenCalledTimes(1)
expect(promptMock).toHaveBeenCalledTimes(1)
expect(selectMock).toHaveBeenCalledTimes(1)
expect(setConfigKeyMock).not.toHaveBeenCalled()
expect(getItemMock).toHaveBeenCalledExactlyOnceWith('default-item-id')
expect(userMessageMock).not.toHaveBeenCalled()
Expand All @@ -311,7 +310,7 @@ describe('selectFromList', () => {
defaultItem: 'default-item-id',
})
getItemMock.mockRejectedValueOnce({ response: { status: statusCode } })
promptMock.mockResolvedValue({ answer: 'No' })
selectMock.mockResolvedValue('no')

const options = { listItems: listItemsMock, defaultValue }
expect(await selectFromList(commandWithDefault, config, options)).toBe('chosen-id')
Expand All @@ -321,7 +320,7 @@ describe('selectFromList', () => {
expect(stringGetIdFromUserMock).toHaveBeenCalledTimes(1)

expect(booleanConfigValueMock).toHaveBeenCalledTimes(1)
expect(promptMock).toHaveBeenCalledTimes(1)
expect(selectMock).toHaveBeenCalledTimes(1)
expect(setConfigKeyMock).not.toHaveBeenCalled()
expect(getItemMock).toHaveBeenCalledExactlyOnceWith('default-item-id')
expect(userMessageMock).not.toHaveBeenCalled()
Expand All @@ -335,7 +334,7 @@ describe('selectFromList', () => {
defaultItem: 'default-item-id',
})
getItemMock.mockRejectedValueOnce(Error('unexpected error'))
promptMock.mockResolvedValue({ answer: 'No' })
selectMock.mockResolvedValue('no')

const options = { listItems: listItemsMock, defaultValue }
await expect(selectFromList(commandWithDefault, config, options))
Expand All @@ -346,7 +345,7 @@ describe('selectFromList', () => {
expect(stringGetIdFromUserMock).not.toHaveBeenCalled()

expect(booleanConfigValueMock).not.toHaveBeenCalled()
expect(promptMock).not.toHaveBeenCalled()
expect(selectMock).not.toHaveBeenCalled()
expect(setConfigKeyMock).not.toHaveBeenCalled()
expect(getItemMock).toHaveBeenCalledExactlyOnceWith('default-item-id')
expect(userMessageMock).not.toHaveBeenCalled()
Expand All @@ -355,7 +354,7 @@ describe('selectFromList', () => {

it('does not save default when user asked not to', async () => {
booleanConfigValueMock.mockReturnValueOnce(false)
promptMock.mockResolvedValue({ answer: 'No' })
selectMock.mockResolvedValue('no')

expect(await selectFromList(command, config,
{ listItems: listItemsMock, defaultValue })).toBe('chosen-id')
Expand All @@ -366,8 +365,8 @@ describe('selectFromList', () => {

expect(booleanConfigValueMock)
.toHaveBeenCalledExactlyOnceWith('defaultItem::neverAskForSaveAgain')
expect(promptMock).toHaveBeenCalledExactlyOnceWith(
expect.objectContaining({ type: 'list', name: 'answer' }),
expect(selectMock).toHaveBeenCalledExactlyOnceWith(
expect.objectContaining({ message: 'Do you want to save this as the default?' }),
)
expect(setConfigKeyMock).not.toHaveBeenCalled()
})
Expand All @@ -384,13 +383,13 @@ describe('selectFromList', () => {

expect(booleanConfigValueMock)
.toHaveBeenCalledExactlyOnceWith('defaultItem::neverAskForSaveAgain')
expect(promptMock).not.toHaveBeenCalled()
expect(selectMock).not.toHaveBeenCalled()
expect(setConfigKeyMock).not.toHaveBeenCalled()
})

it('saves selected item as default', async () => {
booleanConfigValueMock.mockReturnValueOnce(false)
promptMock.mockResolvedValue({ answer: 'yes' })
selectMock.mockResolvedValue('yes')

expect(await selectFromList(command, config,
{ listItems: listItemsMock, defaultValue })).toBe('chosen-id')
Expand All @@ -401,8 +400,8 @@ describe('selectFromList', () => {

expect(booleanConfigValueMock)
.toHaveBeenCalledExactlyOnceWith('defaultItem::neverAskForSaveAgain')
expect(promptMock).toHaveBeenCalledExactlyOnceWith(
expect.objectContaining({ type: 'list', name: 'answer' }),
expect(selectMock).toHaveBeenCalledExactlyOnceWith(
expect.objectContaining({ message: 'Do you want to save this as the default?' }),
)
expect(setConfigKeyMock)
.toHaveBeenCalledExactlyOnceWith(command.cliConfig, 'defaultItem', 'chosen-id')
Expand All @@ -412,7 +411,7 @@ describe('selectFromList', () => {

it('saves "never ask again" response"', async () => {
booleanConfigValueMock.mockReturnValueOnce(false)
promptMock.mockResolvedValue({ answer: 'never' })
selectMock.mockResolvedValue('never')

expect(await selectFromList(command, config,
{ listItems: listItemsMock, defaultValue })).toBe('chosen-id')
Expand All @@ -423,8 +422,8 @@ describe('selectFromList', () => {

expect(booleanConfigValueMock).toHaveBeenCalledTimes(1)
expect(booleanConfigValueMock).toHaveBeenCalledWith('defaultItem::neverAskForSaveAgain')
expect(promptMock).toHaveBeenCalledExactlyOnceWith(
expect.objectContaining({ type: 'list', name: 'answer' }),
expect(selectMock).toHaveBeenCalledExactlyOnceWith(
expect.objectContaining({ message: 'Do you want to save this as the default?' }),
)
expect(setConfigKeyMock).toHaveBeenCalledExactlyOnceWith(
command.cliConfig,
Expand Down
Loading