Created
January 30, 2017 12:58
-
-
Save dima117/121d3d5a3608fec7dd77d8b053096d23 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function(global) { | |
global.expect || (global.expect = chai.expect); | |
var Assertion = chai.Assertion, | |
helpers = { | |
/** | |
* Плюрализация | |
* @param {Array} forms формы слова [1, 2, 5] | |
* @param {Number} count количество | |
* @returns {String} | |
*/ | |
pluralizeWord: function(forms, count) { | |
var lang = u.consts('lang') || 'ru'; | |
if (lang == 'ru' || lang == 'ua') { | |
count %= 100; | |
if (count >= 5 && count <= 20) { | |
return forms[2]; | |
} | |
count %= 10; | |
if (count == 1) { | |
return forms[0]; | |
} else if (count < 5 && count > 0) { | |
return forms[1]; | |
} | |
return forms[2]; | |
} else if (lang == 'en' || lang == 'tr') { | |
if (count == 1) return forms[0]; | |
return forms[1]; | |
} | |
throw 'unsupported lang'; | |
}, | |
/** | |
* Формирование строки для отображения количества элементов | |
* @param {Array} forms формы слова [1, 2, 5] | |
* @param {Number} count количество | |
* @param {String} delimiter разделитель | |
* @returns {String} | |
* @example | |
* | |
* u.pluralize(['яблоко', 'яблока', 'яблок'], 5) | |
* // => '5 яблок' | |
*/ | |
pluralize: function(forms, count, delimiter) { | |
return count + (delimiter || ' ') + u.pluralizeWord(forms, count); | |
} | |
}; | |
/** | |
* Наличие модификатора | |
* | |
* expect(block).to.haveMod(block.elem('inner'), 'elem-mod-name'); | |
* expect(block).to.not.haveMod(block.elem('inner'), 'elem-mod-name'); | |
* | |
* expect(block).to.haveMod(block.elem('inner'), 'elem-mod-name', 'elem-mod-val'); | |
* expect(block).to.not.haveMod(block.elem('inner'), 'elem-mod-name', 'elem-mod-val'); | |
* | |
* expect(block).to.haveMod('state'); | |
* expect(block).to.not.haveMod('state'); | |
* | |
* expect(block).to.haveMod('state', 'bla'); | |
* expect(block).to.not.haveMod('state', 'bla'); | |
* | |
* @param {Object} [elem] | |
* @param {String} modName | |
* @param {String} [modVal] | |
* @public | |
*/ | |
function haveMod(elem, modName, modVal) { | |
var len = arguments.length, | |
block = this._obj, | |
who, | |
actModVal; | |
if (len == 2 && typeof elem == 'string') { | |
modVal = arguments[1]; | |
modName = arguments[0]; | |
elem = undefined; | |
} else if (len == 3 && typeof elem == 'string') { // @deprecated: выпилить из b-time-targeting-holidays.test.js (committed 100880) | |
elem = block.elem(elem); | |
} else if (len == 1) { | |
modName = arguments[0]; | |
elem = undefined; | |
} | |
who = elem ? 'элемент блока' : 'блок'; | |
actModVal = elem ? block.getMod(elem, modName) : block.getMod(modName); | |
!modVal ? | |
this.assert( | |
elem ? block.hasMod(elem, modName) : block.hasMod(modName), | |
'\nожидается: ' + who + ' имеет модификатор #{exp}' + | |
'\nактуально: ' + who + ' не имеет модификатор #{exp}', | |
'\nожидается: ' + who + ' не имеет модификатор #{exp}' + | |
'\nактуально: ' + who + ' имеет модификатор #{exp} со значением #{act}', | |
modName, | |
actModVal | |
) : | |
this.assert( | |
elem ? block.hasMod(elem, modName, modVal) : block.hasMod(modName, modVal), | |
'\nожидается: ' + who + ' имеет модификатор \'' + modName + '\' со значением #{exp}' + | |
'\nактуально: ' + who + ' имеет модификатор \'' + modName + '\' со значением #{act}', | |
'\nожидается: ' + who + ' не имеет модификатор \'' + modName + '\' со значением #{exp}' + | |
'\nактуально: ' + who + ' имеет модификатор \'' + modName + '\' со значением #{act}', | |
modVal, | |
actModVal | |
); | |
} | |
/** | |
* Существование|Отсутствие одного элемента в DOM-дереве | |
* | |
* expect(block).to.haveElem('action'); | |
* expect(block).to.not.haveElem('action'); | |
* | |
* expect(block).to.haveElem('action', 'state', 'current'); | |
* | |
* @param {String} name | |
* @param {String} [modName] | |
* @param {String} [modVal] | |
* @public | |
*/ | |
function haveElem(name, modName, modVal) { | |
return modName ? | |
haveElems.call(this, name, modName, modVal, 1) : | |
haveElems.call(this, name, 1); | |
} | |
/** | |
* Существование|Отсутствие элементов в DOM-дереве | |
* | |
* expect(block).to.haveElems('action'); | |
* expect(block).to.not.haveElems('action'); | |
* | |
* expect(block).to.haveElems('action', 3); | |
* | |
* @param {String} name | |
* @param {String} [modName] | |
* @param {String} [modVal] | |
* @param {Number} [count] | |
* @public | |
*/ | |
function haveElems(name, modName, modVal, count) { | |
var block = this._obj, | |
text = ['раз', 'раза'], | |
currentCount; | |
if (modName && typeof modName == 'string') { | |
currentCount = block.findElem(name, modName, modVal).length; | |
name = [name, modName, modVal].join('_'); | |
} else { | |
currentCount = block.findElem(name).length; | |
count = modName; | |
} | |
if (arguments.length % 2) { | |
// не передан параметр count | |
this.assert( | |
currentCount > 0, | |
'\nожидается: элемент #{exp} существует\nактуально: элемент #{exp} не существует', | |
'\nожидается: элемент #{exp} не существует\nактуально: элемент #{exp} существует', | |
name | |
); | |
} else { | |
// передан параметр count | |
this.assert( | |
currentCount === count, | |
'\nожидается: элемент #{exp} встречается ' + helpers.pluralize(text, count) + | |
'\nактуально: элемент #{exp} встречается #{act} раз', | |
'\nожидается: элемент #{exp} не встречается ' + helpers.pluralize(text, count) + | |
'\nактуально: элемент #{exp} встречается #{act} раз', | |
name, | |
currentCount | |
); | |
} | |
} | |
/** | |
* Триггер BEM-событий блока | |
* | |
* @example | |
* После создания блока | |
* expect(block).to.triggerEvent('new-goal'); | |
* expect(block).to.triggerEvent('new-goal', { goal: 1 }); | |
* expect(block).to.triggerEvent('new-goal', function() { block.trigger('new-goal) }); | |
* expect(block).to.triggerEvent('new-goal', { goal: 1 }, function() { block.trigger('new-goal', { goal: 1 }) }); | |
* | |
* До создания блока | |
* expect(BEM.blocks['b-block']).to.triggerEvent('popup-content-inited'); | |
* expect(BEM.blocks['b-block']).to.triggerEvent('popup-content-inited', { empty: true }); | |
* expect(BEM.blocks['b-block']).to.triggerEvent('popup-content-inited', function() { block.trigger('popup-content-inited') }); | |
* expect(BEM.blocks['b-block']).to.triggerEvent('popup-content-inited', { empty: true }, function() { block.trigger('popup-content-inited', { empty: true }) }); | |
* | |
* @param {String} event | |
* @param {Object} [data] | |
* @param {Function} [actionCallback] функция, выполнение которой вызовет ожидаемое событие | |
* @public | |
* | |
*/ | |
function triggerEvent(event, data, actionCallback) { | |
var block = this._obj, | |
newEvent, | |
newData; | |
if (arguments.length == 2 && typeof data == 'function') { | |
actionCallback = data; | |
data = undefined; | |
} | |
if (actionCallback) { | |
sinon.spy(block, 'trigger'); | |
actionCallback(); | |
} else { | |
if (!block.trigger.id) { | |
throw new TypeError('В тесте не хватает sinon.spy(\'trigger\')'); | |
} | |
} | |
data && block.trigger.firstCall && (newData = block.trigger.firstCall.args[1]); | |
this.assert( | |
block.trigger.called, | |
'\nожидается: блок тригерит событие \'' + event + (data ? ' с \'#{exp}\'' : '') + | |
'\nактуально: блок не тригерит событие', | |
'\nожидается: блок не тригерит событие' + | |
'\nактуально: блок тригерит событие \'' + event + (newData ? ' с \'#{act}\'' : ''), | |
data, | |
newData | |
); | |
if (!block.trigger.called) return; | |
newEvent = block.trigger.firstCall.args[0].type || block.trigger.firstCall.args[0]; | |
if (data) { | |
this.assert( | |
newEvent === event && u._.isEqual(data, newData), | |
'\n' + | |
'ожидается: блок тригерит событие \'' + event + '\' с \'#{exp}\'\n' + | |
'актуально: блок тригерит событие \'' + newEvent + '\' с \'#{act}\'', | |
'', | |
data, | |
newData | |
); | |
} else { | |
this.assert( | |
newEvent === event, | |
'\n' + | |
'ожидается: блок тригерит событие #{exp}\n' + | |
'актуально: блок тригерит событие #{act}', | |
'', | |
event, | |
newEvent | |
); | |
} | |
if (actionCallback) { | |
block.trigger.restore(); | |
} | |
} | |
/** | |
* Существование|Отсутствие одного блока внутри | |
* | |
* expect(block).to.haveBlock('input'); | |
* expect(block).to.not.haveBlock('input'); | |
* | |
* expect(block).to.haveBlock('input', 'disabled', 'yes'); | |
* | |
* @param {String|jQuery} [elem] | |
* @param {String|Object} blockParams | |
* @param {String} blockParams.block | |
* @param {String} blockParams.modName | |
* @param {String} blockParams.modVal | |
* @public | |
*/ | |
function haveBlock(elem, blockParams) { | |
return arguments.length == 2 ? | |
haveBlocks.call(this, elem, blockParams, 1) : | |
haveBlocks.call(this, elem, 1); | |
} | |
/** | |
* Существование|Отсутствие блоков внутри | |
* | |
* expect(block).to.haveBlocks('input'); | |
* expect(block).to.not.haveBlocks('input'); | |
* | |
* expect(block).to.haveBlocks('input', 3); | |
* | |
* @param {String|jQuery} [elem] | |
* @param {String|Object} blockParams | |
* @param {String} blockParams.block | |
* @param {String} blockParams.modName | |
* @param {String} blockParams.modVal | |
* @param {Number} [count] | |
* @public | |
*/ | |
function haveBlocks(elem, blockParams, count) { | |
if (arguments.length == 2) { | |
if (typeof blockParams === 'number') { | |
// не передан элемент | |
count = blockParams; | |
blockParams = elem; | |
elem = undefined; | |
} | |
//else { не передано кол-во элементов } | |
} else if (arguments.length == 1) { | |
blockParams = elem; | |
elem = undefined; | |
} | |
var block = this._obj, | |
text = ['раз', 'раза'], | |
currentCount = block | |
.findBlocksInside(elem && (typeof elem === 'string' ? block.findElem(elem) : elem), blockParams) | |
.length, | |
countExist = typeof count !== 'undefined', | |
blockName = typeof blockParams === 'string' ? | |
blockParams : | |
BEM.INTERNAL.buildClass(blockParams.block, blockParams.modName, blockParams.modVal); | |
if (countExist) { | |
this.assert( | |
currentCount === count, | |
'\nожидается: блок #{exp} встречается ' + helpers.pluralize(text, count) + | |
'\nактуально: блок #{exp} встречается #{act} раз', | |
'', | |
blockName, | |
currentCount | |
); | |
} else { | |
this.assert( | |
currentCount > 0, | |
'\nожидается: блок #{exp} существует\nактуально: элемент #{exp} не существует', | |
'\nожидается: блок #{exp} не существует\nактуально: элемент #{exp} существует', | |
blockName | |
); | |
} | |
} | |
Assertion.addMethod('haveMod', haveMod); | |
Assertion.addMethod('haveElem', haveElem); | |
Assertion.addMethod('haveElems', haveElems); | |
Assertion.addMethod('haveBlock', haveBlock); | |
Assertion.addMethod('haveBlocks', haveBlocks); | |
Assertion.addMethod('triggerEvent', triggerEvent); | |
}(window)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment