419 lines
14 KiB
JavaScript
419 lines
14 KiB
JavaScript
import React from 'react'
|
|
import { NumericInput } from '../../../src/components/Common/NumericInput'
|
|
import { TEXT_FIELDS, VALIDATION_MESSAGES, VALIDATION_TYPES } from '../../../src/utils/constants'
|
|
import renderer from 'react-test-renderer'
|
|
import Adapter from 'enzyme-adapter-react-15'
|
|
import { configure, mount } from 'enzyme'
|
|
|
|
configure({ adapter: new Adapter() })
|
|
|
|
describe('NumericInput', () => {
|
|
const INPUT_EVENT = {
|
|
KEYPRESS: 'keypress',
|
|
CHANGE: 'change',
|
|
PASTE: 'paste'
|
|
}
|
|
|
|
let changeMock
|
|
let keypressMock
|
|
let pasteMock
|
|
let numericInputComponent
|
|
let wrapperMemo, wrapper
|
|
let inputMemo, input
|
|
|
|
beforeEach(() => {
|
|
changeMock = { target: { value: '' } }
|
|
|
|
keypressMock = { key: '1', preventDefault: jest.fn() }
|
|
|
|
pasteMock = {
|
|
preventDefault: jest.fn(),
|
|
clipboardData: {
|
|
getData: () => 'e123e123'
|
|
}
|
|
}
|
|
|
|
numericInputComponent = {
|
|
side: 'left',
|
|
title: TEXT_FIELDS.DECIMALS,
|
|
description:
|
|
'Refers to how divisible a token can be, from 0 (not at all divisible) to 18 (pretty much continuous).',
|
|
errorMessage: VALIDATION_MESSAGES.DECIMALS,
|
|
onValueUpdate: jest.fn()
|
|
}
|
|
|
|
wrapperMemo = undefined
|
|
wrapper = () => wrapperMemo || (wrapperMemo = mount(React.createElement(NumericInput, numericInputComponent)))
|
|
|
|
inputMemo = undefined
|
|
input = () =>
|
|
inputMemo ||
|
|
(inputMemo = wrapper()
|
|
.find('input')
|
|
.at(0))
|
|
})
|
|
|
|
it('Should render the component', () => {
|
|
numericInputComponent.min = 0
|
|
numericInputComponent.max = 18
|
|
numericInputComponent.acceptFloat = true
|
|
numericInputComponent.minDecimals = 0
|
|
numericInputComponent.maxDecimals = 4
|
|
|
|
expect(renderer.create(React.createElement(NumericInput, numericInputComponent)).toJSON()).toMatchSnapshot()
|
|
})
|
|
it('Should prevent pasting invalid value', () => {
|
|
input().simulate(INPUT_EVENT.PASTE, pasteMock)
|
|
expect(pasteMock.preventDefault).toHaveBeenCalled()
|
|
})
|
|
it('Should allow pasting valid value', () => {
|
|
pasteMock.clipboardData.getData = () => '12'
|
|
|
|
input().simulate(INPUT_EVENT.PASTE, pasteMock)
|
|
expect(pasteMock.preventDefault).toHaveBeenCalledTimes(0)
|
|
})
|
|
|
|
it('Should call onValueUpdate callback on successful update', () => {
|
|
changeMock.target.value = '10'
|
|
|
|
input().simulate(INPUT_EVENT.CHANGE, changeMock)
|
|
expect(numericInputComponent.onValueUpdate).toHaveBeenCalledTimes(1)
|
|
expect(numericInputComponent.onValueUpdate).toHaveBeenCalledWith({
|
|
value: 10,
|
|
pristine: false,
|
|
valid: VALIDATION_TYPES.VALID
|
|
})
|
|
})
|
|
|
|
it('Should accept empty values', () => {
|
|
numericInputComponent.acceptEmpty = true
|
|
changeMock.target.value = ''
|
|
|
|
input().simulate(INPUT_EVENT.CHANGE, changeMock)
|
|
expect(numericInputComponent.onValueUpdate).toHaveBeenCalledTimes(1)
|
|
expect(numericInputComponent.onValueUpdate).toHaveBeenCalledWith({
|
|
value: '',
|
|
pristine: false,
|
|
valid: VALIDATION_TYPES.VALID
|
|
})
|
|
})
|
|
|
|
it('Should reject empty values', () => {
|
|
changeMock.target.value = ''
|
|
|
|
input().simulate(INPUT_EVENT.CHANGE, changeMock)
|
|
expect(numericInputComponent.onValueUpdate).toHaveBeenCalledTimes(1)
|
|
expect(numericInputComponent.onValueUpdate).toHaveBeenCalledWith({
|
|
value: '',
|
|
pristine: false,
|
|
valid: VALIDATION_TYPES.INVALID
|
|
})
|
|
})
|
|
|
|
describe('symbols', () => {
|
|
it('Should consider empty string as valid', () => {
|
|
input().simulate(INPUT_EVENT.CHANGE, changeMock)
|
|
expect(numericInputComponent.onValueUpdate).toHaveBeenCalled()
|
|
})
|
|
|
|
describe('min', () => {
|
|
it('Should accept "-" symbol if min is negative', () => {
|
|
numericInputComponent.min = -10
|
|
keypressMock.key = '-'
|
|
|
|
input().simulate(INPUT_EVENT.KEYPRESS, keypressMock)
|
|
expect(keypressMock.preventDefault).toHaveBeenCalledTimes(0)
|
|
})
|
|
it('Should accept "-" symbol if min is negative and accepts floating numbers', () => {
|
|
numericInputComponent.min = -10
|
|
numericInputComponent.acceptFloat = true
|
|
keypressMock.key = '-'
|
|
|
|
input().simulate(INPUT_EVENT.KEYPRESS, keypressMock)
|
|
expect(keypressMock.preventDefault).toHaveBeenCalledTimes(0)
|
|
})
|
|
it('Should reject "-" symbol if min is not negative', () => {
|
|
numericInputComponent.min = 0
|
|
keypressMock.key = '-'
|
|
|
|
input().simulate(INPUT_EVENT.KEYPRESS, keypressMock)
|
|
expect(keypressMock.preventDefault).toHaveBeenCalled()
|
|
})
|
|
})
|
|
|
|
describe('max', () => {
|
|
it('Should accept "-" symbol if max is negative', () => {
|
|
numericInputComponent.max = -10
|
|
keypressMock.key = '-'
|
|
|
|
input().simulate(INPUT_EVENT.KEYPRESS, keypressMock)
|
|
expect(keypressMock.preventDefault).toHaveBeenCalledTimes(0)
|
|
})
|
|
it('Should accept "-" symbol if max is negative and accepts floating numbers', () => {
|
|
numericInputComponent.max = -10
|
|
numericInputComponent.acceptFloat = true
|
|
keypressMock.key = '-'
|
|
|
|
input().simulate(INPUT_EVENT.KEYPRESS, keypressMock)
|
|
expect(keypressMock.preventDefault).toHaveBeenCalledTimes(0)
|
|
})
|
|
it('Should reject "-" symbol if max is not negative', () => {
|
|
numericInputComponent.max = 10
|
|
keypressMock.key = '-'
|
|
|
|
input().simulate(INPUT_EVENT.KEYPRESS, keypressMock)
|
|
expect(keypressMock.preventDefault).toHaveBeenCalled()
|
|
})
|
|
})
|
|
|
|
it('Should prevent "." if no float is allowed', () => {
|
|
numericInputComponent.value = '10'
|
|
keypressMock.key = '.'
|
|
|
|
input().simulate(INPUT_EVENT.KEYPRESS, keypressMock)
|
|
expect(keypressMock.preventDefault).toHaveBeenCalledTimes(1)
|
|
})
|
|
|
|
it('Should prevent "+" if no float is allowed', () => {
|
|
numericInputComponent.value = '10'
|
|
keypressMock.key = '+'
|
|
|
|
input().simulate(INPUT_EVENT.KEYPRESS, keypressMock)
|
|
expect(keypressMock.preventDefault).toHaveBeenCalledTimes(1)
|
|
})
|
|
|
|
it('Should prevent "e" if no float is allowed', () => {
|
|
numericInputComponent.value = '10'
|
|
keypressMock.key = 'e'
|
|
|
|
input().simulate(INPUT_EVENT.KEYPRESS, keypressMock)
|
|
expect(keypressMock.preventDefault).toHaveBeenCalledTimes(1)
|
|
})
|
|
})
|
|
|
|
describe('integer numbers', () => {
|
|
describe('min', () => {
|
|
it('Should fail if value is lesser than min', () => {
|
|
numericInputComponent.min = 5
|
|
changeMock.target.value = '4'
|
|
|
|
input().simulate(INPUT_EVENT.CHANGE, changeMock)
|
|
expect(numericInputComponent.onValueUpdate).toHaveBeenCalledTimes(1)
|
|
expect(numericInputComponent.onValueUpdate).toHaveBeenCalledWith({
|
|
value: 4,
|
|
pristine: false,
|
|
valid: VALIDATION_TYPES.INVALID
|
|
})
|
|
})
|
|
it('Should pass if value is greater than min', () => {
|
|
numericInputComponent.min = 5
|
|
changeMock.target.value = '8'
|
|
|
|
input().simulate(INPUT_EVENT.CHANGE, changeMock)
|
|
expect(numericInputComponent.onValueUpdate).toHaveBeenCalledTimes(1)
|
|
expect(numericInputComponent.onValueUpdate).toHaveBeenCalledWith({
|
|
value: 8,
|
|
pristine: false,
|
|
valid: VALIDATION_TYPES.VALID
|
|
})
|
|
})
|
|
})
|
|
|
|
describe('max', () => {
|
|
it('Should fail if value is greater than max', () => {
|
|
numericInputComponent.max = 15
|
|
changeMock.target.value = '20'
|
|
|
|
input().simulate(INPUT_EVENT.CHANGE, changeMock)
|
|
expect(numericInputComponent.onValueUpdate).toHaveBeenCalledTimes(1)
|
|
expect(numericInputComponent.onValueUpdate).toHaveBeenCalledWith({
|
|
value: 20,
|
|
pristine: false,
|
|
valid: VALIDATION_TYPES.INVALID
|
|
})
|
|
})
|
|
it('Should pass if value is lesser than min', () => {
|
|
numericInputComponent.max = 15
|
|
changeMock.target.value = '10'
|
|
|
|
input().simulate(INPUT_EVENT.CHANGE, changeMock)
|
|
expect(numericInputComponent.onValueUpdate).toHaveBeenCalledTimes(1)
|
|
expect(numericInputComponent.onValueUpdate).toHaveBeenCalledWith({
|
|
value: 10,
|
|
pristine: false,
|
|
valid: VALIDATION_TYPES.VALID
|
|
})
|
|
})
|
|
})
|
|
})
|
|
|
|
describe('float numbers', () => {
|
|
beforeEach(() => {
|
|
numericInputComponent.acceptFloat = true
|
|
numericInputComponent.minDecimals = 2
|
|
numericInputComponent.maxDecimals = 4
|
|
})
|
|
|
|
describe('maxDecimals', () => {
|
|
it('Should fail if value has more decimals', () => {
|
|
changeMock.target.value = '1.12345'
|
|
|
|
input().simulate(INPUT_EVENT.CHANGE, changeMock)
|
|
expect(numericInputComponent.onValueUpdate).toHaveBeenCalledTimes(1)
|
|
expect(numericInputComponent.onValueUpdate).toHaveBeenCalledWith({
|
|
value: 1.12345,
|
|
pristine: false,
|
|
valid: VALIDATION_TYPES.INVALID
|
|
})
|
|
})
|
|
it('Should pass if value has less decimals', () => {
|
|
changeMock.target.value = '1.123'
|
|
|
|
input().simulate(INPUT_EVENT.CHANGE, changeMock)
|
|
expect(numericInputComponent.onValueUpdate).toHaveBeenCalledTimes(1)
|
|
expect(numericInputComponent.onValueUpdate).toHaveBeenCalledWith({
|
|
value: 1.123,
|
|
pristine: false,
|
|
valid: VALIDATION_TYPES.VALID
|
|
})
|
|
})
|
|
it('Should pass if value has same decimals', () => {
|
|
changeMock.target.value = '1.1234'
|
|
|
|
input().simulate(INPUT_EVENT.CHANGE, changeMock)
|
|
expect(numericInputComponent.onValueUpdate).toHaveBeenCalledTimes(1)
|
|
expect(numericInputComponent.onValueUpdate).toHaveBeenCalledWith({
|
|
value: 1.1234,
|
|
pristine: false,
|
|
valid: VALIDATION_TYPES.VALID
|
|
})
|
|
})
|
|
})
|
|
|
|
describe('minDecimals', () => {
|
|
it('Should fail if value has less decimals', () => {
|
|
changeMock.target.value = '1.1'
|
|
|
|
input().simulate(INPUT_EVENT.CHANGE, changeMock)
|
|
expect(numericInputComponent.onValueUpdate).toHaveBeenCalledTimes(1)
|
|
expect(numericInputComponent.onValueUpdate).toHaveBeenCalledWith({
|
|
value: 1.1,
|
|
pristine: false,
|
|
valid: VALIDATION_TYPES.INVALID
|
|
})
|
|
})
|
|
it('Should pass if value has more decimals', () => {
|
|
changeMock.target.value = '1.1234'
|
|
|
|
input().simulate(INPUT_EVENT.CHANGE, changeMock)
|
|
expect(numericInputComponent.onValueUpdate).toHaveBeenCalledTimes(1)
|
|
expect(numericInputComponent.onValueUpdate).toHaveBeenCalledWith({
|
|
value: 1.1234,
|
|
pristine: false,
|
|
valid: VALIDATION_TYPES.VALID
|
|
})
|
|
})
|
|
it('Should pass if value has same decimals', () => {
|
|
changeMock.target.value = '1.12'
|
|
|
|
input().simulate(INPUT_EVENT.CHANGE, changeMock)
|
|
expect(numericInputComponent.onValueUpdate).toHaveBeenCalledTimes(1)
|
|
expect(numericInputComponent.onValueUpdate).toHaveBeenCalledWith({
|
|
value: 1.12,
|
|
pristine: false,
|
|
valid: VALIDATION_TYPES.VALID
|
|
})
|
|
})
|
|
})
|
|
|
|
describe('range [minDecimals, maxDecimals]', () => {
|
|
it('Should fail for: 1.1, if it is outside the range', () => {
|
|
changeMock.target.value = '1.1'
|
|
|
|
input().simulate(INPUT_EVENT.CHANGE, changeMock)
|
|
expect(numericInputComponent.onValueUpdate).toHaveBeenCalledTimes(1)
|
|
expect(numericInputComponent.onValueUpdate).toHaveBeenCalledWith({
|
|
value: 1.1,
|
|
pristine: false,
|
|
valid: VALIDATION_TYPES.INVALID
|
|
})
|
|
})
|
|
it('Should fail for: 1.12345, if it is outside the range', () => {
|
|
changeMock.target.value = '1.12345'
|
|
|
|
input().simulate(INPUT_EVENT.CHANGE, changeMock)
|
|
expect(numericInputComponent.onValueUpdate).toHaveBeenCalledTimes(1)
|
|
expect(numericInputComponent.onValueUpdate).toHaveBeenCalledWith({
|
|
value: 1.12345,
|
|
pristine: false,
|
|
valid: VALIDATION_TYPES.INVALID
|
|
})
|
|
})
|
|
it('Should pass for: 1.12, if it is inside the range', () => {
|
|
changeMock.target.value = '1.12'
|
|
|
|
input().simulate(INPUT_EVENT.CHANGE, changeMock)
|
|
expect(numericInputComponent.onValueUpdate).toHaveBeenCalledTimes(1)
|
|
expect(numericInputComponent.onValueUpdate).toHaveBeenCalledWith({
|
|
value: 1.12,
|
|
pristine: false,
|
|
valid: VALIDATION_TYPES.VALID
|
|
})
|
|
})
|
|
it('Should pass for: 1.123, if it is inside the range', () => {
|
|
changeMock.target.value = '1.123'
|
|
|
|
input().simulate(INPUT_EVENT.CHANGE, changeMock)
|
|
expect(numericInputComponent.onValueUpdate).toHaveBeenCalledTimes(1)
|
|
expect(numericInputComponent.onValueUpdate).toHaveBeenCalledWith({
|
|
value: 1.123,
|
|
pristine: false,
|
|
valid: VALIDATION_TYPES.VALID
|
|
})
|
|
})
|
|
})
|
|
|
|
describe('dot notation', () => {
|
|
it('Should reject float with dot notation', () => {
|
|
numericInputComponent.acceptFloat = false
|
|
numericInputComponent.value = 1
|
|
|
|
keypressMock.key = '.'
|
|
|
|
input().simulate(INPUT_EVENT.KEYPRESS, keypressMock)
|
|
expect(keypressMock.preventDefault).toHaveBeenCalled()
|
|
})
|
|
it('Should accept float with dot notation', () => {
|
|
numericInputComponent.minDecimals = 0
|
|
numericInputComponent.value = 1
|
|
|
|
keypressMock.key = '.'
|
|
|
|
input().simulate(INPUT_EVENT.KEYPRESS, keypressMock)
|
|
expect(keypressMock.preventDefault).toHaveBeenCalledTimes(0)
|
|
expect()
|
|
})
|
|
})
|
|
|
|
describe('scientific notation', () => {
|
|
it('Should reject float with scientific notation', () => {
|
|
numericInputComponent.acceptFloat = false
|
|
numericInputComponent.value = 1
|
|
|
|
keypressMock.key = 'e'
|
|
|
|
input().simulate(INPUT_EVENT.KEYPRESS, keypressMock)
|
|
expect(keypressMock.preventDefault).toHaveBeenCalled()
|
|
})
|
|
it('Should accept float with scientific notation', () => {
|
|
numericInputComponent.value = 1
|
|
|
|
keypressMock.key = 'e'
|
|
|
|
input().simulate(INPUT_EVENT.KEYPRESS, keypressMock)
|
|
expect(keypressMock.preventDefault).toHaveBeenCalledTimes(0)
|
|
})
|
|
})
|
|
})
|
|
})
|