@instructure/quiz-interactions
Version:
A React UI component Library for quiz interaction types.
123 lines (108 loc) • 3.44 kB
JavaScript
import {afterEach, beforeEach, describe, expect, it, vi} from 'vitest'
import GenerateSolutionsService from '../GenerateSolutionsService'
describe('GenerateSolutionsService', () => {
const onStartStub = vi.fn()
const onSuccessStub = vi.fn()
const onFailureStub = vi.fn()
const onCancelStub = vi.fn()
const numSolutions = 3
const variables = [
{
name: 'x',
min: 0,
max: 5,
precision: 0,
},
{
name: 'y',
min: 3,
max: 7,
precision: 1,
},
]
const formula = 'x + y'
const precision = 3
let service
beforeEach(async () => {
service = new GenerateSolutionsService({
onStart: onStartStub,
onSuccess: onSuccessStub,
onFailure: onFailureStub,
onCancel: onCancelStub,
})
})
afterEach(() => {
onStartStub.mockReset()
onSuccessStub.mockReset()
onFailureStub.mockReset()
onCancelStub.mockReset()
})
it('calls onStart when started', () => {
service.start(numSolutions, variables, formula, precision)
expect(onStartStub).toHaveBeenCalled()
})
it('generates a promise which returns with solutions', async () => {
await service.start(numSolutions, variables, formula, precision)
expect(onSuccessStub).toHaveBeenCalled()
expect(onFailureStub).not.toHaveBeenCalled()
const results = onSuccessStub.mock.calls[0][0]
expect(results).toHaveLength(numSolutions)
results.forEach(({inputs, output}) => {
const x = Number(inputs.find(i => i.name === 'x').value)
const y = Number(inputs.find(i => i.name === 'y').value)
expect(x + y).toBe(Number(output))
})
})
it('respects the given precision', async () => {
await service.start(numSolutions, variables, formula, 0)
const results = onSuccessStub.mock.calls[0][0]
results.forEach(({inputs, output}) => {
const sum = Number(inputs[0].value) + Number(inputs[1].value)
expect(Math.round(sum, 0)).toBe(Number(output))
})
})
it('does not call onSuccess when the promise is canceled', async () => {
const promise = service.start(numSolutions, variables, formula)
service.cancel()
await promise
expect(onSuccessStub).not.toHaveBeenCalled()
expect(onFailureStub).not.toHaveBeenCalled()
})
it('calls the onFailure stub when solution search fails', async () => {
await service.start(numSolutions, variables, 'x + y/0')
expect(onSuccessStub).not.toHaveBeenCalled()
expect(onFailureStub).toHaveBeenCalled()
})
it('does not call onFailure when the promise is canceled', async () => {
const promise = service.start(numSolutions, variables, 'x + y/0')
service.cancel()
await promise
expect(onSuccessStub).not.toHaveBeenCalled()
expect(onFailureStub).not.toHaveBeenCalled()
})
it('calls onCancel when canceled', () => {
service.start(numSolutions, variables, formula)
service.cancel()
expect(onCancelStub).toHaveBeenCalled()
})
it('fails when not enough solutions were found', async () => {
const variables = [
{
name: 'x',
min: 0,
max: 1,
precision: 0,
},
{
name: 'y',
min: 2,
max: 3,
precision: 0,
},
]
await service.start(10, variables, 'x + y')
expect(onSuccessStub).not.toHaveBeenCalled()
expect(onFailureStub).toHaveBeenCalled()
expect(onFailureStub.mock.calls[0][0]).toHaveLength(4)
})
})