blob: 73a8da0365a5f6c3ea79a3cfbdd2e05ffe963a70 [file] [edit]
import Range from '../../src/range.js'
import { clearFixture, createEvent, getFixture } from '../helpers/fixture.js'
describe('Range', () => {
let fixtureEl
beforeAll(() => {
fixtureEl = getFixture()
})
afterEach(() => {
clearFixture()
})
const getRangeHtml = (wrapperAttributes = '', inputAttributes = '') => {
return `
<div class="form-range" ${wrapperAttributes}>
<input type="range" class="form-range-input" min="0" max="100" value="50" ${inputAttributes}>
</div>
`
}
describe('VERSION', () => {
it('should return plugin version', () => {
expect(Range.VERSION).toEqual(jasmine.any(String))
})
})
describe('DATA_KEY', () => {
it('should return plugin data key', () => {
expect(Range.DATA_KEY).toEqual('bs.range')
})
})
describe('Default', () => {
it('should return default config', () => {
expect(Range.Default).toEqual(jasmine.any(Object))
expect(Range.Default.bubble).toBeFalse()
})
})
describe('DefaultType', () => {
it('should return default type config', () => {
expect(Range.DefaultType).toEqual(jasmine.any(Object))
})
})
describe('constructor', () => {
it('should take care of element either passed as a CSS selector or DOM element', () => {
fixtureEl.innerHTML = getRangeHtml()
const rangeEl = fixtureEl.querySelector('.form-range')
const rangeBySelector = new Range('.form-range')
expect(rangeBySelector._element).toEqual(rangeEl)
rangeBySelector.dispose()
const rangeByElement = new Range(rangeEl)
expect(rangeByElement._element).toEqual(rangeEl)
})
it('should find the range input inside the wrapper', () => {
fixtureEl.innerHTML = getRangeHtml()
const rangeEl = fixtureEl.querySelector('.form-range')
const inputEl = fixtureEl.querySelector('.form-range-input')
const range = new Range(rangeEl)
expect(range._input).toEqual(inputEl)
})
it('should set the --bs-range-fill custom property on init', () => {
fixtureEl.innerHTML = getRangeHtml()
const rangeEl = fixtureEl.querySelector('.form-range')
new Range(rangeEl) // eslint-disable-line no-new
expect(rangeEl.style.getPropertyValue('--bs-range-fill')).toEqual('0.5')
})
it('should honor min/max when computing the fill ratio', () => {
fixtureEl.innerHTML = `
<div class="form-range">
<input type="range" class="form-range-input" min="0" max="200" value="50">
</div>
`
const rangeEl = fixtureEl.querySelector('.form-range')
new Range(rangeEl) // eslint-disable-line no-new
expect(rangeEl.style.getPropertyValue('--bs-range-fill')).toEqual('0.25')
})
it('should do nothing when there is no range input', () => {
fixtureEl.innerHTML = '<div class="form-range"></div>'
const rangeEl = fixtureEl.querySelector('.form-range')
const range = new Range(rangeEl)
expect(range._input).toBeNull()
})
})
describe('update', () => {
it('should update the --bs-range-fill custom property on input', () => {
fixtureEl.innerHTML = getRangeHtml()
const rangeEl = fixtureEl.querySelector('.form-range')
const inputEl = fixtureEl.querySelector('.form-range-input')
new Range(rangeEl) // eslint-disable-line no-new
inputEl.value = '75'
inputEl.dispatchEvent(createEvent('input'))
expect(rangeEl.style.getPropertyValue('--bs-range-fill')).toEqual('0.75')
})
})
describe('bubble', () => {
it('should create a tooltip-based value bubble when enabled', () => {
fixtureEl.innerHTML = getRangeHtml('data-bs-bubble')
const rangeEl = fixtureEl.querySelector('.form-range')
new Range(rangeEl) // eslint-disable-line no-new
const bubble = fixtureEl.querySelector('.form-range-bubble')
expect(bubble).not.toBeNull()
expect(bubble).toHaveClass('tooltip')
expect(bubble.querySelector('.tooltip-inner').textContent).toEqual('50')
})
it('should not create a bubble by default', () => {
fixtureEl.innerHTML = getRangeHtml()
const rangeEl = fixtureEl.querySelector('.form-range')
new Range(rangeEl) // eslint-disable-line no-new
expect(fixtureEl.querySelector('.form-range-bubble')).toBeNull()
})
it('should update the bubble text on input', () => {
fixtureEl.innerHTML = getRangeHtml('data-bs-bubble')
const rangeEl = fixtureEl.querySelector('.form-range')
const inputEl = fixtureEl.querySelector('.form-range-input')
new Range(rangeEl) // eslint-disable-line no-new
inputEl.value = '80'
inputEl.dispatchEvent(createEvent('input'))
expect(fixtureEl.querySelector('.tooltip-inner').textContent).toEqual('80')
})
it('should format the bubble text with a custom formatter', () => {
fixtureEl.innerHTML = getRangeHtml('data-bs-bubble')
const rangeEl = fixtureEl.querySelector('.form-range')
new Range(rangeEl, { formatter: value => `${value}%` }) // eslint-disable-line no-new
expect(fixtureEl.querySelector('.tooltip-inner').textContent).toEqual('50%')
})
})
describe('ticks', () => {
const getTicksHtml = () => {
return `
<div class="form-range">
<input type="range" class="form-range-input" min="0" max="100" value="50" list="ticksList">
</div>
<datalist id="ticksList">
<option value="0" label="Low"></option>
<option value="10"></option>
<option value="100" label="High"></option>
</datalist>
`
}
it('should render a tick for each datalist option', () => {
fixtureEl.innerHTML = getTicksHtml()
const rangeEl = fixtureEl.querySelector('.form-range')
new Range(rangeEl) // eslint-disable-line no-new
const ticks = fixtureEl.querySelectorAll('.form-range-tick')
expect(ticks.length).toEqual(3)
})
it('should place each tick on a grid line via grid-template-columns (handles uneven values)', () => {
fixtureEl.innerHTML = getTicksHtml()
const rangeEl = fixtureEl.querySelector('.form-range')
new Range(rangeEl) // eslint-disable-line no-new
// datalist values 0/10/100 -> gaps between 0, .1, 1, and 1
const ticksEl = fixtureEl.querySelector('.form-range-ticks')
expect(ticksEl.style.gridTemplateColumns).toEqual('0fr 0.1fr 0.9fr 0fr')
const ticks = fixtureEl.querySelectorAll('.form-range-tick')
expect(ticks[0].style.gridColumnStart).toEqual('2')
expect(ticks[1].style.gridColumnStart).toEqual('3')
expect(ticks[2].style.gridColumnStart).toEqual('4')
})
it('should render labels from the option label only', () => {
fixtureEl.innerHTML = getTicksHtml()
const rangeEl = fixtureEl.querySelector('.form-range')
new Range(rangeEl) // eslint-disable-line no-new
const labels = fixtureEl.querySelectorAll('.form-range-tick-label')
expect(labels.length).toEqual(2)
expect(labels[0].textContent).toEqual('Low')
expect(labels[1].textContent).toEqual('High')
})
it('should do nothing when there is no linked datalist', () => {
fixtureEl.innerHTML = getRangeHtml()
const rangeEl = fixtureEl.querySelector('.form-range')
const range = new Range(rangeEl)
expect(range._ticks).toBeNull()
expect(fixtureEl.querySelector('.form-range-ticks')).toBeNull()
})
})
describe('events', () => {
it('should trigger a changed event with the current value', () => {
return new Promise(resolve => {
fixtureEl.innerHTML = getRangeHtml()
const rangeEl = fixtureEl.querySelector('.form-range')
const inputEl = fixtureEl.querySelector('.form-range-input')
new Range(rangeEl) // eslint-disable-line no-new
inputEl.addEventListener('changed.bs.range', event => {
expect(event.value).toEqual(90)
resolve()
})
inputEl.value = '90'
inputEl.dispatchEvent(createEvent('input'))
})
})
})
describe('dispose', () => {
it('should dispose the instance and remove decorations', () => {
fixtureEl.innerHTML = getRangeHtml('data-bs-bubble')
const rangeEl = fixtureEl.querySelector('.form-range')
const range = new Range(rangeEl)
expect(Range.getInstance(rangeEl)).not.toBeNull()
expect(fixtureEl.querySelector('.form-range-bubble')).not.toBeNull()
range.dispose()
expect(Range.getInstance(rangeEl)).toBeNull()
expect(fixtureEl.querySelector('.form-range-bubble')).toBeNull()
})
})
describe('getInstance', () => {
it('should return range instance', () => {
fixtureEl.innerHTML = getRangeHtml()
const rangeEl = fixtureEl.querySelector('.form-range')
const range = new Range(rangeEl)
expect(Range.getInstance(rangeEl)).toEqual(range)
expect(Range.getInstance(rangeEl)).toBeInstanceOf(Range)
})
it('should return null when there is no instance', () => {
fixtureEl.innerHTML = '<div></div>'
const div = fixtureEl.querySelector('div')
expect(Range.getInstance(div)).toBeNull()
})
})
describe('getOrCreateInstance', () => {
it('should return existing instance', () => {
fixtureEl.innerHTML = getRangeHtml()
const rangeEl = fixtureEl.querySelector('.form-range')
const range = new Range(rangeEl)
expect(Range.getOrCreateInstance(rangeEl)).toEqual(range)
expect(Range.getOrCreateInstance(rangeEl)).toBeInstanceOf(Range)
})
it('should create new instance when none exists', () => {
fixtureEl.innerHTML = getRangeHtml()
const rangeEl = fixtureEl.querySelector('.form-range')
expect(Range.getInstance(rangeEl)).toBeNull()
expect(Range.getOrCreateInstance(rangeEl)).toBeInstanceOf(Range)
})
})
})