На веб-сайте, за который я отвечаю, мне пришлось написать IIFE, чтобы он служил основой страницы (ранее такого не было, и мы не используем какую-либо платформу (Angular, React,Vue, ...) в наших приложениях).(Насколько мне известно, это реализация шаблона проектирования модулей в JavaScript.) В настоящее время он настроен для обработки сценариев одного типа, но теперь он должен обрабатывать гораздо больше.
Он объявлен в источнике следующим образом:
const menuState = (function() {
class MenuData {
constructor(attached = [], available = []) {
// attached,available MUST be arrays!
if ((!Array.isArray(attached)) || (!Array.isArray(available))) {
throw TypeError("passed data MUST be in the form of Arrays!")
}
this.attached = attached;
this.available = available;
}
add(entities) {
// entities MUST be Array
if (!Array.isArray(entities)) throw ReferenceError("entities must be array")
// from here, we simply move from this.available to this.attached, the entities
// but first, let's check if they're even available
if (hasEntities(entities, this.available)) {
// attach them
this.attached = this.attached.concat(entities)
// they are no longer available
this.available= this.available
.filter(excluderFactory(entities))
}
// if they're not attached, that is an error
if (!hasEntities(entities, this.attached)) {
throw Error('The entities you were trying to add were neither attached nor available')
}
}
remove(entities) {
// entities MUST be Array
if (!Array.isArray(entities)) throw ReferenceError("entities must be array")
// from here, we simply move from this.attached to this.available, the entities
// but first, let's check if they're even attached
if (hasEntities(entities, this.attached)) {
// make them available
this.available = this.available.concat(entities)
// detach them
this.attached = this.attached
.filter(excluderFactory(entities))
}
// if they're not available, that is an error
if (!hasEntities(entities, this.available)) {
throw Error('The entities you were trying to remove were neither attached nor available')
}
}
};
let _categories = new MenuData(),
_items = new MenuData()
let _itemPool = [],
_categoryItems = {}
/**
* Determines if an array has entities with an Id.
* @param {Object[]} entities
* @param {Object[]} arrayToCheck
* @returns {boolean} whether arrayToCheck has objects with entities' Ids.
*/
function hasEntities(entities, arrayToCheck) {
for (let idx in entities) {
if (arrayToCheck.find((element) => element.Id === entities[idx].Id)) {
if (idx == entities.length - 1) {
return true;
}
continue;
}
return false;
}
}
/**
* Returns a callback for the purpose of excluding entities
* @param {Object[]} entities the entities to exclude
*/
function excluderFactory(entities) {
return function(model) {
return !entities.find((entity) => entity.Id === model.Id)
}
}
return {
// some methods to expose to other parts of the page
}
})()
Итак, я подумал о том, чтобы попробовать какую-нибудь управляемую тестированием разработку во внешнем интерфейсе, записав в бизнес-требованиях как провальные тесты.
Как я думаю об этом
Я решил использовать Mocha с Chai.js для утверждений.Однако, если не считать буквального копирования и вставки тестируемого модуля непосредственно в тестовую среду, а затем после его копирования и вставки обратно в исходный код, я не знаю, как можно получить доступ к этой переменной висходный файл, без необходимости делать специальные вещи, такие как добавление export
строк к исходному коду.
Каков объективно лучший способ сделать это?