449 lines
11 KiB
JavaScript

import Tooltip from '../../src/index.js';
import '@popperjs/test-utils';
import then from '@popperjs/test-utils/utils/then.js';
import '@popperjs/test-utils/utils/customEventPolyfill.js';
const jasmineWrapper = document.getElementById('jasmineWrapper');
let reference;
let instance;
function createReference() {
reference = document.createElement('div');
reference.style.width = '100px';
reference.style.height = '100px';
reference.style.margin = '100px';
reference.innerText = 'reference';
jasmineWrapper.appendChild(reference);
}
describe('[tooltip.js]', () => {
describe('manual', () => {
beforeEach(() => {
createReference();
});
it('should show tooltip', done => {
instance = new Tooltip(reference, {
title: 'foobar',
});
instance.show();
then(() => {
expect(document.querySelector('.tooltip')).not.toBeNull();
done();
});
});
it('should hide tooltip', done => {
instance = new Tooltip(reference, {
title: 'foobar',
});
instance.show();
then(() => instance.hide());
then(() => {
expect(document.querySelector('.tooltip').style.display).toBe('none');
done();
});
});
it('should toggle (show) tooltip', done => {
instance = new Tooltip(reference, {
title: 'foobar',
});
instance.toggle();
then(() => {
expect(document.querySelector('.tooltip')).not.toBeNull();
done();
});
});
it('should toggle (hide) tooltip', done => {
instance = new Tooltip(reference, {
title: 'foobar',
});
instance.show();
then(() => instance.toggle());
then(() => {
expect(document.querySelector('.tooltip').style.display).toBe('none');
done();
});
});
it('should show, hide and show again a tooltip', done => {
instance = new Tooltip(reference, {
title: 'foobar',
});
instance.show();
then(() => instance.hide());
then(() => instance.show());
then(() => {
expect(document.querySelector('.tooltip')).not.toBeNull();
done();
});
});
it('should dispose tooltip', done => {
instance = new Tooltip(reference, {
title: 'foobar',
});
instance.show();
then(() => instance.dispose());
then(() => {
expect(document.querySelector('.tooltip')).toBeNull();
});
then(() => {
reference.click();
});
then(() => {
expect(document.querySelector('.tooltip')).toBeNull();
done();
});
});
it('should dispose tooltip despite never being shown', done => {
instance = new Tooltip(reference, {
title: 'foobar',
});
instance.dispose();
then(() => {
expect(document.querySelector('.tooltip')).toBeNull();
});
then(() => {
reference.dispatchEvent(new CustomEvent('mouseenter'));
});
then(() => {
expect(document.querySelector('.tooltip')).toBeNull();
done();
});
});
});
describe('container', () => {
beforeEach(() => {
createReference();
});
it('should show tooltip as child of body', done => {
instance = new Tooltip(reference, {
title: 'foobar',
container: 'body',
});
instance.show();
then(() => {
expect(document.querySelector('.tooltip').parentNode).toBe(
document.body
);
instance.dispose();
done();
});
});
});
describe('content', () => {
beforeEach(() => {
createReference();
});
it('should show text tooltip', done => {
instance = new Tooltip(reference, {
title: 'foobar',
});
instance.show();
then(() => {
expect(
document.querySelector('.tooltip .tooltip-inner').textContent
).toBe('foobar');
done();
});
});
it('should show HTML tooltip', done => {
instance = new Tooltip(reference, {
title: '<strong>foobar</strong>',
html: true,
});
instance.show();
then(() => {
expect(
document.querySelector('.tooltip .tooltip-inner').innerHTML
).toBe('<strong>foobar</strong>');
done();
});
});
it('should show stripped out HTML tooltip', done => {
instance = new Tooltip(reference, {
title: '<strong>foobar</strong>',
html: true,
});
instance.show();
then(() => {
expect(
document.querySelector('.tooltip .tooltip-inner').textContent
).toBe('foobar');
done();
});
});
it('should use a DOM node as tooltip content', done => {
const content = document.createElement('div');
content.innerText = 'foobar';
instance = new Tooltip(reference, {
title: content,
html: true,
});
instance.show();
then(() => {
expect(
document.querySelector('.tooltip .tooltip-inner').innerHTML
).toBe('<div>foobar</div>');
done();
});
});
it('should use a document fragment as tooltip content', done => {
const content = document.createDocumentFragment();
const inner = document.createElement('div');
inner.innerText = 'test';
content.appendChild(inner);
instance = new Tooltip(reference, {
title: content,
html: true,
});
instance.show();
then(() => {
expect(
document.querySelector('.tooltip .tooltip-inner').innerHTML
).toBe('<div>test</div>');
done();
});
});
it('should use a function result as tooltip content', done => {
instance = new Tooltip(reference, {
title: () => 'foobar',
});
instance.show();
then(() => {
expect(
document.querySelector('.tooltip .tooltip-inner').textContent
).toBe('foobar');
done();
});
});
it('should use a custom template with empty leading&trailing spaces', done => {
instance = new Tooltip(reference, {
title: 'foobar',
template: `
<div class="tooltip" role="tooltip">
<div class="tooltip-arrow"></div>
<div class="foobar"><div class="tooltip-inner"></div></div>
</div>
`,
});
instance.show();
then(() => {
expect(document.querySelector('.tooltip .foobar').textContent).toBe(
'foobar'
);
done();
});
});
});
describe('events', () => {
beforeEach(() => {
createReference();
});
afterEach(() => {
instance.dispose();
jasmineWrapper.innerHTML = '';
});
it('should show a tooltip when hovered', done => {
instance = new Tooltip(reference, {
title: 'foobar',
trigger: 'hover',
});
expect(document.querySelector('.tooltip')).toBeNull();
reference.dispatchEvent(new CustomEvent('mouseenter'));
then(() => {
expect(document.querySelector('.tooltip')).not.toBeNull();
done();
});
});
it('should hide a tooltip on reference mouseleave', done => {
instance = new Tooltip(reference, {
title: 'foobar',
trigger: 'hover',
});
expect(document.querySelector('.tooltip')).toBeNull();
reference.dispatchEvent(new CustomEvent('mouseenter'));
then(() => reference.dispatchEvent(new CustomEvent('mouseleave')), 200);
then(() => {
expect(document.querySelector('.tooltip').style.display).toBe('none');
done();
}, 200);
});
it('should hide a tooltip on tooltip mouseleave', done => {
instance = new Tooltip(reference, {
title: 'foobar',
trigger: 'hover',
});
expect(document.querySelector('.tooltip')).toBeNull();
reference.dispatchEvent(new CustomEvent('mouseenter'));
then(() => reference.dispatchEvent(new CustomEvent('mouseleave')));
then(() =>
document
.querySelector('.tooltip')
.dispatchEvent(new CustomEvent('mouseenter'))
);
then(() =>
document
.querySelector('.tooltip')
.dispatchEvent(new CustomEvent('mouseleave'))
);
then(() => {
expect(document.querySelector('.tooltip').style.display).toBe('none');
done();
}, 200);
});
it('should not hide a tooltip if user mouseenter tooltip and then mouseenter reference element again', done => {
instance = new Tooltip(reference, {
title: 'foobar',
trigger: 'hover',
});
expect(document.querySelector('.tooltip')).toBeNull();
reference.dispatchEvent(new CustomEvent('mouseenter'));
then(() => reference.dispatchEvent(new CustomEvent('mouseleave')));
then(() =>
document
.querySelector('.tooltip')
.dispatchEvent(new CustomEvent('mouseenter'))
);
then(() =>
document
.querySelector('.tooltip')
.dispatchEvent(new CustomEvent('mouseleave'))
);
then(() => reference.dispatchEvent(new CustomEvent('mouseenter')));
then(() => {
expect(document.querySelector('.tooltip').style.display).toBe('');
done();
}, 200);
});
it('should show a tooltip on click', done => {
instance = new Tooltip(reference, {
title: 'foobar',
trigger: 'click',
});
expect(document.querySelector('.tooltip')).toBeNull();
reference.dispatchEvent(new CustomEvent('click'));
then(() => {
expect(document.querySelector('.tooltip')).not.toBeNull();
done();
});
});
it('should not show tooltip if mouse leaves reference before tooltip is shown', done => {
instance = new Tooltip(reference, {
title: 'foobar',
trigger: 'hover',
delay: { show: 1000, hide: 0 },
});
expect(document.querySelector('.tooltip')).toBeNull();
reference.dispatchEvent(new CustomEvent('mouseenter'));
reference.dispatchEvent(new CustomEvent('mouseleave'));
then(() => {
expect(document.querySelector('.tooltip')).toBeNull();
done();
});
});
it('should hide a tooltip on click while open', done => {
instance = new Tooltip(reference, {
title: 'foobar',
trigger: 'click',
});
expect(document.querySelector('.tooltip')).toBeNull();
reference.dispatchEvent(new CustomEvent('click'));
then(() => reference.dispatchEvent(new CustomEvent('click')));
then(() => {
expect(document.querySelector('.tooltip').style.display).toBe('none');
done();
});
});
});
describe('options', () => {
beforeEach(() => {
createReference();
});
it('should proxy the `options.offset` value to the Popper.js instance', done => {
instance = new Tooltip(reference, {
title: 'test',
offset: 10,
}).show();
expect(instance._popperOptions.modifiers.offset.offset).toBe(10);
done();
});
});
});