Skip to content

Commit

Permalink
DomUtil function tests (#7547)
Browse files Browse the repository at this point in the history
* Added tests for getStyle, create & remote, and empty elements dom utils.

* Added a few more tests for the DomUtil functions

* Test for testProp, setTransform and setPosition utils

* Added setPosition and getPosition tests

* Added getSizeparentnode and getscale tests

* Added tests for textSelection, imageDrag and outline DomUtils.

* Fix linting errors

* Fixed tests for browser compatibility

* Fixed certain browser specific boundingClientRect issues

* update tests

Co-authored-by: falke-design <design.falke@gmail.com>
  • Loading branch information
LGNorris and Falke-Design authored Apr 15, 2022
1 parent b3e1b24 commit c7aadab
Showing 1 changed file with 380 additions and 3 deletions.
383 changes: 380 additions & 3 deletions spec/suites/dom/DomUtilSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ describe('DomUtil', function () {
beforeEach(function () {
el = document.createElement('div');
el.style.position = 'absolute';
el.style.top = el.style.left = '-10000px';
el.style.top = el.style.left = '0px';
document.body.appendChild(el);
});

Expand Down Expand Up @@ -52,8 +52,385 @@ describe('DomUtil', function () {
expect(el.className).to.eql('foo barz');
});
});
describe('#getStyle', function () {
it('gets the value for a certain style attribute on an element,', function () {
el.style.color = 'black';
expect(L.DomUtil.getStyle(el, 'color')).to.eql('black');
el.style.color = 'green';
expect(L.DomUtil.getStyle(el, 'color')).to.eql('green');
});

(L.Browser.ie ? it.skip : it)("returns empty string if style isn't defined", function () {
var e = document.createElement('div');
expect(L.DomUtil.getStyle(e, "position")).to.be('');
});

it("returns undefined if style don't exist on HTML element or default css", function () {
expect(L.DomUtil.getStyle(el, "random_name_for_style")).to.be(undefined);
});
});

describe("#create", function () {
it("creates an HTML element div without any class name", function () {
var e = L.DomUtil.create("div");
expect(e.className).to.eql('');
expect(e.tagName).to.eql("DIV");
});

it("creates an HTML element div with specified class name", function () {
var e = L.DomUtil.create("div", "test");
expect(e.className).to.eql('test');
expect(e.tagName).to.eql("DIV");
});

it("creates an p element with a div as parent", function () {
var parent = L.DomUtil.create("div");
expect(parent.children.length).to.equal(0);
var child = L.DomUtil.create("p", "test", parent);
expect(child.parentNode === parent).to.be(true);
expect(parent.children.length).to.equal(1);
});
});


describe("#remove", function () {
it("removes element", function () {
var e = L.DomUtil.create("div", "test", el);
L.DomUtil.remove(e);
expect(el.contains(e)).to.be(false);
});

it("does nothing if element hasn't a parent", function () {
var e = L.DomUtil.create("div", "test");
L.DomUtil.remove(e);
expect(document.body.contains(e)).to.be(false);
});
});

describe("#empty", function () {
it("removes all children of element", function () {
L.DomUtil.create("div", "test", el);
L.DomUtil.create("div", "test1", el);
L.DomUtil.create("div", "test2", el);
L.DomUtil.empty(el);
expect(el.childNodes.length).to.be(0);
});

it("does nothing if element doesn't have children", function () {
expect(el.childNodes.length).to.be(0);
L.DomUtil.empty(el);
expect(el.childNodes.length).to.be(0);
});
});

describe('#toFront', function () {
it('moves el to last child position parent element', function () {
var elm = L.DomUtil.create('div', 'childContainer', el);
L.DomUtil.create("div", "test", el);
L.DomUtil.create("div", "test1", el);
expect(el.children.length).to.equal(3);
expect(Array.from(el.children).indexOf(elm)).to.be(0);
L.DomUtil.toFront(elm);
expect(Array.from(el.children).indexOf(elm)).to.be(2);
});

it("doesn't move an element if he's already in the front", function () {
L.DomUtil.create("div", "test", el);
L.DomUtil.create("div", "test1", el);
var e1 = L.DomUtil.create("div", "test2", el);
expect(el.lastChild).to.eql(e1);
L.DomUtil.toFront(e1);
expect(el.lastChild).to.eql(e1);
});

it("doesn't crash if element doesn't have a parent", function () {
var e = L.DomUtil.create("div");
L.DomUtil.toFront(e);
});
});

describe('#toBack', function () {
it('moves el to first child position parent element', function () {
L.DomUtil.create("div", "test", el);
L.DomUtil.create("div", "test1", el);
var elm = L.DomUtil.create('div', 'childContainer', el);
expect(el.children.length).to.equal(3);
expect(Array.from(el.children).indexOf(elm)).to.be(2);
L.DomUtil.toBack(elm);
expect(Array.from(el.children).indexOf(elm)).to.be(0);
});

it("doesn't move an element if it is already in the back", function () {
var e1 = L.DomUtil.create("div", "test", el);
L.DomUtil.create("div", "test1", el);
L.DomUtil.create("div", "test2", el);
expect(el.firstChild).to.be(e1);
L.DomUtil.toBack(el);
expect(el.firstChild).to.be(e1);
});

it("doesn't crash if an element doesn't have a parent", function () {
var e = L.DomUtil.create("div");
L.DomUtil.toBack(e);
});
});

describe('#setClass, #getClass', function () {
it('sets the elements class', function () {
expect(el.classList.contains('newClass')).to.not.be.ok();
L.DomUtil.setClass(el, 'newClass');
expect(el.classList.contains('newClass')).to.be.ok();
});

it('gets the elements class', function () {
expect(L.DomUtil.getClass(el)).to.not.equal('newClass');
L.DomUtil.setClass(el, 'newClass');
expect(L.DomUtil.getClass(el)).to.equal('newClass');
});
});

describe('#setOpacity', function () {
it('sets opacity of element', function () {
L.DomUtil.setOpacity(el, 1);
expect(el.style.opacity).to.equal('1');
L.DomUtil.setOpacity(el, 0.5);
expect(el.style.opacity).to.equal('0.5');
L.DomUtil.setOpacity(el, '0');
expect(el.style.opacity).to.equal('0');
});

it("replaces the class of SGV element by the specified argument", function () {
var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
L.DomUtil.setClass(svg, "testclass");
expect(svg.className.baseVal).to.be("testclass");
});

it("gets the class name of SVG element", function () {
var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
svg.className.baseVal = "testclass";
expect(L.DomUtil.getClass(svg)).to.be("testclass");
});

it('returns empty string if it has no classes', function () {
expect(L.DomUtil.getClass(el)).to.be('');
});
});

// describe('#setPosition', noSpecs);
describe('#testProp', function () {
(L.Browser.ie ? it.skip : it)('check array of style names return first valid style name for element', function () {
var hasProp;
hasProp = L.DomUtil.testProp(['-webkit-transform', '-webkit-transform', '-ms-tranform', '-o-transform']);
expect(hasProp).to.match(/(?:-webkit-transform|-webkit-transform|-ms-tranform|-o-transform)/);
});

it("returns false if property doesn't exist", function () {
expect(L.DomUtil.testProp(["testprop"])).to.be(false);
});
});

describe('#setTransform', function () {
it("resets the transform style of an el.", function () {
expect(L.DomUtil.getStyle(el, 'transform')).to.be.equal('none');

var offset = L.point(200, 200);
var scale = 10;
L.DomUtil.setTransform(el, offset, scale);
var transform = L.DomUtil.getStyle(el, 'transform');
expect(L.DomUtil.getStyle(el, 'transform')).to.be.equal(transform);

var newScale = 20;
var newOffset = L.point(400, 400);
L.DomUtil.setTransform(el, newOffset, newScale);
expect(L.DomUtil.getStyle(el, 'transform')).to.not.be.equal(transform);
});

(L.Browser.ie ? it.skip : it)("reset the 3d CSS transform when offset and scale aren't specified", function () {
L.DomUtil.setTransform(el);
expect(el.style[L.DomUtil.TRANSFORM]).to.be('translate3d(' + 0 + 'px, ' + 0 + 'px, 0px)');
});

(L.Browser.ie ? it.skip : it)("set the 3d CSS transform with just the specified point if scale isn't specified", function () {
L.DomUtil.setTransform(el, new L.Point(1, 1));
expect(el.style[L.DomUtil.TRANSFORM]).to.be('translate3d(' + 1 + 'px, ' + 1 + 'px, 0px)');
});

(L.Browser.ie ? it.skip : it)("set 3d CSS transform to translate3d(0px, 0px, 0) and add to it scale(${scalevalue}) if only scale is specified", function () {
L.DomUtil.setTransform(el, undefined, 5);
expect(el.style[L.DomUtil.TRANSFORM]).to.be('translate3d(' + 0 + 'px, ' + 0 + 'px, 0px) scale(' + 5 + ')');
});

(L.Browser.ie ? it.skip : it)("set the 3d CSS transform with the specified point ant the corresponding scale", function () {
L.DomUtil.setTransform(el, new L.Point(1, 1), 5);
expect(el.style[L.DomUtil.TRANSFORM]).to.be('translate3d(' + 1 + 'px, ' + 1 + 'px, 0px) scale(' + 5 + ')');
});
// TODO: test with Browser.ie3d to true
});

describe('#setPosition, #getPosition', function () {
it("sets position of el to coordinates specified by position.", function () {
expect(L.DomUtil.getStyle(el, 'left')).to.be.equal('0px');
expect(L.DomUtil.getStyle(el, 'top')).to.be.equal('0px');

var x = 50;
var y = 55;
var position = L.point(x, y);
L.DomUtil.setPosition(el, position);
expect(L.DomUtil.getPosition(el)).to.be.eql({x: x, y: y});

var newX = 333;
var newY = 666;
var newPosition = L.point(newX, newY);
L.DomUtil.setPosition(el, newPosition);
expect(L.DomUtil.getPosition(el)).to.be.eql({x: newX, y: newY});
});

it("returns position of an element positioned with setPosition.", function () {
var coordinates = {x: 333, y: 666};
var position = L.point(coordinates);
expect(L.DomUtil.getPosition(el)).to.not.eql(coordinates);
L.DomUtil.setPosition(el, position);
expect(L.DomUtil.getPosition(el)).to.be.an('object');
expect(L.DomUtil.getPosition(el)).to.eql(coordinates);
});

it("returns [0, 0] point if the HTML element wasn't positioned before", function () {
expect(L.DomUtil.getPosition(el)).to.eql(new L.Point(0, 0));
});
});

// describe('#getStyle', noSpecs);
describe('#getSizedParentNode', function () {
it('find nearest parent element where height / width are not null', function () {
var child = document.createElement('div');
var grandChild = document.createElement('div');
el.appendChild(child);
child.appendChild(grandChild);
child.style.width = child.style.height = '500px';
expect(L.DomUtil.getSizedParentNode(grandChild)).to.eql(child);
});

it("throws an error if the element hasn't a parent", function () {
expect(function () {
L.DomUtil.getSizedParentNode(document.createElement('div'));
}).to.throwException();
});
});

describe('#getScale', function () {
it('returns scale of element as x & y scales respectively', function () {
var childEl = document.createElement('div');
childEl.style.width = '250px';
childEl.style.height = '250px';
childEl.style.padding = '15px';
childEl.style.margin = '25px';
el.appendChild(childEl);
var scale = {
x: 1,
y: 1,
boundingClientRect: {
x: 25,
y: 25,
width: 280,
height: 280,
top: 25,
right: 305,
bottom: 305,
left: 25,
}
};
// Not all browsers contain x y inside boundclientRect, always contains top, right, bottom and left properties
expect(L.DomUtil.getScale(childEl).boundingClientRect.top).to.be.equal(scale.boundingClientRect.top);
expect(L.DomUtil.getScale(childEl).boundingClientRect.right).to.be.equal(scale.boundingClientRect.right);
expect(L.DomUtil.getScale(childEl).boundingClientRect.bottom).to.be.equal(scale.boundingClientRect.bottom);
expect(L.DomUtil.getScale(childEl).boundingClientRect.left).to.be.equal(scale.boundingClientRect.left);

childEl.style.padding = '400px';
expect(L.DomUtil.getScale(childEl).boundingClientRect.bottom).to.not.be.equal(scale.boundingClientRect.bottom);
});

(L.Browser.ie ? it.skip : it)("returns x and y to 1 with all boundingClientRect's values to 0 for empty element not added yet to the body", function () {
var newElement = document.createElement("div");
var scale = L.DomUtil.getScale(newElement);
expect(scale.x).to.eql(1);
expect(scale.y).to.eql(1);
expect(scale.boundingClientRect.x).to.eql(0);
expect(scale.boundingClientRect.y).to.eql(0);
expect(scale.boundingClientRect.left).to.eql(0);
expect(scale.boundingClientRect.right).to.eql(0);
expect(scale.boundingClientRect.top).to.eql(0);
expect(scale.boundingClientRect.height).to.eql(0);
expect(scale.boundingClientRect.bottom).to.eql(0);
expect(scale.boundingClientRect.width).to.eql(0);
});
});


describe('#disableTextSelection, #enableTextSelection', function () {
it('disable / enable the selectstart DOM events for the user ', function () {
var selectionPrevented;
function checkPrevented(e) {
if (e.defaultPrevented) {
selectionPrevented = true;
} else {
selectionPrevented = false;
}
}
var child = document.createElement('div');
el.appendChild(child);

L.DomUtil.disableTextSelection();
window.addEventListener('selectstart', checkPrevented);
happen.once(child, {type: 'selectstart'});
expect(selectionPrevented).to.be.ok();

L.DomUtil.enableTextSelection();
happen.once(child, {type: 'selectstart'});
expect(selectionPrevented).to.not.be.ok();
});
});

describe('#disableImageDrag, #enablerImageDrag', function () {
it('disable / enable dragstart DOM events for the user', function () {
var selectionPrevented;
function checkPrevented(e) {
if (e.defaultPrevented) {
selectionPrevented = true;
} else {
selectionPrevented = false;
}
}
var child = document.createElement('div');
el.appendChild(child);

L.DomUtil.disableImageDrag();
window.addEventListener('dragstart', checkPrevented);
happen.once(child, {type: 'dragstart'});
expect(selectionPrevented).to.be.ok();

L.DomUtil.enableImageDrag();
happen.once(child, {type: 'dragstart'});
expect(selectionPrevented).to.not.be.ok();
});
});

describe('#preventOutline, #restoreOutline', function () {
(L.Browser.ie ? it.skip : it)('prevent / restore outline for the element', function () {
var child = document.createElement('div');
el.appendChild(child);
child.tabIndex = 0;
expect(child.style.outline).to.be.equal(child.style.outline);
L.DomUtil.preventOutline(child);
expect(child.style.outline).to.match(/(?:none)/);

// Explicit #restoreOutline through direct call
expect(child.style.outline).to.match(/(?:none)/);
L.DomUtil.restoreOutline(child);
expect(child.style.outline).to.be.equal(child.style.outline);

// Implicit #restoreOutline test through simulation
L.DomUtil.preventOutline(child);
expect(child.style.outline).to.match(/(?:none)/);
happen.once(child, {type: 'keydown'});
expect(child.style.outline).to.be.equal(child.style.outline);
});
});
});

0 comments on commit c7aadab

Please sign in to comment.