UNPKG

@schukai/monster

Version:

Monster is a simple library for creating fast, robust and lightweight websites.

352 lines (313 loc) 13.2 kB
/******** Convert chai-dom 1.8.1 to es module, without any other modification. From https://github.com/nathanboktae/chai-dom/blob/86c3423/chai-dom.js See https://github.com/nathanboktae/chai-dom/issues/38 Usage: import { chaiDom } from '<path-to>/chai-dom'; chai.use(chaiDom); Copyright (c) 2015 Nathan Black and other contributors This work is licensed under the terms of the MIT license. For a copy, see <https://opensource.org/licenses/MIT>. **********/ export function chaiDom(chai, utils) { var flag = utils.flag, elToString = function(el) { let desc if (isNodeList(el)) { if (el.length === 0) return 'empty NodeList' desc = Array.prototype.slice.call(el, 0, 5).map(elToString).join(', ') return el.length > 5 ? desc + '... (+' + (el.length - 5) + ' more)' : desc } if (!isHTMLElement(el)) { return String(el) } desc = el.tagName.toLowerCase() if (el.id) { desc += '#' + el.id } if (el.className) { desc += '.' + String(el.className).replace(/\s+/g, '.') } Array.prototype.forEach.call(el.attributes, function(attr) { if (attr.name !== 'class' && attr.name !== 'id') { desc += '[' + attr.name + (attr.value ? '="' + attr.value + '"]' : ']') } }) return desc }, attrAssert = function(name, val) { let el = flag(this, 'object'), actual = el.getAttribute(name) if (!flag(this, 'negate') || undefined === val) { this.assert( !!el.attributes[name] , 'expected ' + elToString(el) + ' to have an attribute #{exp}' , 'expected ' + elToString(el) + ' not to have an attribute #{exp}' , name ) } if (undefined !== val) { this.assert( val === actual , 'expected ' + elToString(el) + ' to have an attribute ' + utils.inspect(name) + ' with the value #{exp}, but the value was #{act}' , 'expected ' + elToString(el) + ' not to have an attribute ' + utils.inspect(name) + ' with the value #{act}' , val , actual ) } flag(this, 'object', actual) }, isHTMLElement = function(el) { return el.nodeType === 1 // window.Node.ELEMENT_NODE }, isNodeList = function(obj) { return Object.prototype.toString.call(obj) === '[object NodeList]' } utils.elToString = elToString chai.Assertion.addMethod('attr', attrAssert) chai.Assertion.addMethod('attribute', attrAssert) chai.Assertion.addMethod('class', function(className) { var el = flag(this, 'object') this.assert( el.classList.contains(className) , 'expected ' + elToString(el) + ' to have class #{exp}' , 'expected ' + elToString(el) + ' not to have class #{exp}' , className ) }) chai.Assertion.addMethod('id', function(id) { var el = flag(this, 'object') this.assert( el.id == id , 'expected ' + elToString(el) + ' to have id #{exp}' , 'expected ' + elToString(el) + ' not to have id #{exp}' , id ) }) chai.Assertion.addMethod('html', function(html) { var el = flag(this, 'object'), actual = flag(this, 'object').innerHTML if (flag(this, 'contains')) { this.assert( actual.indexOf(html) >= 0 , 'expected #{act} to contain HTML #{exp}' , 'expected #{act} not to contain HTML #{exp}' , html , actual ) } else { this.assert( actual === html , 'expected ' + elToString(el) + ' to have HTML #{exp}, but the HTML was #{act}' , 'expected ' + elToString(el) + ' not to have HTML #{exp}' , html , actual ) } }) chai.Assertion.addChainableMethod('trimmed', null, function() { flag(this, 'trim-text', true) }) chai.Assertion.addMethod('text', function(text) { var obj = flag(this, 'object'), contains = flag(this, 'contains'), trim = flag(this, 'trim-text'), actual, result if (isNodeList(obj)) { actual = Array.prototype.map.call(obj, function(el) { return trim ? el.textContent.trim() : el.textContent }) if (Array.isArray(text)) { result = contains ? text[flag(this, 'negate') ? 'some' : 'every'](function(t) { return Array.prototype.some.call(obj, function(el) { return (trim ? el.textContent.trim() : el.textContent) === t }) }) : utils.eql(actual, text) actual = actual.join() text = text.join() } else { actual = actual.join('') result = contains ? actual.indexOf(text) >= 0 : actual === text } } else { actual = trim ? obj.textContent.trim() : obj.textContent result = contains ? actual.indexOf(text) >= 0 : actual === text } var objDesc = elToString(obj), textMsg = trim ? 'trimmed text' : 'text' if (contains) { this.assert( result , 'expected ' + objDesc + ' to contain #{exp}, but the ' + textMsg + ' was #{act}' , 'expected ' + objDesc + ' not to contain #{exp}, but the ' + textMsg + ' was #{act}' , text , actual ) } else { this.assert( result , 'expected ' + objDesc + ' to have ' + textMsg + ' #{exp}, but the ' + textMsg + ' was #{act}' , 'expected ' + objDesc + ' not to have ' + textMsg + ' #{exp}' , text , actual ) } }) chai.Assertion.addMethod('value', function(value) { var el = flag(this, 'object'), actual = flag(this, 'object').value this.assert( flag(this, 'object').value === value , 'expected ' + elToString(el) + ' to have value #{exp}, but the value was #{act}' , 'expected ' + elToString(el) + ' not to have value #{exp}' , value , actual ) }) chai.Assertion.overwriteProperty('exist', function(_super) { return function() { var obj = flag(this, 'object') if (isNodeList(obj)) { this.assert( obj.length > 0 , 'expected an empty NodeList to have nodes' , 'expected ' + elToString(obj) + ' to not exist') } else { _super.apply(this, arguments) } } }) chai.Assertion.overwriteProperty('empty', function(_super) { return function() { var obj = flag(this, 'object') if (isHTMLElement(obj)) { this.assert( obj.children.length === 0 , 'expected ' + elToString(obj) + ' to be empty' , 'expected ' + elToString(obj) + ' to not be empty') } else if (isNodeList(obj)) { this.assert( obj.length === 0 , 'expected ' + elToString(obj) + ' to be empty' , 'expected ' + elToString(obj) + ' to not be empty') } else { _super.apply(this, arguments) } } }) chai.Assertion.overwriteChainableMethod('length', function(_super) { return function(length) { var obj = flag(this, 'object') if (isNodeList(obj) || isHTMLElement(obj)) { var actualLength = obj.children ? obj.children.length : obj.length this.assert( actualLength === length , 'expected ' + elToString(obj) + ' to have #{exp} children but it had #{act} children' , 'expected ' + elToString(obj) + ' to not have #{exp} children' , length , actualLength ) } else { _super.apply(this, arguments) } } }, function(_super) { return function() { _super.call(this) } } ) chai.Assertion.overwriteMethod('match', function(_super) { return function(selector) { var obj = flag(this, 'object') if (isHTMLElement(obj)) { this.assert( obj.matches(selector) , 'expected ' + elToString(obj) + ' to match #{exp}' , 'expected ' + elToString(obj) + ' to not match #{exp}' , selector ) } else if (isNodeList(obj)) { this.assert( (!!obj.length && Array.prototype.every.call(obj, function(el) { return el.matches(selector) })) , 'expected ' + elToString(obj) + ' to match #{exp}' , 'expected ' + elToString(obj) + ' to not match #{exp}' , selector ) } else { _super.apply(this, arguments) } } }) chai.Assertion.overwriteChainableMethod('contain', function(_super) { return function(subitem) { var obj = flag(this, 'object') if (isHTMLElement(obj)) { if (typeof subitem === 'string') { this.assert( !!obj.querySelector(subitem) , 'expected ' + elToString(obj) + ' to contain #{exp}' , 'expected ' + elToString(obj) + ' to not contain #{exp}' , subitem) } else { this.assert( obj.contains(subitem) , 'expected ' + elToString(obj) + ' to contain ' + elToString(subitem) , 'expected ' + elToString(obj) + ' to not contain ' + elToString(subitem)) } } else { _super.apply(this, arguments) } } }, function(_super) { return function() { _super.call(this) } } ) chai.Assertion.addMethod('descendant', function(subitem) { var obj = flag(this, 'object'), actual = subitem if (typeof subitem === 'string') { actual = obj.querySelector(subitem) this.assert( !!actual , 'expected ' + elToString(obj) + ' to have descendant #{exp}' , 'expected ' + elToString(obj) + ' to not have descendant #{exp}' , subitem) } else { this.assert( obj.contains(subitem) , 'expected ' + elToString(obj) + ' to contain ' + elToString(subitem) , 'expected ' + elToString(obj) + ' to not contain ' + elToString(subitem)) } flag(this, 'object', actual) }) chai.Assertion.addMethod('descendants', function(selector) { var obj = flag(this, 'object'), actual = obj.querySelectorAll(selector) this.assert( !!actual.length , 'expected ' + elToString(obj) + ' to have descendants #{exp}' , 'expected ' + elToString(obj) + ' to not have descendants #{exp}' , selector) flag(this, 'object', actual) }) chai.Assertion.addProperty('displayed', function() { var el = flag(this, 'object'), actual = document.body.contains(el) ? window.getComputedStyle(el).display : el.style.display this.assert( actual !== 'none' , 'expected ' + elToString(el) + ' to be displayed, but it was not' , 'expected ' + elToString(el) + ' to not be displayed, but it was as ' + actual , actual ) }) chai.Assertion.addProperty('visible', function() { var el = flag(this, 'object'), actual = document.body.contains(el) ? window.getComputedStyle(el).visibility : el.style.visibility this.assert( actual !== 'hidden' && actual !== 'collapse' , 'expected ' + elToString(el) + ' to be visible, but it was ' + (actual === 'hidden' ? 'hidden' : 'collapsed') , 'expected ' + elToString(el) + ' to not be visible, but it was' , actual ) }) }