aboutsummaryrefslogtreecommitdiff
path: root/js/tests/unit/util
diff options
context:
space:
mode:
Diffstat (limited to 'js/tests/unit/util')
-rw-r--r--js/tests/unit/util/backdrop.spec.js441
-rw-r--r--js/tests/unit/util/component-functions.spec.js40
-rw-r--r--js/tests/unit/util/config.spec.js166
-rw-r--r--js/tests/unit/util/focustrap.spec.js266
-rw-r--r--js/tests/unit/util/index.spec.js499
-rw-r--r--js/tests/unit/util/sanitizer.spec.js84
-rw-r--r--js/tests/unit/util/scrollbar.spec.js146
-rw-r--r--js/tests/unit/util/swipe.spec.js230
-rw-r--r--js/tests/unit/util/template-factory.spec.js59
9 files changed, 1057 insertions, 874 deletions
diff --git a/js/tests/unit/util/backdrop.spec.js b/js/tests/unit/util/backdrop.spec.js
index 818ddf221..0faaac6a5 100644
--- a/js/tests/unit/util/backdrop.spec.js
+++ b/js/tests/unit/util/backdrop.spec.js
@@ -1,6 +1,6 @@
-import Backdrop from '../../../src/util/backdrop'
-import { getTransitionDurationFromElement } from '../../../src/util/index'
-import { clearFixture, getFixture } from '../../helpers/fixture'
+import Backdrop from '../../../src/util/backdrop.js'
+import { getTransitionDurationFromElement } from '../../../src/util/index.js'
+import { clearFixture, getFixture } from '../../helpers/fixture.js'
const CLASS_BACKDROP = '.modal-backdrop'
const CLASS_NAME_FADE = 'fade'
@@ -23,270 +23,297 @@ describe('Backdrop', () => {
})
describe('show', () => {
- it('if it is "shown", should append the backdrop html once, on show, and contain "show" class', done => {
- const instance = new Backdrop({
- isVisible: true,
- isAnimated: false
- })
- const getElements = () => document.querySelectorAll(CLASS_BACKDROP)
+ it('should append the backdrop html once on show and include the "show" class if it is "shown"', () => {
+ return new Promise(resolve => {
+ const instance = new Backdrop({
+ isVisible: true,
+ isAnimated: false
+ })
+ const getElements = () => document.querySelectorAll(CLASS_BACKDROP)
- expect(getElements().length).toEqual(0)
+ expect(getElements()).toHaveSize(0)
- instance.show()
- instance.show(() => {
- expect(getElements().length).toEqual(1)
- for (const el of getElements()) {
- expect(el.classList.contains(CLASS_NAME_SHOW)).toEqual(true)
- }
+ instance.show()
+ instance.show(() => {
+ expect(getElements()).toHaveSize(1)
+ for (const el of getElements()) {
+ expect(el).toHaveClass(CLASS_NAME_SHOW)
+ }
- done()
+ resolve()
+ })
})
})
- it('if it is not "shown", should not append the backdrop html', done => {
- const instance = new Backdrop({
- isVisible: false,
- isAnimated: true
- })
- const getElements = () => document.querySelectorAll(CLASS_BACKDROP)
+ it('should not append the backdrop html if it is not "shown"', () => {
+ return new Promise(resolve => {
+ const instance = new Backdrop({
+ isVisible: false,
+ isAnimated: true
+ })
+ const getElements = () => document.querySelectorAll(CLASS_BACKDROP)
- expect(getElements().length).toEqual(0)
- instance.show(() => {
- expect(getElements().length).toEqual(0)
- done()
+ expect(getElements()).toHaveSize(0)
+ instance.show(() => {
+ expect(getElements()).toHaveSize(0)
+ resolve()
+ })
})
})
- it('if it is "shown" and "animated", should append the backdrop html once, and contain "fade" class', done => {
- const instance = new Backdrop({
- isVisible: true,
- isAnimated: true
- })
- const getElements = () => document.querySelectorAll(CLASS_BACKDROP)
+ it('should append the backdrop html once and include the "fade" class if it is "shown" and "animated"', () => {
+ return new Promise(resolve => {
+ const instance = new Backdrop({
+ isVisible: true,
+ isAnimated: true
+ })
+ const getElements = () => document.querySelectorAll(CLASS_BACKDROP)
- expect(getElements().length).toEqual(0)
+ expect(getElements()).toHaveSize(0)
- instance.show(() => {
- expect(getElements().length).toEqual(1)
- for (const el of getElements()) {
- expect(el.classList.contains(CLASS_NAME_FADE)).toEqual(true)
- }
+ instance.show(() => {
+ expect(getElements()).toHaveSize(1)
+ for (const el of getElements()) {
+ expect(el).toHaveClass(CLASS_NAME_FADE)
+ }
- done()
+ resolve()
+ })
})
})
})
describe('hide', () => {
- it('should remove the backdrop html', done => {
- const instance = new Backdrop({
- isVisible: true,
- isAnimated: true
- })
+ it('should remove the backdrop html', () => {
+ return new Promise(resolve => {
+ const instance = new Backdrop({
+ isVisible: true,
+ isAnimated: true
+ })
- const getElements = () => document.body.querySelectorAll(CLASS_BACKDROP)
+ const getElements = () => document.body.querySelectorAll(CLASS_BACKDROP)
- expect(getElements().length).toEqual(0)
- instance.show(() => {
- expect(getElements().length).toEqual(1)
- instance.hide(() => {
- expect(getElements().length).toEqual(0)
- done()
+ expect(getElements()).toHaveSize(0)
+ instance.show(() => {
+ expect(getElements()).toHaveSize(1)
+ instance.hide(() => {
+ expect(getElements()).toHaveSize(0)
+ resolve()
+ })
})
})
})
- it('should remove "show" class', done => {
- const instance = new Backdrop({
- isVisible: true,
- isAnimated: true
- })
- const elem = instance._getElement()
+ it('should remove the "show" class', () => {
+ return new Promise(resolve => {
+ const instance = new Backdrop({
+ isVisible: true,
+ isAnimated: true
+ })
+ const elem = instance._getElement()
- instance.show()
- instance.hide(() => {
- expect(elem.classList.contains(CLASS_NAME_SHOW)).toEqual(false)
- done()
+ instance.show()
+ instance.hide(() => {
+ expect(elem).not.toHaveClass(CLASS_NAME_SHOW)
+ resolve()
+ })
})
})
- it('if it is not "shown", should not try to remove Node on remove method', done => {
- const instance = new Backdrop({
- isVisible: false,
- isAnimated: true
- })
- const getElements = () => document.querySelectorAll(CLASS_BACKDROP)
- const spy = spyOn(instance, 'dispose').and.callThrough()
+ it('should not try to remove Node on remove method if it is not "shown"', () => {
+ return new Promise(resolve => {
+ const instance = new Backdrop({
+ isVisible: false,
+ isAnimated: true
+ })
+ const getElements = () => document.querySelectorAll(CLASS_BACKDROP)
+ const spy = spyOn(instance, 'dispose').and.callThrough()
- expect(getElements().length).toEqual(0)
- expect(instance._isAppended).toEqual(false)
- instance.show(() => {
- instance.hide(() => {
- expect(getElements().length).toEqual(0)
- expect(spy).not.toHaveBeenCalled()
- expect(instance._isAppended).toEqual(false)
- done()
+ expect(getElements()).toHaveSize(0)
+ expect(instance._isAppended).toBeFalse()
+ instance.show(() => {
+ instance.hide(() => {
+ expect(getElements()).toHaveSize(0)
+ expect(spy).not.toHaveBeenCalled()
+ expect(instance._isAppended).toBeFalse()
+ resolve()
+ })
})
})
})
- it('should not error if the backdrop no longer has a parent', done => {
- fixtureEl.innerHTML = '<div id="wrapper"></div>'
+ it('should not error if the backdrop no longer has a parent', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = '<div id="wrapper"></div>'
- const wrapper = fixtureEl.querySelector('#wrapper')
- const instance = new Backdrop({
- isVisible: true,
- isAnimated: true,
- rootElement: wrapper
- })
+ const wrapper = fixtureEl.querySelector('#wrapper')
+ const instance = new Backdrop({
+ isVisible: true,
+ isAnimated: true,
+ rootElement: wrapper
+ })
- const getElements = () => document.querySelectorAll(CLASS_BACKDROP)
+ const getElements = () => document.querySelectorAll(CLASS_BACKDROP)
- instance.show(() => {
- wrapper.remove()
- instance.hide(() => {
- expect(getElements().length).toEqual(0)
- done()
+ instance.show(() => {
+ wrapper.remove()
+ instance.hide(() => {
+ expect(getElements()).toHaveSize(0)
+ resolve()
+ })
})
})
})
})
describe('click callback', () => {
- it('it should execute callback on click', done => {
- const spy = jasmine.createSpy('spy')
+ it('should execute callback on click', () => {
+ return new Promise(resolve => {
+ const spy = jasmine.createSpy('spy')
- const instance = new Backdrop({
- isVisible: true,
- isAnimated: false,
- clickCallback: () => spy()
- })
- const endTest = () => {
- setTimeout(() => {
- expect(spy).toHaveBeenCalled()
- done()
- }, 10)
- }
-
- instance.show(() => {
- const clickEvent = document.createEvent('MouseEvents')
- clickEvent.initEvent('mousedown', true, true)
- document.querySelector(CLASS_BACKDROP).dispatchEvent(clickEvent)
- endTest()
- })
- })
- })
-
- describe('animation callbacks', () => {
- it('if it is animated, should show and hide backdrop after counting transition duration', done => {
- const instance = new Backdrop({
- isVisible: true,
- isAnimated: true
- })
- const spy2 = jasmine.createSpy('spy2')
-
- const execDone = () => {
- setTimeout(() => {
- expect(spy2).toHaveBeenCalledTimes(2)
- done()
- }, 10)
- }
-
- instance.show(spy2)
- instance.hide(() => {
- spy2()
- execDone()
- })
- expect(spy2).not.toHaveBeenCalled()
- })
+ const instance = new Backdrop({
+ isVisible: true,
+ isAnimated: false,
+ clickCallback: () => spy()
+ })
+ const endTest = () => {
+ setTimeout(() => {
+ expect(spy).toHaveBeenCalled()
+ resolve()
+ }, 10)
+ }
- it('if it is not animated, should show and hide backdrop without delay', done => {
- const spy = jasmine.createSpy('spy', getTransitionDurationFromElement)
- const instance = new Backdrop({
- isVisible: true,
- isAnimated: false
+ instance.show(() => {
+ const clickEvent = new Event('mousedown', { bubbles: true, cancelable: true })
+ document.querySelector(CLASS_BACKDROP).dispatchEvent(clickEvent)
+ endTest()
+ })
})
- const spy2 = jasmine.createSpy('spy2')
-
- instance.show(spy2)
- instance.hide(spy2)
-
- setTimeout(() => {
- expect(spy2).toHaveBeenCalled()
- expect(spy).not.toHaveBeenCalled()
- done()
- }, 10)
})
- it('if it is not "shown", should not call delay callbacks', done => {
- const instance = new Backdrop({
- isVisible: false,
- isAnimated: true
+ describe('animation callbacks', () => {
+ it('should show and hide backdrop after counting transition duration if it is animated', () => {
+ return new Promise(resolve => {
+ const instance = new Backdrop({
+ isVisible: true,
+ isAnimated: true
+ })
+ const spy2 = jasmine.createSpy('spy2')
+
+ const execDone = () => {
+ setTimeout(() => {
+ expect(spy2).toHaveBeenCalledTimes(2)
+ resolve()
+ }, 10)
+ }
+
+ instance.show(spy2)
+ instance.hide(() => {
+ spy2()
+ execDone()
+ })
+ expect(spy2).not.toHaveBeenCalled()
+ })
})
- const spy = jasmine.createSpy('spy', getTransitionDurationFromElement)
- instance.show()
- instance.hide(() => {
- expect(spy).not.toHaveBeenCalled()
- done()
- })
- })
- })
- describe('Config', () => {
- describe('rootElement initialization', () => {
- it('Should be appended on "document.body" by default', done => {
- const instance = new Backdrop({
- isVisible: true
- })
- const getElement = () => document.querySelector(CLASS_BACKDROP)
- instance.show(() => {
- expect(getElement().parentElement).toEqual(document.body)
- done()
+ it('should show and hide backdrop without a delay if it is not animated', () => {
+ return new Promise(resolve => {
+ const spy = jasmine.createSpy('spy', getTransitionDurationFromElement)
+ const instance = new Backdrop({
+ isVisible: true,
+ isAnimated: false
+ })
+ const spy2 = jasmine.createSpy('spy2')
+
+ instance.show(spy2)
+ instance.hide(spy2)
+
+ setTimeout(() => {
+ expect(spy2).toHaveBeenCalled()
+ expect(spy).not.toHaveBeenCalled()
+ resolve()
+ }, 10)
})
})
- it('Should find the rootElement if passed as a string', done => {
- const instance = new Backdrop({
- isVisible: true,
- rootElement: 'body'
- })
- const getElement = () => document.querySelector(CLASS_BACKDROP)
- instance.show(() => {
- expect(getElement().parentElement).toEqual(document.body)
- done()
+ it('should not call delay callbacks if it is not "shown"', () => {
+ return new Promise(resolve => {
+ const instance = new Backdrop({
+ isVisible: false,
+ isAnimated: true
+ })
+ const spy = jasmine.createSpy('spy', getTransitionDurationFromElement)
+
+ instance.show()
+ instance.hide(() => {
+ expect(spy).not.toHaveBeenCalled()
+ resolve()
+ })
})
})
+ })
- it('Should appended on any element given by the proper config', done => {
- fixtureEl.innerHTML = [
- '<div id="wrapper">',
- '</div>'
- ].join('')
+ describe('Config', () => {
+ describe('rootElement initialization', () => {
+ it('should be appended on "document.body" by default', () => {
+ return new Promise(resolve => {
+ const instance = new Backdrop({
+ isVisible: true
+ })
+ const getElement = () => document.querySelector(CLASS_BACKDROP)
+ instance.show(() => {
+ expect(getElement().parentElement).toEqual(document.body)
+ resolve()
+ })
+ })
+ })
- const wrapper = fixtureEl.querySelector('#wrapper')
- const instance = new Backdrop({
- isVisible: true,
- rootElement: wrapper
+ it('should find the rootElement if passed as a string', () => {
+ return new Promise(resolve => {
+ const instance = new Backdrop({
+ isVisible: true,
+ rootElement: 'body'
+ })
+ const getElement = () => document.querySelector(CLASS_BACKDROP)
+ instance.show(() => {
+ expect(getElement().parentElement).toEqual(document.body)
+ resolve()
+ })
+ })
})
- const getElement = () => document.querySelector(CLASS_BACKDROP)
- instance.show(() => {
- expect(getElement().parentElement).toEqual(wrapper)
- done()
+
+ it('should be appended on any element given by the proper config', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = '<div id="wrapper"></div>'
+
+ const wrapper = fixtureEl.querySelector('#wrapper')
+ const instance = new Backdrop({
+ isVisible: true,
+ rootElement: wrapper
+ })
+ const getElement = () => document.querySelector(CLASS_BACKDROP)
+ instance.show(() => {
+ expect(getElement().parentElement).toEqual(wrapper)
+ resolve()
+ })
+ })
})
})
- })
- describe('ClassName', () => {
- it('Should be able to have different classNames than default', done => {
- const instance = new Backdrop({
- isVisible: true,
- className: 'foo'
- })
- const getElement = () => document.querySelector('.foo')
- instance.show(() => {
- expect(getElement()).toEqual(instance._getElement())
- instance.dispose()
- done()
+ describe('ClassName', () => {
+ it('should allow configuring className', () => {
+ return new Promise(resolve => {
+ const instance = new Backdrop({
+ isVisible: true,
+ className: 'foo'
+ })
+ const getElement = () => document.querySelector('.foo')
+ instance.show(() => {
+ expect(getElement()).toEqual(instance._getElement())
+ instance.dispose()
+ resolve()
+ })
+ })
})
})
})
diff --git a/js/tests/unit/util/component-functions.spec.js b/js/tests/unit/util/component-functions.spec.js
index edaedd32e..ce83785e2 100644
--- a/js/tests/unit/util/component-functions.spec.js
+++ b/js/tests/unit/util/component-functions.spec.js
@@ -1,8 +1,6 @@
-/* Test helpers */
-
-import { clearFixture, createEvent, getFixture } from '../../helpers/fixture'
-import { enableDismissTrigger } from '../../../src/util/component-functions'
-import BaseComponent from '../../../src/base-component'
+import BaseComponent from '../../../src/base-component.js'
+import { enableDismissTrigger } from '../../../src/util/component-functions.js'
+import { clearFixture, createEvent, getFixture } from '../../helpers/fixture.js'
class DummyClass2 extends BaseComponent {
static get NAME() {
@@ -33,12 +31,12 @@ describe('Plugin functions', () => {
it('should get Plugin and execute the given method, when a click occurred on data-bs-dismiss="PluginName"', () => {
fixtureEl.innerHTML = [
'<div id="foo" class="test">',
- ' <button type="button" data-bs-dismiss="test" data-bs-target="#foo"></button>',
+ ' <button type="button" data-bs-dismiss="test" data-bs-target="#foo"></button>',
'</div>'
].join('')
- spyOn(DummyClass2, 'getOrCreateInstance').and.callThrough()
- spyOn(DummyClass2.prototype, 'testMethod')
+ const spyGet = spyOn(DummyClass2, 'getOrCreateInstance').and.callThrough()
+ const spyTest = spyOn(DummyClass2.prototype, 'testMethod')
const componentWrapper = fixtureEl.querySelector('#foo')
const btnClose = fixtureEl.querySelector('[data-bs-dismiss="test"]')
const event = createEvent('click')
@@ -46,19 +44,19 @@ describe('Plugin functions', () => {
enableDismissTrigger(DummyClass2, 'testMethod')
btnClose.dispatchEvent(event)
- expect(DummyClass2.getOrCreateInstance).toHaveBeenCalledWith(componentWrapper)
- expect(DummyClass2.prototype.testMethod).toHaveBeenCalled()
+ expect(spyGet).toHaveBeenCalledWith(componentWrapper)
+ expect(spyTest).toHaveBeenCalled()
})
it('if data-bs-dismiss="PluginName" hasn\'t got "data-bs-target", "getOrCreateInstance" has to be initialized by closest "plugin.Name" class', () => {
fixtureEl.innerHTML = [
'<div id="foo" class="test">',
- ' <button type="button" data-bs-dismiss="test"></button>',
+ ' <button type="button" data-bs-dismiss="test"></button>',
'</div>'
].join('')
- spyOn(DummyClass2, 'getOrCreateInstance').and.callThrough()
- spyOn(DummyClass2.prototype, 'hide')
+ const spyGet = spyOn(DummyClass2, 'getOrCreateInstance').and.callThrough()
+ const spyHide = spyOn(DummyClass2.prototype, 'hide')
const componentWrapper = fixtureEl.querySelector('#foo')
const btnClose = fixtureEl.querySelector('[data-bs-dismiss="test"]')
const event = createEvent('click')
@@ -66,31 +64,31 @@ describe('Plugin functions', () => {
enableDismissTrigger(DummyClass2)
btnClose.dispatchEvent(event)
- expect(DummyClass2.getOrCreateInstance).toHaveBeenCalledWith(componentWrapper)
- expect(DummyClass2.prototype.hide).toHaveBeenCalled()
+ expect(spyGet).toHaveBeenCalledWith(componentWrapper)
+ expect(spyHide).toHaveBeenCalled()
})
it('if data-bs-dismiss="PluginName" is disabled, must not trigger function', () => {
fixtureEl.innerHTML = [
'<div id="foo" class="test">',
- ' <button type="button" disabled data-bs-dismiss="test"></button>',
+ ' <button type="button" disabled data-bs-dismiss="test"></button>',
'</div>'
].join('')
- spyOn(DummyClass2, 'getOrCreateInstance').and.callThrough()
+ const spy = spyOn(DummyClass2, 'getOrCreateInstance').and.callThrough()
const btnClose = fixtureEl.querySelector('[data-bs-dismiss="test"]')
const event = createEvent('click')
enableDismissTrigger(DummyClass2)
btnClose.dispatchEvent(event)
- expect(DummyClass2.getOrCreateInstance).not.toHaveBeenCalled()
+ expect(spy).not.toHaveBeenCalled()
})
it('should prevent default when the trigger is <a> or <area>', () => {
fixtureEl.innerHTML = [
'<div id="foo" class="test">',
- ' <a type="button" data-bs-dismiss="test"></a>',
+ ' <a type="button" data-bs-dismiss="test"></a>',
'</div>'
].join('')
@@ -98,11 +96,11 @@ describe('Plugin functions', () => {
const event = createEvent('click')
enableDismissTrigger(DummyClass2)
- spyOn(Event.prototype, 'preventDefault').and.callThrough()
+ const spy = spyOn(Event.prototype, 'preventDefault').and.callThrough()
btnClose.dispatchEvent(event)
- expect(Event.prototype.preventDefault).toHaveBeenCalled()
+ expect(spy).toHaveBeenCalled()
})
})
})
diff --git a/js/tests/unit/util/config.spec.js b/js/tests/unit/util/config.spec.js
new file mode 100644
index 000000000..93987a74a
--- /dev/null
+++ b/js/tests/unit/util/config.spec.js
@@ -0,0 +1,166 @@
+import Config from '../../../src/util/config.js'
+import { clearFixture, getFixture } from '../../helpers/fixture.js'
+
+class DummyConfigClass extends Config {
+ static get NAME() {
+ return 'dummy'
+ }
+}
+
+describe('Config', () => {
+ let fixtureEl
+ const name = 'dummy'
+
+ beforeAll(() => {
+ fixtureEl = getFixture()
+ })
+
+ afterEach(() => {
+ clearFixture()
+ })
+
+ describe('NAME', () => {
+ it('should return plugin NAME', () => {
+ expect(DummyConfigClass.NAME).toEqual(name)
+ })
+ })
+
+ describe('DefaultType', () => {
+ it('should return plugin default type', () => {
+ expect(DummyConfigClass.DefaultType).toEqual(jasmine.any(Object))
+ })
+ })
+
+ describe('Default', () => {
+ it('should return plugin defaults', () => {
+ expect(DummyConfigClass.Default).toEqual(jasmine.any(Object))
+ })
+ })
+
+ describe('mergeConfigObj', () => {
+ it('should parse element\'s data attributes and merge it with default config. Element\'s data attributes must excel Defaults', () => {
+ fixtureEl.innerHTML = '<div id="test" data-bs-test-bool="false" data-bs-test-int="8" data-bs-test-string1="bar"></div>'
+
+ spyOnProperty(DummyConfigClass, 'Default', 'get').and.returnValue({
+ testBool: true,
+ testString: 'foo',
+ testString1: 'foo',
+ testInt: 7
+ })
+ const instance = new DummyConfigClass()
+ const configResult = instance._mergeConfigObj({}, fixtureEl.querySelector('#test'))
+
+ expect(configResult.testBool).toEqual(false)
+ expect(configResult.testString).toEqual('foo')
+ expect(configResult.testString1).toEqual('bar')
+ expect(configResult.testInt).toEqual(8)
+ })
+
+ it('should parse element\'s data attributes and merge it with default config, plug these given during method call. The programmatically given should excel all', () => {
+ fixtureEl.innerHTML = '<div id="test" data-bs-test-bool="false" data-bs-test-int="8" data-bs-test-string-1="bar"></div>'
+
+ spyOnProperty(DummyConfigClass, 'Default', 'get').and.returnValue({
+ testBool: true,
+ testString: 'foo',
+ testString1: 'foo',
+ testInt: 7
+ })
+ const instance = new DummyConfigClass()
+ const configResult = instance._mergeConfigObj({
+ testString1: 'test',
+ testInt: 3
+ }, fixtureEl.querySelector('#test'))
+
+ expect(configResult.testBool).toEqual(false)
+ expect(configResult.testString).toEqual('foo')
+ expect(configResult.testString1).toEqual('test')
+ expect(configResult.testInt).toEqual(3)
+ })
+
+ it('should parse element\'s data attribute `config` and any rest attributes. The programmatically given should excel all. Data attribute `config` should excel only Defaults', () => {
+ fixtureEl.innerHTML = '<div id="test" data-bs-config=\'{"testBool":false,"testInt":50,"testInt2":100}\' data-bs-test-int="8" data-bs-test-string-1="bar"></div>'
+
+ spyOnProperty(DummyConfigClass, 'Default', 'get').and.returnValue({
+ testBool: true,
+ testString: 'foo',
+ testString1: 'foo',
+ testInt: 7,
+ testInt2: 600
+ })
+ const instance = new DummyConfigClass()
+ const configResult = instance._mergeConfigObj({
+ testString1: 'test'
+ }, fixtureEl.querySelector('#test'))
+
+ expect(configResult.testBool).toEqual(false)
+ expect(configResult.testString).toEqual('foo')
+ expect(configResult.testString1).toEqual('test')
+ expect(configResult.testInt).toEqual(8)
+ expect(configResult.testInt2).toEqual(100)
+ })
+
+ it('should omit element\'s data attribute `config` if is not an object', () => {
+ fixtureEl.innerHTML = '<div id="test" data-bs-config="foo" data-bs-test-int="8"></div>'
+
+ spyOnProperty(DummyConfigClass, 'Default', 'get').and.returnValue({
+ testInt: 7,
+ testInt2: 79
+ })
+ const instance = new DummyConfigClass()
+ const configResult = instance._mergeConfigObj({}, fixtureEl.querySelector('#test'))
+
+ expect(configResult.testInt).toEqual(8)
+ expect(configResult.testInt2).toEqual(79)
+ })
+ })
+
+ describe('typeCheckConfig', () => {
+ it('should check type of the config object', () => {
+ spyOnProperty(DummyConfigClass, 'DefaultType', 'get').and.returnValue({
+ toggle: 'boolean',
+ parent: '(string|element)'
+ })
+ const config = {
+ toggle: true,
+ parent: 777
+ }
+
+ const obj = new DummyConfigClass()
+ expect(() => {
+ obj._typeCheckConfig(config)
+ }).toThrowError(TypeError, `${obj.constructor.NAME.toUpperCase()}: Option "parent" provided type "number" but expected type "(string|element)".`)
+ })
+
+ it('should return null stringified when null is passed', () => {
+ spyOnProperty(DummyConfigClass, 'DefaultType', 'get').and.returnValue({
+ toggle: 'boolean',
+ parent: '(null|element)'
+ })
+
+ const obj = new DummyConfigClass()
+ const config = {
+ toggle: true,
+ parent: null
+ }
+
+ obj._typeCheckConfig(config)
+ expect().nothing()
+ })
+
+ it('should return undefined stringified when undefined is passed', () => {
+ spyOnProperty(DummyConfigClass, 'DefaultType', 'get').and.returnValue({
+ toggle: 'boolean',
+ parent: '(undefined|element)'
+ })
+
+ const obj = new DummyConfigClass()
+ const config = {
+ toggle: true,
+ parent: undefined
+ }
+
+ obj._typeCheckConfig(config)
+ expect().nothing()
+ })
+ })
+})
diff --git a/js/tests/unit/util/focustrap.spec.js b/js/tests/unit/util/focustrap.spec.js
index 99bc95fca..0a20017d5 100644
--- a/js/tests/unit/util/focustrap.spec.js
+++ b/js/tests/unit/util/focustrap.spec.js
@@ -1,7 +1,7 @@
-import FocusTrap from '../../../src/util/focustrap'
-import EventHandler from '../../../src/dom/event-handler'
-import SelectorEngine from '../../../src/dom/selector-engine'
-import { clearFixture, getFixture, createEvent } from '../../helpers/fixture'
+import EventHandler from '../../../src/dom/event-handler.js'
+import SelectorEngine from '../../../src/dom/selector-engine.js'
+import FocusTrap from '../../../src/util/focustrap.js'
+import { clearFixture, createEvent, getFixture } from '../../helpers/fixture.js'
describe('FocusTrap', () => {
let fixtureEl
@@ -20,12 +20,12 @@ describe('FocusTrap', () => {
const trapElement = fixtureEl.querySelector('div')
- spyOn(trapElement, 'focus')
+ const spy = spyOn(trapElement, 'focus')
const focustrap = new FocusTrap({ trapElement })
focustrap.activate()
- expect(trapElement.focus).toHaveBeenCalled()
+ expect(spy).toHaveBeenCalled()
})
it('if configured not to autofocus, should not autofocus itself', () => {
@@ -33,148 +33,156 @@ describe('FocusTrap', () => {
const trapElement = fixtureEl.querySelector('div')
- spyOn(trapElement, 'focus')
+ const spy = spyOn(trapElement, 'focus')
const focustrap = new FocusTrap({ trapElement, autofocus: false })
focustrap.activate()
- expect(trapElement.focus).not.toHaveBeenCalled()
+ expect(spy).not.toHaveBeenCalled()
})
- it('should force focus inside focus trap if it can', done => {
- fixtureEl.innerHTML = [
- '<a href="#" id="outside">outside</a>',
- '<div id="focustrap" tabindex="-1">',
- ' <a href="#" id="inside">inside</a>',
- '</div>'
- ].join('')
+ it('should force focus inside focus trap if it can', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<a href="#" id="outside">outside</a>',
+ '<div id="focustrap" tabindex="-1">',
+ ' <a href="#" id="inside">inside</a>',
+ '</div>'
+ ].join('')
- const trapElement = fixtureEl.querySelector('div')
- const focustrap = new FocusTrap({ trapElement })
- focustrap.activate()
+ const trapElement = fixtureEl.querySelector('div')
+ const focustrap = new FocusTrap({ trapElement })
+ focustrap.activate()
- const inside = document.getElementById('inside')
+ const inside = document.getElementById('inside')
- const focusInListener = () => {
- expect(inside.focus).toHaveBeenCalled()
- document.removeEventListener('focusin', focusInListener)
- done()
- }
+ const focusInListener = () => {
+ expect(spy).toHaveBeenCalled()
+ document.removeEventListener('focusin', focusInListener)
+ resolve()
+ }
- spyOn(inside, 'focus')
- spyOn(SelectorEngine, 'focusableChildren').and.callFake(() => [inside])
+ const spy = spyOn(inside, 'focus')
+ spyOn(SelectorEngine, 'focusableChildren').and.callFake(() => [inside])
- document.addEventListener('focusin', focusInListener)
+ document.addEventListener('focusin', focusInListener)
- const focusInEvent = createEvent('focusin', { bubbles: true })
- Object.defineProperty(focusInEvent, 'target', {
- value: document.getElementById('outside')
- })
+ const focusInEvent = createEvent('focusin', { bubbles: true })
+ Object.defineProperty(focusInEvent, 'target', {
+ value: document.getElementById('outside')
+ })
- document.dispatchEvent(focusInEvent)
+ document.dispatchEvent(focusInEvent)
+ })
})
- it('should wrap focus around forward on tab', done => {
- fixtureEl.innerHTML = [
- '<a href="#" id="outside">outside</a>',
- '<div id="focustrap" tabindex="-1">',
- ' <a href="#" id="first">first</a>',
- ' <a href="#" id="inside">inside</a>',
- ' <a href="#" id="last">last</a>',
- '</div>'
- ].join('')
-
- const trapElement = fixtureEl.querySelector('div')
- const focustrap = new FocusTrap({ trapElement })
- focustrap.activate()
-
- const first = document.getElementById('first')
- const inside = document.getElementById('inside')
- const last = document.getElementById('last')
- const outside = document.getElementById('outside')
-
- spyOn(SelectorEngine, 'focusableChildren').and.callFake(() => [first, inside, last])
- spyOn(first, 'focus').and.callThrough()
-
- const focusInListener = () => {
- expect(first.focus).toHaveBeenCalled()
- first.removeEventListener('focusin', focusInListener)
- done()
- }
-
- first.addEventListener('focusin', focusInListener)
-
- const keydown = createEvent('keydown')
- keydown.key = 'Tab'
-
- document.dispatchEvent(keydown)
- outside.focus()
+ it('should wrap focus around forward on tab', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<a href="#" id="outside">outside</a>',
+ '<div id="focustrap" tabindex="-1">',
+ ' <a href="#" id="first">first</a>',
+ ' <a href="#" id="inside">inside</a>',
+ ' <a href="#" id="last">last</a>',
+ '</div>'
+ ].join('')
+
+ const trapElement = fixtureEl.querySelector('div')
+ const focustrap = new FocusTrap({ trapElement })
+ focustrap.activate()
+
+ const first = document.getElementById('first')
+ const inside = document.getElementById('inside')
+ const last = document.getElementById('last')
+ const outside = document.getElementById('outside')
+
+ spyOn(SelectorEngine, 'focusableChildren').and.callFake(() => [first, inside, last])
+ const spy = spyOn(first, 'focus').and.callThrough()
+
+ const focusInListener = () => {
+ expect(spy).toHaveBeenCalled()
+ first.removeEventListener('focusin', focusInListener)
+ resolve()
+ }
+
+ first.addEventListener('focusin', focusInListener)
+
+ const keydown = createEvent('keydown')
+ keydown.key = 'Tab'
+
+ document.dispatchEvent(keydown)
+ outside.focus()
+ })
})
- it('should wrap focus around backwards on shift-tab', done => {
- fixtureEl.innerHTML = [
- '<a href="#" id="outside">outside</a>',
- '<div id="focustrap" tabindex="-1">',
- ' <a href="#" id="first">first</a>',
- ' <a href="#" id="inside">inside</a>',
- ' <a href="#" id="last">last</a>',
- '</div>'
- ].join('')
-
- const trapElement = fixtureEl.querySelector('div')
- const focustrap = new FocusTrap({ trapElement })
- focustrap.activate()
-
- const first = document.getElementById('first')
- const inside = document.getElementById('inside')
- const last = document.getElementById('last')
- const outside = document.getElementById('outside')
-
- spyOn(SelectorEngine, 'focusableChildren').and.callFake(() => [first, inside, last])
- spyOn(last, 'focus').and.callThrough()
-
- const focusInListener = () => {
- expect(last.focus).toHaveBeenCalled()
- last.removeEventListener('focusin', focusInListener)
- done()
- }
-
- last.addEventListener('focusin', focusInListener)
-
- const keydown = createEvent('keydown')
- keydown.key = 'Tab'
- keydown.shiftKey = true
-
- document.dispatchEvent(keydown)
- outside.focus()
+ it('should wrap focus around backwards on shift-tab', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<a href="#" id="outside">outside</a>',
+ '<div id="focustrap" tabindex="-1">',
+ ' <a href="#" id="first">first</a>',
+ ' <a href="#" id="inside">inside</a>',
+ ' <a href="#" id="last">last</a>',
+ '</div>'
+ ].join('')
+
+ const trapElement = fixtureEl.querySelector('div')
+ const focustrap = new FocusTrap({ trapElement })
+ focustrap.activate()
+
+ const first = document.getElementById('first')
+ const inside = document.getElementById('inside')
+ const last = document.getElementById('last')
+ const outside = document.getElementById('outside')
+
+ spyOn(SelectorEngine, 'focusableChildren').and.callFake(() => [first, inside, last])
+ const spy = spyOn(last, 'focus').and.callThrough()
+
+ const focusInListener = () => {
+ expect(spy).toHaveBeenCalled()
+ last.removeEventListener('focusin', focusInListener)
+ resolve()
+ }
+
+ last.addEventListener('focusin', focusInListener)
+
+ const keydown = createEvent('keydown')
+ keydown.key = 'Tab'
+ keydown.shiftKey = true
+
+ document.dispatchEvent(keydown)
+ outside.focus()
+ })
})
- it('should force focus on itself if there is no focusable content', done => {
- fixtureEl.innerHTML = [
- '<a href="#" id="outside">outside</a>',
- '<div id="focustrap" tabindex="-1"></div>'
- ].join('')
+ it('should force focus on itself if there is no focusable content', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<a href="#" id="outside">outside</a>',
+ '<div id="focustrap" tabindex="-1"></div>'
+ ].join('')
- const trapElement = fixtureEl.querySelector('div')
- const focustrap = new FocusTrap({ trapElement })
- focustrap.activate()
+ const trapElement = fixtureEl.querySelector('div')
+ const focustrap = new FocusTrap({ trapElement })
+ focustrap.activate()
- const focusInListener = () => {
- expect(focustrap._config.trapElement.focus).toHaveBeenCalled()
- document.removeEventListener('focusin', focusInListener)
- done()
- }
+ const focusInListener = () => {
+ expect(spy).toHaveBeenCalled()
+ document.removeEventListener('focusin', focusInListener)
+ resolve()
+ }
- spyOn(focustrap._config.trapElement, 'focus')
+ const spy = spyOn(focustrap._config.trapElement, 'focus')
- document.addEventListener('focusin', focusInListener)
+ document.addEventListener('focusin', focusInListener)
- const focusInEvent = createEvent('focusin', { bubbles: true })
- Object.defineProperty(focusInEvent, 'target', {
- value: document.getElementById('outside')
- })
+ const focusInEvent = createEvent('focusin', { bubbles: true })
+ Object.defineProperty(focusInEvent, 'target', {
+ value: document.getElementById('outside')
+ })
- document.dispatchEvent(focusInEvent)
+ document.dispatchEvent(focusInEvent)
+ })
})
})
@@ -182,29 +190,29 @@ describe('FocusTrap', () => {
it('should flag itself as no longer active', () => {
const focustrap = new FocusTrap({ trapElement: fixtureEl })
focustrap.activate()
- expect(focustrap._isActive).toBe(true)
+ expect(focustrap._isActive).toBeTrue()
focustrap.deactivate()
- expect(focustrap._isActive).toBe(false)
+ expect(focustrap._isActive).toBeFalse()
})
it('should remove all event listeners', () => {
const focustrap = new FocusTrap({ trapElement: fixtureEl })
focustrap.activate()
- spyOn(EventHandler, 'off')
+ const spy = spyOn(EventHandler, 'off')
focustrap.deactivate()
- expect(EventHandler.off).toHaveBeenCalled()
+ expect(spy).toHaveBeenCalled()
})
it('doesn\'t try removing event listeners unless it needs to (in case it hasn\'t been activated)', () => {
const focustrap = new FocusTrap({ trapElement: fixtureEl })
- spyOn(EventHandler, 'off')
+ const spy = spyOn(EventHandler, 'off')
focustrap.deactivate()
- expect(EventHandler.off).not.toHaveBeenCalled()
+ expect(spy).not.toHaveBeenCalled()
})
})
})
diff --git a/js/tests/unit/util/index.spec.js b/js/tests/unit/util/index.spec.js
index ccfe5e2c2..9e154818f 100644
--- a/js/tests/unit/util/index.spec.js
+++ b/js/tests/unit/util/index.spec.js
@@ -1,5 +1,6 @@
-import * as Util from '../../../src/util/index'
-import { clearFixture, getFixture } from '../../helpers/fixture'
+import * as Util from '../../../src/util/index.js'
+import { noop } from '../../../src/util/index.js'
+import { clearFixture, getFixture } from '../../helpers/fixture.js'
describe('Util', () => {
let fixtureEl
@@ -21,119 +22,6 @@ describe('Util', () => {
})
})
- describe('getSelectorFromElement', () => {
- it('should get selector from data-bs-target', () => {
- fixtureEl.innerHTML = [
- '<div id="test" data-bs-target=".target"></div>',
- '<div class="target"></div>'
- ].join('')
-
- const testEl = fixtureEl.querySelector('#test')
-
- expect(Util.getSelectorFromElement(testEl)).toEqual('.target')
- })
-
- it('should get selector from href if no data-bs-target set', () => {
- fixtureEl.innerHTML = [
- '<a id="test" href=".target"></a>',
- '<div class="target"></div>'
- ].join('')
-
- const testEl = fixtureEl.querySelector('#test')
-
- expect(Util.getSelectorFromElement(testEl)).toEqual('.target')
- })
-
- it('should get selector from href if data-bs-target equal to #', () => {
- fixtureEl.innerHTML = [
- '<a id="test" data-bs-target="#" href=".target"></a>',
- '<div class="target"></div>'
- ].join('')
-
- const testEl = fixtureEl.querySelector('#test')
-
- expect(Util.getSelectorFromElement(testEl)).toEqual('.target')
- })
-
- it('should return null if a selector from a href is a url without an anchor', () => {
- fixtureEl.innerHTML = [
- '<a id="test" data-bs-target="#" href="foo/bar.html"></a>',
- '<div class="target"></div>'
- ].join('')
-
- const testEl = fixtureEl.querySelector('#test')
-
- expect(Util.getSelectorFromElement(testEl)).toBeNull()
- })
-
- it('should return the anchor if a selector from a href is a url', () => {
- fixtureEl.innerHTML = [
- '<a id="test" data-bs-target="#" href="foo/bar.html#target"></a>',
- '<div id="target"></div>'
- ].join('')
-
- const testEl = fixtureEl.querySelector('#test')
-
- expect(Util.getSelectorFromElement(testEl)).toEqual('#target')
- })
-
- it('should return null if selector not found', () => {
- fixtureEl.innerHTML = '<a id="test" href=".target"></a>'
-
- const testEl = fixtureEl.querySelector('#test')
-
- expect(Util.getSelectorFromElement(testEl)).toBeNull()
- })
-
- it('should return null if no selector', () => {
- fixtureEl.innerHTML = '<div></div>'
-
- const testEl = fixtureEl.querySelector('div')
-
- expect(Util.getSelectorFromElement(testEl)).toBeNull()
- })
- })
-
- describe('getElementFromSelector', () => {
- it('should get element from data-bs-target', () => {
- fixtureEl.innerHTML = [
- '<div id="test" data-bs-target=".target"></div>',
- '<div class="target"></div>'
- ].join('')
-
- const testEl = fixtureEl.querySelector('#test')
-
- expect(Util.getElementFromSelector(testEl)).toEqual(fixtureEl.querySelector('.target'))
- })
-
- it('should get element from href if no data-bs-target set', () => {
- fixtureEl.innerHTML = [
- '<a id="test" href=".target"></a>',
- '<div class="target"></div>'
- ].join('')
-
- const testEl = fixtureEl.querySelector('#test')
-
- expect(Util.getElementFromSelector(testEl)).toEqual(fixtureEl.querySelector('.target'))
- })
-
- it('should return null if element not found', () => {
- fixtureEl.innerHTML = '<a id="test" href=".target"></a>'
-
- const testEl = fixtureEl.querySelector('#test')
-
- expect(Util.getElementFromSelector(testEl)).toBeNull()
- })
-
- it('should return null if no selector', () => {
- fixtureEl.innerHTML = '<div></div>'
-
- const testEl = fixtureEl.querySelector('div')
-
- expect(Util.getElementFromSelector(testEl)).toBeNull()
- })
- })
-
describe('getTransitionDurationFromElement', () => {
it('should get transition from element', () => {
fixtureEl.innerHTML = '<div style="transition: all 300ms ease-out;"></div>'
@@ -154,34 +42,35 @@ describe('Util', () => {
})
describe('triggerTransitionEnd', () => {
- it('should trigger transitionend event', done => {
- fixtureEl.innerHTML = '<div></div>'
+ it('should trigger transitionend event', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = '<div></div>'
- const el = fixtureEl.querySelector('div')
- const spy = spyOn(el, 'dispatchEvent').and.callThrough()
+ const el = fixtureEl.querySelector('div')
+ const spy = spyOn(el, 'dispatchEvent').and.callThrough()
- el.addEventListener('transitionend', () => {
- expect(spy).toHaveBeenCalled()
- done()
- })
+ el.addEventListener('transitionend', () => {
+ expect(spy).toHaveBeenCalled()
+ resolve()
+ })
- Util.triggerTransitionEnd(el)
+ Util.triggerTransitionEnd(el)
+ })
})
})
describe('isElement', () => {
it('should detect if the parameter is an element or not and return Boolean', () => {
- fixtureEl.innerHTML =
- [
- '<div id="foo" class="test"></div>',
- '<div id="bar" class="test"></div>'
- ].join('')
+ fixtureEl.innerHTML = [
+ '<div id="foo" class="test"></div>',
+ '<div id="bar" class="test"></div>'
+ ].join('')
const el = fixtureEl.querySelector('#foo')
- expect(Util.isElement(el)).toEqual(true)
- expect(Util.isElement({})).toEqual(false)
- expect(Util.isElement(fixtureEl.querySelectorAll('.test'))).toEqual(false)
+ expect(Util.isElement(el)).toBeTrue()
+ expect(Util.isElement({})).toBeFalse()
+ expect(Util.isElement(fixtureEl.querySelectorAll('.test'))).toBeFalse()
})
it('should detect jQuery element', () => {
@@ -193,17 +82,16 @@ describe('Util', () => {
jquery: 'foo'
}
- expect(Util.isElement(fakejQuery)).toEqual(true)
+ expect(Util.isElement(fakejQuery)).toBeTrue()
})
})
describe('getElement', () => {
it('should try to parse element', () => {
- fixtureEl.innerHTML =
- [
- '<div id="foo" class="test"></div>',
- '<div id="bar" class="test"></div>'
- ].join('')
+ fixtureEl.innerHTML = [
+ '<div id="foo" class="test"></div>',
+ '<div id="bar" class="test"></div>'
+ ].join('')
const el = fixtureEl.querySelector('div')
@@ -225,61 +113,14 @@ describe('Util', () => {
})
})
- describe('typeCheckConfig', () => {
- const namePlugin = 'collapse'
-
- it('should check type of the config object', () => {
- const defaultType = {
- toggle: 'boolean',
- parent: '(string|element)'
- }
- const config = {
- toggle: true,
- parent: 777
- }
-
- expect(() => {
- Util.typeCheckConfig(namePlugin, config, defaultType)
- }).toThrowError(TypeError, 'COLLAPSE: Option "parent" provided type "number" but expected type "(string|element)".')
- })
-
- it('should return null stringified when null is passed', () => {
- const defaultType = {
- toggle: 'boolean',
- parent: '(null|element)'
- }
- const config = {
- toggle: true,
- parent: null
- }
-
- Util.typeCheckConfig(namePlugin, config, defaultType)
- expect().nothing()
- })
-
- it('should return undefined stringified when undefined is passed', () => {
- const defaultType = {
- toggle: 'boolean',
- parent: '(undefined|element)'
- }
- const config = {
- toggle: true,
- parent: undefined
- }
-
- Util.typeCheckConfig(namePlugin, config, defaultType)
- expect().nothing()
- })
- })
-
describe('isVisible', () => {
it('should return false if the element is not defined', () => {
- expect(Util.isVisible(null)).toEqual(false)
- expect(Util.isVisible(undefined)).toEqual(false)
+ expect(Util.isVisible(null)).toBeFalse()
+ expect(Util.isVisible(undefined)).toBeFalse()
})
it('should return false if the element provided is not a dom element', () => {
- expect(Util.isVisible({})).toEqual(false)
+ expect(Util.isVisible({})).toBeFalse()
})
it('should return false if the element is not visible with display none', () => {
@@ -287,7 +128,7 @@ describe('Util', () => {
const div = fixtureEl.querySelector('div')
- expect(Util.isVisible(div)).toEqual(false)
+ expect(Util.isVisible(div)).toBeFalse()
})
it('should return false if the element is not visible with visibility hidden', () => {
@@ -295,7 +136,7 @@ describe('Util', () => {
const div = fixtureEl.querySelector('div')
- expect(Util.isVisible(div)).toEqual(false)
+ expect(Util.isVisible(div)).toBeFalse()
})
it('should return false if an ancestor element is display none', () => {
@@ -311,7 +152,7 @@ describe('Util', () => {
const div = fixtureEl.querySelector('.content')
- expect(Util.isVisible(div)).toEqual(false)
+ expect(Util.isVisible(div)).toBeFalse()
})
it('should return false if an ancestor element is visibility hidden', () => {
@@ -327,7 +168,7 @@ describe('Util', () => {
const div = fixtureEl.querySelector('.content')
- expect(Util.isVisible(div)).toEqual(false)
+ expect(Util.isVisible(div)).toBeFalse()
})
it('should return true if an ancestor element is visibility hidden, but reverted', () => {
@@ -343,7 +184,7 @@ describe('Util', () => {
const div = fixtureEl.querySelector('.content')
- expect(Util.isVisible(div)).toEqual(true)
+ expect(Util.isVisible(div)).toBeTrue()
})
it('should return true if the element is visible', () => {
@@ -355,7 +196,7 @@ describe('Util', () => {
const div = fixtureEl.querySelector('#element')
- expect(Util.isVisible(div)).toEqual(true)
+ expect(Util.isVisible(div)).toBeTrue()
})
it('should return false if the element is hidden, but not via display or visibility', () => {
@@ -367,20 +208,56 @@ describe('Util', () => {
const div = fixtureEl.querySelector('#element')
- expect(Util.isVisible(div)).toEqual(false)
+ expect(Util.isVisible(div)).toBeFalse()
+ })
+
+ it('should return true if its a closed details element', () => {
+ fixtureEl.innerHTML = '<details id="element"></details>'
+
+ const div = fixtureEl.querySelector('#element')
+
+ expect(Util.isVisible(div)).toBeTrue()
+ })
+
+ it('should return true if the element is visible inside an open details element', () => {
+ fixtureEl.innerHTML = [
+ '<details open>',
+ ' <div id="element"></div>',
+ '</details>'
+ ].join('')
+
+ const div = fixtureEl.querySelector('#element')
+
+ expect(Util.isVisible(div)).toBeTrue()
+ })
+
+ it('should return true if the element is a visible summary in a closed details element', () => {
+ fixtureEl.innerHTML = [
+ '<details>',
+ ' <summary id="element-1">',
+ ' <span id="element-2"></span>',
+ ' </summary>',
+ '</details>'
+ ].join('')
+
+ const element1 = fixtureEl.querySelector('#element-1')
+ const element2 = fixtureEl.querySelector('#element-2')
+
+ expect(Util.isVisible(element1)).toBeTrue()
+ expect(Util.isVisible(element2)).toBeTrue()
})
})
describe('isDisabled', () => {
it('should return true if the element is not defined', () => {
- expect(Util.isDisabled(null)).toEqual(true)
- expect(Util.isDisabled(undefined)).toEqual(true)
- expect(Util.isDisabled()).toEqual(true)
+ expect(Util.isDisabled(null)).toBeTrue()
+ expect(Util.isDisabled(undefined)).toBeTrue()
+ expect(Util.isDisabled()).toBeTrue()
})
it('should return true if the element provided is not a dom element', () => {
- expect(Util.isDisabled({})).toEqual(true)
- expect(Util.isDisabled('test')).toEqual(true)
+ expect(Util.isDisabled({})).toBeTrue()
+ expect(Util.isDisabled('test')).toBeTrue()
})
it('should return true if the element has disabled attribute', () => {
@@ -396,9 +273,9 @@ describe('Util', () => {
const div1 = fixtureEl.querySelector('#element1')
const div2 = fixtureEl.querySelector('#element2')
- expect(Util.isDisabled(div)).toEqual(true)
- expect(Util.isDisabled(div1)).toEqual(true)
- expect(Util.isDisabled(div2)).toEqual(true)
+ expect(Util.isDisabled(div)).toBeTrue()
+ expect(Util.isDisabled(div1)).toBeTrue()
+ expect(Util.isDisabled(div2)).toBeTrue()
})
it('should return false if the element has disabled attribute with "false" value, or doesn\'t have attribute', () => {
@@ -412,8 +289,8 @@ describe('Util', () => {
const div = fixtureEl.querySelector('#element')
const div1 = fixtureEl.querySelector('#element1')
- expect(Util.isDisabled(div)).toEqual(false)
- expect(Util.isDisabled(div1)).toEqual(false)
+ expect(Util.isDisabled(div)).toBeFalse()
+ expect(Util.isDisabled(div1)).toBeFalse()
})
it('should return false if the element is not disabled ', () => {
@@ -427,15 +304,16 @@ describe('Util', () => {
const el = selector => fixtureEl.querySelector(selector)
- expect(Util.isDisabled(el('#button'))).toEqual(false)
- expect(Util.isDisabled(el('#select'))).toEqual(false)
- expect(Util.isDisabled(el('#input'))).toEqual(false)
+ expect(Util.isDisabled(el('#button'))).toBeFalse()
+ expect(Util.isDisabled(el('#select'))).toBeFalse()
+ expect(Util.isDisabled(el('#input'))).toBeFalse()
})
+
it('should return true if the element has disabled attribute', () => {
fixtureEl.innerHTML = [
'<div>',
- ' <input id="input" disabled="disabled"/>',
- ' <input id="input1" disabled="disabled"/>',
+ ' <input id="input" disabled="disabled">',
+ ' <input id="input1" disabled="disabled">',
' <button id="button" disabled="true"></button>',
' <button id="button1" disabled="disabled"></button>',
' <button id="button2" disabled></button>',
@@ -446,12 +324,12 @@ describe('Util', () => {
const el = selector => fixtureEl.querySelector(selector)
- expect(Util.isDisabled(el('#input'))).toEqual(true)
- expect(Util.isDisabled(el('#input1'))).toEqual(true)
- expect(Util.isDisabled(el('#button'))).toEqual(true)
- expect(Util.isDisabled(el('#button1'))).toEqual(true)
- expect(Util.isDisabled(el('#button2'))).toEqual(true)
- expect(Util.isDisabled(el('#input'))).toEqual(true)
+ expect(Util.isDisabled(el('#input'))).toBeTrue()
+ expect(Util.isDisabled(el('#input1'))).toBeTrue()
+ expect(Util.isDisabled(el('#button'))).toBeTrue()
+ expect(Util.isDisabled(el('#button1'))).toBeTrue()
+ expect(Util.isDisabled(el('#button2'))).toBeTrue()
+ expect(Util.isDisabled(el('#input'))).toBeTrue()
})
it('should return true if the element has class "disabled"', () => {
@@ -463,19 +341,19 @@ describe('Util', () => {
const div = fixtureEl.querySelector('#element')
- expect(Util.isDisabled(div)).toEqual(true)
+ expect(Util.isDisabled(div)).toBeTrue()
})
it('should return true if the element has class "disabled" but disabled attribute is false', () => {
fixtureEl.innerHTML = [
'<div>',
- ' <input id="input" class="disabled" disabled="false"/>',
+ ' <input id="input" class="disabled" disabled="false">',
'</div>'
].join('')
const div = fixtureEl.querySelector('#input')
- expect(Util.isDisabled(div)).toEqual(true)
+ expect(Util.isDisabled(div)).toBeTrue()
})
})
@@ -493,7 +371,7 @@ describe('Util', () => {
spyOn(document.documentElement, 'attachShadow').and.returnValue(null)
- expect(Util.findShadowRoot(div)).toEqual(null)
+ expect(Util.findShadowRoot(div)).toBeNull()
})
it('should return null when we do not find a shadow root', () => {
@@ -505,7 +383,7 @@ describe('Util', () => {
spyOn(document, 'getRootNode').and.returnValue(undefined)
- expect(Util.findShadowRoot(document)).toEqual(null)
+ expect(Util.findShadowRoot(document)).toBeNull()
})
it('should return the shadow root when found', () => {
@@ -532,7 +410,7 @@ describe('Util', () => {
describe('noop', () => {
it('should be a function', () => {
- expect(typeof Util.noop).toEqual('function')
+ expect(Util.noop).toEqual(jasmine.any(Function))
})
})
@@ -569,14 +447,14 @@ describe('Util', () => {
document.body.setAttribute('data-bs-no-jquery', '')
expect(window.jQuery).toEqual(fakejQuery)
- expect(Util.getjQuery()).toEqual(null)
+ expect(Util.getjQuery()).toBeNull()
document.body.removeAttribute('data-bs-no-jquery')
})
it('should not return jQuery if not present', () => {
window.jQuery = undefined
- expect(Util.getjQuery()).toEqual(null)
+ expect(Util.getjQuery()).toBeNull()
})
})
@@ -585,7 +463,7 @@ describe('Util', () => {
const spy = jasmine.createSpy()
const spy2 = jasmine.createSpy()
- spyOn(document, 'addEventListener').and.callThrough()
+ const spyAdd = spyOn(document, 'addEventListener').and.callThrough()
spyOnProperty(document, 'readyState').and.returnValue('loading')
Util.onDOMContentLoaded(spy)
@@ -598,7 +476,7 @@ describe('Util', () => {
expect(spy).toHaveBeenCalled()
expect(spy2).toHaveBeenCalled()
- expect(document.addEventListener).toHaveBeenCalledTimes(1)
+ expect(spyAdd).toHaveBeenCalledTimes(1)
})
it('should execute callback if readyState is not "loading"', () => {
@@ -623,14 +501,14 @@ describe('Util', () => {
})
it('should define a plugin on the jQuery instance', () => {
- const pluginMock = function () {}
+ const pluginMock = Util.noop
pluginMock.NAME = 'test'
- pluginMock.jQueryInterface = function () {}
+ pluginMock.jQueryInterface = Util.noop
Util.defineJQueryPlugin(pluginMock)
- expect(fakejQuery.fn.test).toBe(pluginMock.jQueryInterface)
- expect(fakejQuery.fn.test.Constructor).toBe(pluginMock)
- expect(typeof fakejQuery.fn.test.noConflict).toEqual('function')
+ expect(fakejQuery.fn.test).toEqual(pluginMock.jQueryInterface)
+ expect(fakejQuery.fn.test.Constructor).toEqual(pluginMock)
+ expect(fakejQuery.fn.test.noConflict).toEqual(jasmine.any(Function))
})
})
@@ -640,6 +518,25 @@ describe('Util', () => {
Util.execute(spy)
expect(spy).toHaveBeenCalled()
})
+
+ it('should execute if arg is function & return the result', () => {
+ const functionFoo = (num1, num2 = 10) => num1 + num2
+ const resultFoo = Util.execute(functionFoo, [undefined, 4, 5])
+ expect(resultFoo).toBe(9)
+
+ const resultFoo1 = Util.execute(functionFoo, [undefined, 4])
+ expect(resultFoo1).toBe(14)
+
+ const functionBar = () => 'foo'
+ const resultBar = Util.execute(functionBar)
+ expect(resultBar).toBe('foo')
+ })
+
+ it('should not execute if arg is not function & return default argument', () => {
+ const foo = 'bar'
+ expect(Util.execute(foo)).toBe('bar')
+ expect(Util.execute(foo, [], 4)).toBe(4)
+ })
})
describe('executeAfterTransition', () => {
@@ -670,96 +567,104 @@ describe('Util', () => {
expect(callbackSpy).toHaveBeenCalled()
})
- it('should execute a function after a computed CSS transition duration and there was no transitionend event dispatched', done => {
- const el = document.createElement('div')
- const callbackSpy = jasmine.createSpy('callback spy')
+ it('should execute a function after a computed CSS transition duration and there was no transitionend event dispatched', () => {
+ return new Promise(resolve => {
+ const el = document.createElement('div')
+ const callbackSpy = jasmine.createSpy('callback spy')
- spyOn(window, 'getComputedStyle').and.returnValue({
- transitionDuration: '0.05s',
- transitionDelay: '0s'
- })
+ spyOn(window, 'getComputedStyle').and.returnValue({
+ transitionDuration: '0.05s',
+ transitionDelay: '0s'
+ })
- Util.executeAfterTransition(callbackSpy, el)
+ Util.executeAfterTransition(callbackSpy, el)
- setTimeout(() => {
- expect(callbackSpy).toHaveBeenCalled()
- done()
- }, 70)
+ setTimeout(() => {
+ expect(callbackSpy).toHaveBeenCalled()
+ resolve()
+ }, 70)
+ })
})
- it('should not execute a function a second time after a computed CSS transition duration and if a transitionend event has already been dispatched', done => {
- const el = document.createElement('div')
- const callbackSpy = jasmine.createSpy('callback spy')
+ it('should not execute a function a second time after a computed CSS transition duration and if a transitionend event has already been dispatched', () => {
+ return new Promise(resolve => {
+ const el = document.createElement('div')
+ const callbackSpy = jasmine.createSpy('callback spy')
- spyOn(window, 'getComputedStyle').and.returnValue({
- transitionDuration: '0.05s',
- transitionDelay: '0s'
- })
+ spyOn(window, 'getComputedStyle').and.returnValue({
+ transitionDuration: '0.05s',
+ transitionDelay: '0s'
+ })
- Util.executeAfterTransition(callbackSpy, el)
+ Util.executeAfterTransition(callbackSpy, el)
- setTimeout(() => {
- el.dispatchEvent(new TransitionEvent('transitionend'))
- }, 50)
+ setTimeout(() => {
+ el.dispatchEvent(new TransitionEvent('transitionend'))
+ }, 50)
- setTimeout(() => {
- expect(callbackSpy).toHaveBeenCalledTimes(1)
- done()
- }, 70)
+ setTimeout(() => {
+ expect(callbackSpy).toHaveBeenCalledTimes(1)
+ resolve()
+ }, 70)
+ })
})
- it('should not trigger a transitionend event if another transitionend event had already happened', done => {
- const el = document.createElement('div')
+ it('should not trigger a transitionend event if another transitionend event had already happened', () => {
+ return new Promise(resolve => {
+ const el = document.createElement('div')
- spyOn(window, 'getComputedStyle').and.returnValue({
- transitionDuration: '0.05s',
- transitionDelay: '0s'
- })
+ spyOn(window, 'getComputedStyle').and.returnValue({
+ transitionDuration: '0.05s',
+ transitionDelay: '0s'
+ })
- Util.executeAfterTransition(() => {}, el)
+ Util.executeAfterTransition(noop, el)
- // simulate a event dispatched by the browser
- el.dispatchEvent(new TransitionEvent('transitionend'))
+ // simulate a event dispatched by the browser
+ el.dispatchEvent(new TransitionEvent('transitionend'))
- const dispatchSpy = spyOn(el, 'dispatchEvent').and.callThrough()
+ const dispatchSpy = spyOn(el, 'dispatchEvent').and.callThrough()
- setTimeout(() => {
- // setTimeout should not have triggered another transitionend event.
- expect(dispatchSpy).not.toHaveBeenCalled()
- done()
- }, 70)
+ setTimeout(() => {
+ // setTimeout should not have triggered another transitionend event.
+ expect(dispatchSpy).not.toHaveBeenCalled()
+ resolve()
+ }, 70)
+ })
})
- it('should ignore transitionend events from nested elements', done => {
- fixtureEl.innerHTML = [
- '<div class="outer">',
- ' <div class="nested"></div>',
- '</div>'
- ].join('')
+ it('should ignore transitionend events from nested elements', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="outer">',
+ ' <div class="nested"></div>',
+ '</div>'
+ ].join('')
- const outer = fixtureEl.querySelector('.outer')
- const nested = fixtureEl.querySelector('.nested')
- const callbackSpy = jasmine.createSpy('callback spy')
+ const outer = fixtureEl.querySelector('.outer')
+ const nested = fixtureEl.querySelector('.nested')
+ const callbackSpy = jasmine.createSpy('callback spy')
- spyOn(window, 'getComputedStyle').and.returnValue({
- transitionDuration: '0.05s',
- transitionDelay: '0s'
- })
+ spyOn(window, 'getComputedStyle').and.returnValue({
+ transitionDuration: '0.05s',
+ transitionDelay: '0s'
+ })
- Util.executeAfterTransition(callbackSpy, outer)
+ Util.executeAfterTransition(callbackSpy, outer)
- nested.dispatchEvent(new TransitionEvent('transitionend', {
- bubbles: true
- }))
+ nested.dispatchEvent(new TransitionEvent('transitionend', {
+ bubbles: true
+ }))
- setTimeout(() => {
- expect(callbackSpy).not.toHaveBeenCalled()
- }, 20)
+ setTimeout(() => {
+ expect(callbackSpy).not.toHaveBeenCalled()
+ }, 20)
- setTimeout(() => {
- expect(callbackSpy).toHaveBeenCalled()
- done()
- }, 70)
+ setTimeout(() => {
+ expect(callbackSpy).toHaveBeenCalled()
+ resolve()
+ }, 70)
+ })
})
})
diff --git a/js/tests/unit/util/sanitizer.spec.js b/js/tests/unit/util/sanitizer.spec.js
index 28d624c87..2b21ef2e1 100644
--- a/js/tests/unit/util/sanitizer.spec.js
+++ b/js/tests/unit/util/sanitizer.spec.js
@@ -1,4 +1,4 @@
-import { DefaultAllowlist, sanitizeHtml } from '../../../src/util/sanitizer'
+import { DefaultAllowlist, sanitizeHtml } from '../../../src/util/sanitizer.js'
describe('Sanitizer', () => {
describe('sanitizeHtml', () => {
@@ -10,17 +10,75 @@ describe('Sanitizer', () => {
expect(result).toEqual(empty)
})
- it('should sanitize template by removing tags with XSS', () => {
- const template = [
- '<div>',
- ' <a href="javascript:alert(7)">Click me</a>',
- ' <span>Some content</span>',
- '</div>'
- ].join('')
-
- const result = sanitizeHtml(template, DefaultAllowlist, null)
+ it('should retain tags with valid URLs', () => {
+ const validUrls = [
+ '',
+ 'http://abc',
+ 'HTTP://abc',
+ 'https://abc',
+ 'HTTPS://abc',
+ 'ftp://abc',
+ 'FTP://abc',
+ 'mailto:[email protected]',
+ 'MAILTO:[email protected]',
+ 'tel:123-123-1234',
+ 'TEL:123-123-1234',
+ '#anchor',
+ '/page1.md',
+ 'http://JavaScript/my.js',
+ 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/', // Truncated.
+ 'data:video/webm;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/',
+ 'data:audio/opus;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/',
+ 'unknown-scheme:abc'
+ ]
+
+ for (const url of validUrls) {
+ const template = [
+ '<div>',
+ ` <a href="${url}">Click me</a>`,
+ ' <span>Some content</span>',
+ '</div>'
+ ].join('')
+
+ const result = sanitizeHtml(template, DefaultAllowlist, null)
+
+ expect(result).toContain(`href="${url}"`)
+ }
+ })
- expect(result).not.toContain('href="javascript:alert(7)')
+ it('should sanitize template by removing tags with XSS', () => {
+ const invalidUrls = [
+ // eslint-disable-next-line no-script-url
+ 'javascript:alert(7)',
+ // eslint-disable-next-line no-script-url
+ 'javascript:evil()',
+ // eslint-disable-next-line no-script-url
+ 'JavaScript:abc',
+ ' javascript:abc',
+ ' \n Java\n Script:abc',
+ '&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;',
+ '&#106&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;',
+ '&#106 &#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;',
+ '&#0000106&#0000097&#0000118&#0000097&#0000115&#0000099&#0000114&#0000105&#0000112&#0000116&#0000058',
+ '&#x6A&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3A;',
+ 'jav&#x09;ascript:alert();',
+ 'jav\u0000ascript:alert();'
+ ]
+
+ for (const url of invalidUrls) {
+ const template = [
+ '<div>',
+ ` <a href="${url}">Click me</a>`,
+ ' <span>Some content</span>',
+ '</div>'
+ ].join('')
+
+ const result = sanitizeHtml(template, DefaultAllowlist, null)
+
+ expect(result).not.toContain(`href="${url}"`)
+ }
})
it('should sanitize template and work with multiple regex', () => {
@@ -84,12 +142,12 @@ describe('Sanitizer', () => {
return htmlUnsafe
}
- spyOn(DOMParser.prototype, 'parseFromString')
+ const spy = spyOn(DOMParser.prototype, 'parseFromString')
const result = sanitizeHtml(template, DefaultAllowlist, mySanitize)
expect(result).toEqual(template)
- expect(DOMParser.prototype.parseFromString).not.toHaveBeenCalled()
+ expect(spy).not.toHaveBeenCalled()
})
it('should allow multiple sanitation passes of the same template', () => {
diff --git a/js/tests/unit/util/scrollbar.spec.js b/js/tests/unit/util/scrollbar.spec.js
index 280adb8e5..6dadfcdd1 100644
--- a/js/tests/unit/util/scrollbar.spec.js
+++ b/js/tests/unit/util/scrollbar.spec.js
@@ -1,13 +1,13 @@
-import { clearBodyAndDocument, clearFixture, getFixture } from '../../helpers/fixture'
-import Manipulator from '../../../src/dom/manipulator'
-import ScrollBarHelper from '../../../src/util/scrollbar'
+import Manipulator from '../../../src/dom/manipulator.js'
+import ScrollBarHelper from '../../../src/util/scrollbar.js'
+import { clearBodyAndDocument, clearFixture, getFixture } from '../../helpers/fixture.js'
describe('ScrollBar', () => {
let fixtureEl
const doc = document.documentElement
- const parseInt = arg => Number.parseInt(arg, 10)
- const getPaddingX = el => parseInt(window.getComputedStyle(el).paddingRight)
- const getMarginX = el => parseInt(window.getComputedStyle(el).marginRight)
+ const parseIntDecimal = arg => Number.parseInt(arg, 10)
+ const getPaddingX = el => parseIntDecimal(window.getComputedStyle(el).paddingRight)
+ const getMarginX = el => parseIntDecimal(window.getComputedStyle(el).marginRight)
const getOverFlow = el => el.style.overflow
const getPaddingAttr = el => Manipulator.getDataAttribute(el, 'padding-right')
const getMarginAttr = el => Manipulator.getDataAttribute(el, 'margin-right')
@@ -24,7 +24,9 @@ describe('ScrollBar', () => {
}
}
- const isScrollBarHidden = () => { // IOS devices, Android devices and Browsers on Mac, hide scrollbar by default and appear it, only while scrolling. So the tests for scrollbar would fail
+ // iOS, Android devices and macOS browsers hide scrollbar by default and show it only while scrolling.
+ // So the tests for scrollbar would fail
+ const isScrollBarHidden = () => {
const calc = windowCalculations()
return calc.htmlClient === calc.htmlOffset && calc.htmlClient === calc.window
}
@@ -52,28 +54,24 @@ describe('ScrollBar', () => {
it('should return true if body is overflowing', () => {
document.documentElement.style.overflowY = 'scroll'
document.body.style.overflowY = 'scroll'
- fixtureEl.innerHTML = [
- '<div style="height: 110vh; width: 100%"></div>'
- ].join('')
+ fixtureEl.innerHTML = '<div style="height: 110vh; width: 100%"></div>'
const result = new ScrollBarHelper().isOverflowing()
if (isScrollBarHidden()) {
- expect(result).toEqual(false)
+ expect(result).toBeFalse()
} else {
- expect(result).toEqual(true)
+ expect(result).toBeTrue()
}
})
it('should return false if body is not overflowing', () => {
doc.style.overflowY = 'hidden'
document.body.style.overflowY = 'hidden'
- fixtureEl.innerHTML = [
- '<div style="height: 110vh; width: 100%"></div>'
- ].join('')
+ fixtureEl.innerHTML = '<div style="height: 110vh; width: 100%"></div>'
const scrollBar = new ScrollBarHelper()
const result = scrollBar.isOverflowing()
- expect(result).toEqual(false)
+ expect(result).toBeFalse()
})
})
@@ -81,13 +79,11 @@ describe('ScrollBar', () => {
it('should return an integer greater than zero, if body is overflowing', () => {
doc.style.overflowY = 'scroll'
document.body.style.overflowY = 'scroll'
- fixtureEl.innerHTML = [
- '<div style="height: 110vh; width: 100%"></div>'
- ].join('')
+ fixtureEl.innerHTML = '<div style="height: 110vh; width: 100%"></div>'
const result = new ScrollBarHelper().getWidth()
if (isScrollBarHidden()) {
- expect(result).toBe(0)
+ expect(result).toEqual(0)
} else {
expect(result).toBeGreaterThan(1)
}
@@ -96,9 +92,7 @@ describe('ScrollBar', () => {
it('should return 0 if body is not overflowing', () => {
document.documentElement.style.overflowY = 'hidden'
document.body.style.overflowY = 'hidden'
- fixtureEl.innerHTML = [
- '<div style="height: 110vh; width: 100%"></div>'
- ].join('')
+ fixtureEl.innerHTML = '<div style="height: 110vh; width: 100%"></div>'
const result = new ScrollBarHelper().getWidth()
@@ -107,11 +101,11 @@ describe('ScrollBar', () => {
})
describe('hide - reset', () => {
- it('should adjust the inline padding of fixed elements which are full-width', done => {
+ it('should adjust the inline padding of fixed elements which are full-width', () => {
fixtureEl.innerHTML = [
- '<div style="height: 110vh; width: 100%">' +
- '<div class="fixed-top" id="fixed1" style="padding-right: 0px; width: 100vw"></div>',
- '<div class="fixed-top" id="fixed2" style="padding-right: 5px; width: 100vw"></div>',
+ '<div style="height: 110vh; width: 100%">',
+ ' <div class="fixed-top" id="fixed1" style="padding-right: 0px; width: 100vw"></div>',
+ ' <div class="fixed-top" id="fixed2" style="padding-right: 5px; width: 100vw"></div>',
'</div>'
].join('')
doc.style.overflowY = 'scroll'
@@ -128,25 +122,44 @@ describe('ScrollBar', () => {
let currentPadding = getPaddingX(fixedEl)
let currentPadding2 = getPaddingX(fixedEl2)
- expect(getPaddingAttr(fixedEl)).toEqual(`${originalPadding}px`, 'original fixed element padding should be stored in data-bs-padding-right')
- expect(getPaddingAttr(fixedEl2)).toEqual(`${originalPadding2}px`, 'original fixed element padding should be stored in data-bs-padding-right')
- expect(currentPadding).toEqual(expectedPadding, 'fixed element padding should be adjusted while opening')
- expect(currentPadding2).toEqual(expectedPadding2, 'fixed element padding should be adjusted while opening')
+ expect(getPaddingAttr(fixedEl)).toEqual(`${originalPadding}px`)
+ expect(getPaddingAttr(fixedEl2)).toEqual(`${originalPadding2}px`)
+ expect(currentPadding).toEqual(expectedPadding)
+ expect(currentPadding2).toEqual(expectedPadding2)
scrollBar.reset()
currentPadding = getPaddingX(fixedEl)
currentPadding2 = getPaddingX(fixedEl2)
- expect(getPaddingAttr(fixedEl)).toEqual(null, 'data-bs-padding-right should be cleared after closing')
- expect(getPaddingAttr(fixedEl2)).toEqual(null, 'data-bs-padding-right should be cleared after closing')
- expect(currentPadding).toEqual(originalPadding, 'fixed element padding should be reset after closing')
- expect(currentPadding2).toEqual(originalPadding2, 'fixed element padding should be reset after closing')
- done()
+ expect(getPaddingAttr(fixedEl)).toBeNull()
+ expect(getPaddingAttr(fixedEl2)).toBeNull()
+ expect(currentPadding).toEqual(originalPadding)
+ expect(currentPadding2).toEqual(originalPadding2)
})
- it('should adjust the inline margin and padding of sticky elements', done => {
+ it('should remove padding & margin if not existed before adjustment', () => {
fixtureEl.innerHTML = [
- '<div style="height: 110vh">' +
- '<div class="sticky-top" style="margin-right: 10px; padding-right: 20px; width: 100vw; height: 10px"></div>',
+ '<div style="height: 110vh; width: 100%">',
+ ' <div class="fixed" id="fixed" style="width: 100vw;"></div>',
+ ' <div class="sticky-top" id="sticky" style=" width: 100vw;"></div>',
+ '</div>'
+ ].join('')
+ doc.style.overflowY = 'scroll'
+
+ const fixedEl = fixtureEl.querySelector('#fixed')
+ const stickyEl = fixtureEl.querySelector('#sticky')
+ const scrollBar = new ScrollBarHelper()
+
+ scrollBar.hide()
+ scrollBar.reset()
+
+ expect(fixedEl.getAttribute('style').includes('padding-right')).toBeFalse()
+ expect(stickyEl.getAttribute('style').includes('margin-right')).toBeFalse()
+ })
+
+ it('should adjust the inline margin and padding of sticky elements', () => {
+ fixtureEl.innerHTML = [
+ '<div style="height: 110vh">',
+ ' <div class="sticky-top" style="margin-right: 10px; padding-right: 20px; width: 100vw; height: 10px"></div>',
'</div>'
].join('')
doc.style.overflowY = 'scroll'
@@ -159,23 +172,20 @@ describe('ScrollBar', () => {
const expectedPadding = originalPadding + scrollBar.getWidth()
scrollBar.hide()
- expect(getMarginAttr(stickyTopEl)).toEqual(`${originalMargin}px`, 'original sticky element margin should be stored in data-bs-margin-right')
- expect(getMarginX(stickyTopEl)).toEqual(expectedMargin, 'sticky element margin should be adjusted while opening')
- expect(getPaddingAttr(stickyTopEl)).toEqual(`${originalPadding}px`, 'original sticky element margin should be stored in data-bs-margin-right')
- expect(getPaddingX(stickyTopEl)).toEqual(expectedPadding, 'sticky element margin should be adjusted while opening')
+ expect(getMarginAttr(stickyTopEl)).toEqual(`${originalMargin}px`)
+ expect(getMarginX(stickyTopEl)).toEqual(expectedMargin)
+ expect(getPaddingAttr(stickyTopEl)).toEqual(`${originalPadding}px`)
+ expect(getPaddingX(stickyTopEl)).toEqual(expectedPadding)
scrollBar.reset()
- expect(getMarginAttr(stickyTopEl)).toEqual(null, 'data-bs-margin-right should be cleared after closing')
- expect(getMarginX(stickyTopEl)).toEqual(originalMargin, 'sticky element margin should be reset after closing')
- expect(getPaddingAttr(stickyTopEl)).toEqual(null, 'data-bs-margin-right should be cleared after closing')
- expect(getPaddingX(stickyTopEl)).toEqual(originalPadding, 'sticky element margin should be reset after closing')
- done()
+ expect(getMarginAttr(stickyTopEl)).toBeNull()
+ expect(getMarginX(stickyTopEl)).toEqual(originalMargin)
+ expect(getPaddingAttr(stickyTopEl)).toBeNull()
+ expect(getPaddingX(stickyTopEl)).toEqual(originalPadding)
})
it('should not adjust the inline margin and padding of sticky and fixed elements when element do not have full width', () => {
- fixtureEl.innerHTML = [
- '<div class="sticky-top" style="margin-right: 0px; padding-right: 0px; width: 50vw"></div>'
- ].join('')
+ fixtureEl.innerHTML = '<div class="sticky-top" style="margin-right: 0px; padding-right: 0px; width: 50vw"></div>'
const stickyTopEl = fixtureEl.querySelector('.sticky-top')
const originalMargin = getMarginX(stickyTopEl)
@@ -187,16 +197,16 @@ describe('ScrollBar', () => {
const currentMargin = getMarginX(stickyTopEl)
const currentPadding = getPaddingX(stickyTopEl)
- expect(currentMargin).toEqual(originalMargin, 'sticky element\'s margin should not be adjusted while opening')
- expect(currentPadding).toEqual(originalPadding, 'sticky element\'s padding should not be adjusted while opening')
+ expect(currentMargin).toEqual(originalMargin)
+ expect(currentPadding).toEqual(originalPadding)
scrollBar.reset()
})
it('should not put data-attribute if element doesn\'t have the proper style property, should just remove style property if element didn\'t had one', () => {
fixtureEl.innerHTML = [
- '<div style="height: 110vh; width: 100%">' +
- '<div class="sticky-top" id="sticky" style="width: 100vw"></div>',
+ '<div style="height: 110vh; width: 100%">',
+ ' <div class="sticky-top" id="sticky" style="width: 100vw"></div>',
'</div>'
].join('')
@@ -232,8 +242,8 @@ describe('ScrollBar', () => {
const scrollBarWidth = scrollBar.getWidth()
scrollBar.hide()
- expect(getPaddingX(document.body)).toEqual(scrollBarWidth, 'body does not have inline padding set')
- expect(document.body.style.color).toEqual('red', 'body still has other inline styles set')
+ expect(getPaddingX(document.body)).toEqual(scrollBarWidth)
+ expect(document.body.style.color).toEqual('red')
scrollBar.reset()
})
@@ -243,7 +253,7 @@ describe('ScrollBar', () => {
fixtureEl.innerHTML = [
'<style>',
' body {',
- ` padding-right: ${styleSheetPadding} }`,
+ ` padding-right: ${styleSheetPadding}`,
' }',
'</style>'
].join('')
@@ -253,7 +263,7 @@ describe('ScrollBar', () => {
el.style.paddingRight = inlineStylePadding
const originalPadding = getPaddingX(el)
- expect(originalPadding).toEqual(parseInt(inlineStylePadding)) // Respect only the inline style as it has prevails this of css
+ expect(originalPadding).toEqual(parseIntDecimal(inlineStylePadding)) // Respect only the inline style as it has prevails this of css
const originalOverFlow = 'auto'
el.style.overflow = originalOverFlow
const scrollBar = new ScrollBarHelper()
@@ -264,7 +274,7 @@ describe('ScrollBar', () => {
const currentPadding = getPaddingX(el)
expect(currentPadding).toEqual(scrollBarWidth + originalPadding)
- expect(currentPadding).toEqual(scrollBarWidth + parseInt(inlineStylePadding))
+ expect(currentPadding).toEqual(scrollBarWidth + parseIntDecimal(inlineStylePadding))
expect(getPaddingAttr(el)).toEqual(inlineStylePadding)
expect(getOverFlow(el)).toEqual('hidden')
expect(getOverFlowAttr(el)).toEqual(originalOverFlow)
@@ -273,9 +283,9 @@ describe('ScrollBar', () => {
const currentPadding1 = getPaddingX(el)
expect(currentPadding1).toEqual(originalPadding)
- expect(getPaddingAttr(el)).toEqual(null)
+ expect(getPaddingAttr(el)).toBeNull()
expect(getOverFlow(el)).toEqual(originalOverFlow)
- expect(getOverFlowAttr(el)).toEqual(null)
+ expect(getOverFlowAttr(el)).toBeNull()
})
it('should hide scrollbar and reset it to its initial value - respecting css rules', () => {
@@ -283,7 +293,7 @@ describe('ScrollBar', () => {
fixtureEl.innerHTML = [
'<style>',
' body {',
- ` padding-right: ${styleSheetPadding} }`,
+ ` padding-right: ${styleSheetPadding}`,
' }',
'</style>'
].join('')
@@ -299,7 +309,7 @@ describe('ScrollBar', () => {
const currentPadding = getPaddingX(el)
expect(currentPadding).toEqual(scrollBarWidth + originalPadding)
- expect(currentPadding).toEqual(scrollBarWidth + parseInt(styleSheetPadding))
+ expect(currentPadding).toEqual(scrollBarWidth + parseIntDecimal(styleSheetPadding))
expect(getPaddingAttr(el)).toBeNull() // We do not have to keep css padding
expect(getOverFlow(el)).toEqual('hidden')
expect(getOverFlowAttr(el)).toEqual(originalOverFlow)
@@ -308,9 +318,9 @@ describe('ScrollBar', () => {
const currentPadding1 = getPaddingX(el)
expect(currentPadding1).toEqual(originalPadding)
- expect(getPaddingAttr(el)).toEqual(null)
+ expect(getPaddingAttr(el)).toBeNull()
expect(getOverFlow(el)).toEqual(originalOverFlow)
- expect(getOverFlowAttr(el)).toEqual(null)
+ expect(getOverFlowAttr(el)).toBeNull()
})
it('should not adjust the inline body padding when it does not overflow', () => {
@@ -324,7 +334,7 @@ describe('ScrollBar', () => {
scrollBar.hide()
const currentPadding = getPaddingX(document.body)
- expect(currentPadding).toEqual(originalPadding, 'body padding should not be adjusted')
+ expect(currentPadding).toEqual(originalPadding)
scrollBar.reset()
})
@@ -344,7 +354,7 @@ describe('ScrollBar', () => {
const currentPadding = getPaddingX(document.body)
- expect(currentPadding).toEqual(originalPadding, 'body padding should not be adjusted')
+ expect(currentPadding).toEqual(originalPadding)
scrollBar.reset()
})
diff --git a/js/tests/unit/util/swipe.spec.js b/js/tests/unit/util/swipe.spec.js
index 474e34f65..9252d312b 100644
--- a/js/tests/unit/util/swipe.spec.js
+++ b/js/tests/unit/util/swipe.spec.js
@@ -1,7 +1,7 @@
-import { clearFixture, getFixture } from '../../helpers/fixture'
-import EventHandler from '../../../src/dom/event-handler'
-import Swipe from '../../../src/util/swipe'
-import { noop } from '../../../src/util'
+import EventHandler from '../../../src/dom/event-handler.js'
+import { noop } from '../../../src/util/index.js'
+import Swipe from '../../../src/util/swipe.js'
+import { clearFixture, getFixture } from '../../helpers/fixture.js'
describe('Swipe', () => {
const { Simulator, PointerEvent } = window
@@ -39,17 +39,17 @@ describe('Swipe', () => {
fixtureEl = getFixture()
const cssStyle = [
'<style>',
- ' #fixture .pointer-event {',
- ' touch-action: pan-y;',
+ ' #fixture .pointer-event {',
+ ' touch-action: pan-y;',
' }',
- ' #fixture div {',
- ' width: 300px;',
- ' height: 300px;',
+ ' #fixture div {',
+ ' width: 300px;',
+ ' height: 300px;',
' }',
'</style>'
].join('')
- fixtureEl.innerHTML = '<div id="swipeEl"></div>' + cssStyle
+ fixtureEl.innerHTML = `<div id="swipeEl"></div>${cssStyle}`
swipeEl = fixtureEl.querySelector('div')
})
@@ -78,74 +78,80 @@ describe('Swipe', () => {
})
describe('Config', () => {
- it('Test leftCallback', done => {
- const spyRight = jasmine.createSpy('spy')
- clearPointerEvents()
- defineDocumentElementOntouchstart()
- // eslint-disable-next-line no-new
- new Swipe(swipeEl, {
- leftCallback: () => {
- expect(spyRight).not.toHaveBeenCalled()
- restorePointerEvents()
- done()
- },
- rightCallback: spyRight
- })
-
- mockSwipeGesture(swipeEl, {
- pos: [300, 10],
- deltaX: -300
+ it('Test leftCallback', () => {
+ return new Promise(resolve => {
+ const spyRight = jasmine.createSpy('spy')
+ clearPointerEvents()
+ defineDocumentElementOntouchstart()
+ // eslint-disable-next-line no-new
+ new Swipe(swipeEl, {
+ leftCallback() {
+ expect(spyRight).not.toHaveBeenCalled()
+ restorePointerEvents()
+ resolve()
+ },
+ rightCallback: spyRight
+ })
+
+ mockSwipeGesture(swipeEl, {
+ pos: [300, 10],
+ deltaX: -300
+ })
})
})
- it('Test rightCallback', done => {
- const spyLeft = jasmine.createSpy('spy')
- clearPointerEvents()
- defineDocumentElementOntouchstart()
- // eslint-disable-next-line no-new
- new Swipe(swipeEl, {
- rightCallback: () => {
- expect(spyLeft).not.toHaveBeenCalled()
- restorePointerEvents()
- done()
- },
- leftCallback: spyLeft
- })
-
- mockSwipeGesture(swipeEl, {
- pos: [10, 10],
- deltaX: 300
+ it('Test rightCallback', () => {
+ return new Promise(resolve => {
+ const spyLeft = jasmine.createSpy('spy')
+ clearPointerEvents()
+ defineDocumentElementOntouchstart()
+ // eslint-disable-next-line no-new
+ new Swipe(swipeEl, {
+ rightCallback() {
+ expect(spyLeft).not.toHaveBeenCalled()
+ restorePointerEvents()
+ resolve()
+ },
+ leftCallback: spyLeft
+ })
+
+ mockSwipeGesture(swipeEl, {
+ pos: [10, 10],
+ deltaX: 300
+ })
})
})
- it('Test endCallback', done => {
- clearPointerEvents()
- defineDocumentElementOntouchstart()
- let isFirstTime = true
-
- const callback = () => {
- if (isFirstTime) {
- isFirstTime = false
- return
- }
+ it('Test endCallback', () => {
+ return new Promise(resolve => {
+ clearPointerEvents()
+ defineDocumentElementOntouchstart()
+ let isFirstTime = true
- expect().nothing()
- restorePointerEvents()
- done()
- }
+ const callback = () => {
+ if (isFirstTime) {
+ isFirstTime = false
+ return
+ }
- // eslint-disable-next-line no-new
- new Swipe(swipeEl, {
- endCallback: callback
- })
- mockSwipeGesture(swipeEl, {
- pos: [10, 10],
- deltaX: 300
- })
+ expect().nothing()
+ restorePointerEvents()
+ resolve()
+ }
- mockSwipeGesture(swipeEl, {
- pos: [300, 10],
- deltaX: -300
+ // eslint-disable-next-line no-new
+ new Swipe(swipeEl, {
+ endCallback: callback
+ })
+ mockSwipeGesture(swipeEl, {
+ pos: [10, 10],
+ deltaX: 300
+ })
+
+ mockSwipeGesture(swipeEl, {
+ pos: [300, 10],
+ deltaX: -300
+ })
})
})
})
@@ -157,7 +163,7 @@ describe('Swipe', () => {
deleteDocumentElementOntouchstart()
const swipe = new Swipe(swipeEl)
- spyOn(swipe, '_handleSwipe')
+ const spy = spyOn(swipe, '_handleSwipe')
mockSwipeGesture(swipeEl, {
pos: [300, 10],
@@ -167,56 +173,60 @@ describe('Swipe', () => {
})
restorePointerEvents()
- expect(swipe._handleSwipe).not.toHaveBeenCalled()
+ expect(spy).not.toHaveBeenCalled()
})
- it('should allow swipeRight and call "rightCallback" with pointer events', done => {
- if (!supportPointerEvent) {
- expect().nothing()
- done()
- return
- }
-
- const style = '#fixture .pointer-event { touch-action: none !important; }'
- fixtureEl.innerHTML += style
-
- defineDocumentElementOntouchstart()
- // eslint-disable-next-line no-new
- new Swipe(swipeEl, {
- rightCallback: () => {
- deleteDocumentElementOntouchstart()
+ it('should allow swipeRight and call "rightCallback" with pointer events', () => {
+ return new Promise(resolve => {
+ if (!supportPointerEvent) {
expect().nothing()
- done()
+ resolve()
+ return
}
- })
- mockSwipeGesture(swipeEl, { deltaX: 300 }, 'pointer')
- })
+ const style = '#fixture .pointer-event { touch-action: none !important; }'
+ fixtureEl.innerHTML += style
- it('should allow swipeLeft and call "leftCallback" with pointer events', done => {
- if (!supportPointerEvent) {
- expect().nothing()
- done()
- return
- }
+ defineDocumentElementOntouchstart()
+ // eslint-disable-next-line no-new
+ new Swipe(swipeEl, {
+ rightCallback() {
+ deleteDocumentElementOntouchstart()
+ expect().nothing()
+ resolve()
+ }
+ })
- const style = '#fixture .pointer-event { touch-action: none !important; }'
- fixtureEl.innerHTML += style
+ mockSwipeGesture(swipeEl, { deltaX: 300 }, 'pointer')
+ })
+ })
- defineDocumentElementOntouchstart()
- // eslint-disable-next-line no-new
- new Swipe(swipeEl, {
- leftCallback: () => {
+ it('should allow swipeLeft and call "leftCallback" with pointer events', () => {
+ return new Promise(resolve => {
+ if (!supportPointerEvent) {
expect().nothing()
- deleteDocumentElementOntouchstart()
- done()
+ resolve()
+ return
}
- })
- mockSwipeGesture(swipeEl, {
- pos: [300, 10],
- deltaX: -300
- }, 'pointer')
+ const style = '#fixture .pointer-event { touch-action: none !important; }'
+ fixtureEl.innerHTML += style
+
+ defineDocumentElementOntouchstart()
+ // eslint-disable-next-line no-new
+ new Swipe(swipeEl, {
+ leftCallback() {
+ expect().nothing()
+ deleteDocumentElementOntouchstart()
+ resolve()
+ }
+ })
+
+ mockSwipeGesture(swipeEl, {
+ pos: [300, 10],
+ deltaX: -300
+ }, 'pointer')
+ })
})
})
@@ -266,7 +276,7 @@ describe('Swipe', () => {
expect(Swipe.isSupported()).toBeTrue()
})
- it('should return "false" if "touchstart" not exists in document element and "navigator.maxTouchPoints" are zero (0)', () => {
+ it('should return "false" if "touchstart" not exists in document element and "navigator.maxTouchPoints" are zero (0)', () => {
Object.defineProperty(window.navigator, 'maxTouchPoints', () => 0)
deleteDocumentElementOntouchstart()
diff --git a/js/tests/unit/util/template-factory.spec.js b/js/tests/unit/util/template-factory.spec.js
index 842c480c2..07f4d91c7 100644
--- a/js/tests/unit/util/template-factory.spec.js
+++ b/js/tests/unit/util/template-factory.spec.js
@@ -1,5 +1,5 @@
-import { clearFixture, getFixture } from '../../helpers/fixture'
-import TemplateFactory from '../../../src/util/template-factory'
+import TemplateFactory from '../../../src/util/template-factory.js'
+import { clearFixture, getFixture } from '../../helpers/fixture.js'
describe('TemplateFactory', () => {
let fixtureEl
@@ -86,26 +86,26 @@ describe('TemplateFactory', () => {
const factory = new TemplateFactory({
extraClass: 'testClass'
})
- expect(factory.toHtml().classList.contains('testClass')).toBeTrue()
+ expect(factory.toHtml()).toHaveClass('testClass')
})
it('should add extra classes', () => {
const factory = new TemplateFactory({
extraClass: 'testClass testClass2'
})
- expect(factory.toHtml().classList.contains('testClass')).toBeTrue()
- expect(factory.toHtml().classList.contains('testClass2')).toBeTrue()
+ expect(factory.toHtml()).toHaveClass('testClass')
+ expect(factory.toHtml()).toHaveClass('testClass2')
})
it('should resolve class if function is given', () => {
const factory = new TemplateFactory({
- extraClass: arg => {
+ extraClass(arg) {
expect(arg).toEqual(factory)
return 'testClass'
}
})
- expect(factory.toHtml().classList.contains('testClass')).toBeTrue()
+ expect(factory.toHtml()).toHaveClass('testClass')
})
})
})
@@ -113,11 +113,11 @@ describe('TemplateFactory', () => {
describe('Content', () => {
it('add simple text content', () => {
const template = [
- '<div>' +
- '<div class="foo"></div>' +
- '<div class="foo2"></div>' +
+ '<div>',
+ ' <div class="foo"></div>',
+ ' <div class="foo2"></div>',
'</div>'
- ].join(' ')
+ ].join('')
const factory = new TemplateFactory({
template,
@@ -128,8 +128,8 @@ describe('TemplateFactory', () => {
})
const html = factory.toHtml()
- expect(html.querySelector('.foo').textContent).toBe('bar')
- expect(html.querySelector('.foo2').textContent).toBe('bar2')
+ expect(html.querySelector('.foo').textContent).toEqual('bar')
+ expect(html.querySelector('.foo2').textContent).toEqual('bar2')
})
it('should not fill template if selector not exists', () => {
@@ -140,7 +140,7 @@ describe('TemplateFactory', () => {
content: { '#bar': 'test' }
})
- expect(factory.toHtml().outerHTML).toBe('<div id="foo"></div>')
+ expect(factory.toHtml().outerHTML).toEqual('<div id="foo"></div>')
})
it('should remove template selector, if content is null', () => {
@@ -151,7 +151,7 @@ describe('TemplateFactory', () => {
content: { '#foo': null }
})
- expect(factory.toHtml().outerHTML).toBe('<div></div>')
+ expect(factory.toHtml().outerHTML).toEqual('<div></div>')
})
it('should resolve content if is function', () => {
@@ -162,7 +162,7 @@ describe('TemplateFactory', () => {
content: { '#foo': () => null }
})
- expect(factory.toHtml().outerHTML).toBe('<div></div>')
+ expect(factory.toHtml().outerHTML).toEqual('<div></div>')
})
it('if content is element and "config.html=false", should put content\'s textContent', () => {
@@ -176,9 +176,9 @@ describe('TemplateFactory', () => {
})
const fooEl = factory.toHtml().querySelector('#foo')
- expect(fooEl.innerHTML).not.toBe(contentElement.innerHTML)
- expect(fooEl.textContent).toBe(contentElement.textContent)
- expect(fooEl.textContent).toBe('foobar')
+ expect(fooEl.innerHTML).not.toEqual(contentElement.innerHTML)
+ expect(fooEl.textContent).toEqual(contentElement.textContent)
+ expect(fooEl.textContent).toEqual('foobar')
})
it('if content is element and "config.html=true", should put content\'s outerHtml as child', () => {
@@ -192,8 +192,8 @@ describe('TemplateFactory', () => {
})
const fooEl = factory.toHtml().querySelector('#foo')
- expect(fooEl.innerHTML).toBe(contentElement.outerHTML)
- expect(fooEl.textContent).toBe(contentElement.textContent)
+ expect(fooEl.innerHTML).toEqual(contentElement.outerHTML)
+ expect(fooEl.textContent).toEqual(contentElement.textContent)
})
})
@@ -245,14 +245,15 @@ describe('TemplateFactory', () => {
expect(factory.hasContent()).toBeFalse()
})
})
+
describe('changeContent', () => {
it('should change Content', () => {
const template = [
- '<div>' +
- '<div class="foo"></div>' +
- '<div class="foo2"></div>' +
+ '<div>',
+ ' <div class="foo"></div>',
+ ' <div class="foo2"></div>',
'</div>'
- ].join(' ')
+ ].join('')
const factory = new TemplateFactory({
template,
@@ -276,11 +277,11 @@ describe('TemplateFactory', () => {
it('should change only the given, content', () => {
const template = [
- '<div>' +
- '<div class="foo"></div>' +
- '<div class="foo2"></div>' +
+ '<div>',
+ ' <div class="foo"></div>',
+ ' <div class="foo2"></div>',
'</div>'
- ].join(' ')
+ ].join('')
const factory = new TemplateFactory({
template,