mirror of
https://github.com/loot/libloot.git
synced 2026-07-27 14:16:01 -07:00
Refactor loot.game JS code
Refactor the code into a new module that exports a Game class that provides equivalent functionality, with DOM-accessing code moved to event handlers. Also refactored conflicting testing mock definitions to inside the test suite functions where they're used. This will break existing untested code as no Game object is currently instantiated.
This commit is contained in:
@@ -1,4 +1,68 @@
|
||||
'use strict';
|
||||
function onGamePluginsChange(evt) {
|
||||
if (!evt.detail.valuesAreTotals) {
|
||||
evt.detail.totalMessageNo += parseInt(document.getElementById('totalMessageNo').textContent, 10);
|
||||
evt.detail.warnMessageNo += parseInt(document.getElementById('totalWarningNo').textContent, 10);
|
||||
evt.detail.errorMessageNo += parseInt(document.getElementById('totalErrorNo').textContent, 10);
|
||||
evt.detail.totalPluginNo += parseInt(document.getElementById('totalPluginNo').textContent, 10);
|
||||
evt.detail.activePluginNo += parseInt(document.getElementById('activePluginNo').textContent, 10);
|
||||
evt.detail.dirtyPluginNo += parseInt(document.getElementById('dirtyPluginNo').textContent, 10);
|
||||
}
|
||||
|
||||
document.getElementById('filterTotalMessageNo').textContent = evt.detail.totalMessageNo;
|
||||
document.getElementById('totalMessageNo').textContent = evt.detail.totalMessageNo;
|
||||
document.getElementById('totalWarningNo').textContent = evt.detail.warnMessageNo;
|
||||
document.getElementById('totalErrorNo').textContent = evt.detail.errorMessageNo;
|
||||
|
||||
document.getElementById('filterTotalPluginNo').textContent = evt.detail.totalPluginNo;
|
||||
document.getElementById('totalPluginNo').textContent = evt.detail.totalPluginNo;
|
||||
document.getElementById('activePluginNo').textContent = evt.detail.activePluginNo;
|
||||
document.getElementById('dirtyPluginNo').textContent = evt.detail.dirtyPluginNo;
|
||||
}
|
||||
function onGameGlobalMessagesChange(evt) {
|
||||
document.getElementById('filterTotalMessageNo').textContent = parseInt(document.getElementById('filterTotalMessageNo').textContent, 10) + evt.detail.totalDiff;
|
||||
document.getElementById('totalMessageNo').textContent = parseInt(document.getElementById('totalMessageNo').textContent, 10) + evt.detail.totalDiff;
|
||||
document.getElementById('totalWarningNo').textContent = parseInt(document.getElementById('totalWarningNo').textContent, 10) + evt.detail.warningDiff;
|
||||
document.getElementById('totalErrorNo').textContent = parseInt(document.getElementById('totalErrorNo').textContent, 10) + evt.detail.errorDiff;
|
||||
|
||||
/* Remove old messages from UI. */
|
||||
const generalMessagesList = document.getElementById('summary').getElementsByTagName('ul')[0];
|
||||
while (generalMessagesList.firstElementChild) {
|
||||
generalMessagesList.removeChild(generalMessagesList.firstElementChild);
|
||||
}
|
||||
|
||||
/* Add new messages. */
|
||||
if (evt.detail.messages) {
|
||||
evt.detail.messages.forEach((message) => {
|
||||
const li = document.createElement('li');
|
||||
li.className = message.type;
|
||||
/* Use the Marked library for Markdown formatting support. */
|
||||
li.innerHTML = marked(message.content[0].str);
|
||||
generalMessagesList.appendChild(li);
|
||||
});
|
||||
}
|
||||
}
|
||||
function onGameMasterlistChange(evt) {
|
||||
document.getElementById('masterlistRevision').textContent = evt.detail.revision;
|
||||
document.getElementById('masterlistDate').textContent = evt.detail.date;
|
||||
}
|
||||
function onGameFolderChange(evt) {
|
||||
updateSelectedGame(evt.detail.folder);
|
||||
/* Enable/disable the redate plugins option. */
|
||||
let index = undefined;
|
||||
for (let i = 0; i < loot.settings.games.length; ++i) {
|
||||
if (loot.settings.games[i].folder === evt.detail.folder) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
const redateButton = document.getElementById('redatePluginsButton');
|
||||
if (index && loot.settings.games[index].type === 'Skyrim') {
|
||||
redateButton.removeAttribute('disabled');
|
||||
} else {
|
||||
redateButton.setAttribute('disabled', true);
|
||||
}
|
||||
}
|
||||
function onPluginMessageChange(evt) {
|
||||
document.getElementById('filterTotalMessageNo').textContent = parseInt(document.getElementById('filterTotalMessageNo').textContent, 10) + evt.detail.totalDiff;
|
||||
document.getElementById('totalMessageNo').textContent = parseInt(document.getElementById('totalMessageNo').textContent, 10) + evt.detail.totalDiff;
|
||||
@@ -782,4 +846,10 @@ function setupEventHandlers() {
|
||||
/* Set up handler for plugin message and dirty info changes. */
|
||||
document.addEventListener('loot-plugin-message-change', onPluginMessageChange);
|
||||
document.addEventListener('loot-plugin-isdirty-change', onPluginIsDirtyChange);
|
||||
|
||||
/* Set up event handlers for game member variable changes. */
|
||||
document.addEventListener('loot-game-folder-change', onGameFolderChange);
|
||||
document.addEventListener('loot-game-masterlist-change', onGameMasterlistChange);
|
||||
document.addEventListener('loot-game-global-messages-change', onGameGlobalMessagesChange);
|
||||
document.addEventListener('loot-game-plugins-change', onGamePluginsChange);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,257 @@
|
||||
'use strict';
|
||||
|
||||
(function exportModule(root, factory) {
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// AMD. Register as an anonymous module.
|
||||
define([], factory);
|
||||
} else {
|
||||
// Browser globals
|
||||
root.loot = root.loot || {};
|
||||
root.loot.Game = factory();
|
||||
}
|
||||
}(this, () => {
|
||||
return class Game {
|
||||
constructor(obj, l10n) {
|
||||
this.folder = obj.folder || '';
|
||||
this.globalMessages = obj.globalMessages || [];
|
||||
this.masterlist = obj.masterlist || {};
|
||||
this.plugins = obj.plugins || [];
|
||||
|
||||
this.loadOrder = undefined;
|
||||
this.oldLoadOrder = undefined;
|
||||
|
||||
this._notApplicableString = l10n.translate('N/A');
|
||||
}
|
||||
|
||||
get folder() {
|
||||
return this._folder;
|
||||
}
|
||||
|
||||
set folder(folder) {
|
||||
if (folder !== this._folder) {
|
||||
document.dispatchEvent(new CustomEvent('loot-game-folder-change', {
|
||||
detail: { folder },
|
||||
}));
|
||||
}
|
||||
|
||||
this._folder = folder;
|
||||
}
|
||||
|
||||
get globalMessages() {
|
||||
return this._globalMessages;
|
||||
}
|
||||
|
||||
set globalMessages(globalMessages) {
|
||||
/* Update the message counts. */
|
||||
let oldTotal = 0;
|
||||
let newTotal = 0;
|
||||
let oldWarns = 0;
|
||||
let newWarns = 0;
|
||||
let oldErrs = 0;
|
||||
let newErrs = 0;
|
||||
|
||||
if (this._globalMessages) {
|
||||
oldTotal = this._globalMessages.length;
|
||||
this._globalMessages.forEach((message) => {
|
||||
if (message.type === 'warn') {
|
||||
++oldWarns;
|
||||
} else if (message.type === 'error') {
|
||||
++oldErrs;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (globalMessages) {
|
||||
newTotal = globalMessages.length;
|
||||
|
||||
globalMessages.forEach((message) => {
|
||||
if (message.type === 'warn') {
|
||||
++newWarns;
|
||||
} else if (message.type === 'error') {
|
||||
++newErrs;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (newTotal !== oldTotal || newWarns !== oldWarns || newErrs !== oldErrs) {
|
||||
document.dispatchEvent(new CustomEvent('loot-game-global-messages-change', {
|
||||
detail: {
|
||||
totalDiff: newTotal - oldTotal,
|
||||
warningDiff: newWarns - oldWarns,
|
||||
errorDiff: newErrs - oldErrs,
|
||||
messages: globalMessages,
|
||||
},
|
||||
}));
|
||||
}
|
||||
|
||||
this._globalMessages = globalMessages;
|
||||
}
|
||||
|
||||
get masterlist() {
|
||||
return this._masterlist;
|
||||
}
|
||||
|
||||
set masterlist(masterlist) {
|
||||
if (masterlist !== this._masterlist
|
||||
&& (masterlist === undefined || this._masterlist === undefined
|
||||
|| masterlist.revision !== this._masterlist.revision
|
||||
|| masterlist.date !== this._masterlist.date)) {
|
||||
let revision = this._notApplicableString;
|
||||
let date = this._notApplicableString;
|
||||
if (masterlist && masterlist.revision) {
|
||||
revision = masterlist.revision;
|
||||
}
|
||||
if (masterlist && masterlist.date) {
|
||||
date = masterlist.date;
|
||||
}
|
||||
|
||||
document.dispatchEvent(new CustomEvent('loot-game-masterlist-change', {
|
||||
detail: {
|
||||
revision,
|
||||
date,
|
||||
},
|
||||
}));
|
||||
}
|
||||
|
||||
this._masterlist = masterlist;
|
||||
}
|
||||
|
||||
get plugins() {
|
||||
return this._plugins;
|
||||
}
|
||||
|
||||
set plugins(plugins) {
|
||||
/* Update plugin and message counts. Unlike for global messages
|
||||
it's not worth calculating the count differences, just count
|
||||
from zero. */
|
||||
let totalMessageNo = 0;
|
||||
let warnMessageNo = 0;
|
||||
let errorMessageNo = 0;
|
||||
let activePluginNo = 0;
|
||||
let dirtyPluginNo = 0;
|
||||
|
||||
/* Include global messages in the count. */
|
||||
if (this.globalMessages) {
|
||||
totalMessageNo = this.globalMessages.length;
|
||||
this.globalMessages.forEach((message) => {
|
||||
if (message.type === 'warn') {
|
||||
++warnMessageNo;
|
||||
} else if (message.type === 'error') {
|
||||
++errorMessageNo;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
plugins.forEach((plugin) => {
|
||||
if (plugin.isActive) {
|
||||
++activePluginNo;
|
||||
}
|
||||
if (plugin.isDirty) {
|
||||
++dirtyPluginNo;
|
||||
}
|
||||
if (plugin.messages) {
|
||||
totalMessageNo += plugin.messages.length;
|
||||
plugin.messages.forEach((message) => {
|
||||
if (message.type === 'warn') {
|
||||
++warnMessageNo;
|
||||
} else if (message.type === 'error') {
|
||||
++errorMessageNo;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
document.dispatchEvent(new CustomEvent('loot-game-plugins-change', {
|
||||
detail: {
|
||||
valuesAreTotals: true,
|
||||
totalMessageNo,
|
||||
warnMessageNo,
|
||||
errorMessageNo,
|
||||
totalPluginNo: plugins.length,
|
||||
activePluginNo,
|
||||
dirtyPluginNo,
|
||||
},
|
||||
}));
|
||||
|
||||
this._plugins = plugins;
|
||||
}
|
||||
|
||||
appendPlugin(plugin) {
|
||||
let totalChange = 0;
|
||||
let warnChange = 0;
|
||||
let errorChange = 0;
|
||||
let activeChange = 0;
|
||||
let dirtyChange = 0;
|
||||
|
||||
if (plugin.isActive) {
|
||||
++activeChange;
|
||||
}
|
||||
if (plugin.isDirty) {
|
||||
++dirtyChange;
|
||||
}
|
||||
if (plugin.messages) {
|
||||
totalChange += plugin.messages.length;
|
||||
plugin.messages.forEach((message) => {
|
||||
if (message.type === 'warn') {
|
||||
++warnChange;
|
||||
} else if (message.type === 'error') {
|
||||
++errorChange;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
document.dispatchEvent(new CustomEvent('loot-game-plugins-change', {
|
||||
detail: {
|
||||
valuesAreTotals: false,
|
||||
totalMessageNo: totalChange,
|
||||
warnMessageNo: warnChange,
|
||||
errorMessageNo: errorChange,
|
||||
totalPluginNo: 1,
|
||||
activePluginNo: activeChange,
|
||||
dirtyPluginNo: dirtyChange,
|
||||
},
|
||||
}));
|
||||
|
||||
this._plugins.push(plugin);
|
||||
}
|
||||
|
||||
removePluginAtIndex(index) {
|
||||
let totalChange = 0;
|
||||
let warnChange = 0;
|
||||
let errorChange = 0;
|
||||
let activeChange = 0;
|
||||
let dirtyChange = 0;
|
||||
|
||||
if (this._plugins[index].isActive) {
|
||||
--activeChange;
|
||||
}
|
||||
if (this._plugins[index].isDirty) {
|
||||
--dirtyChange;
|
||||
}
|
||||
if (this._plugins[index].messages) {
|
||||
totalChange -= this._plugins[index].messages.length;
|
||||
this._plugins[index].messages.forEach((message) => {
|
||||
if (message.type === 'warn') {
|
||||
--warnChange;
|
||||
} else if (message.type === 'error') {
|
||||
--errorChange;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
document.dispatchEvent(new CustomEvent('loot-game-plugins-change', {
|
||||
detail: {
|
||||
valuesAreTotals: false,
|
||||
totalMessageNo: totalChange,
|
||||
warnMessageNo: warnChange,
|
||||
errorMessageNo: errorChange,
|
||||
totalPluginNo: -1,
|
||||
activePluginNo: activeChange,
|
||||
dirtyPluginNo: dirtyChange,
|
||||
},
|
||||
}));
|
||||
|
||||
this._plugins.splice(index, 1);
|
||||
}
|
||||
};
|
||||
}));
|
||||
@@ -141,3 +141,19 @@ function setFilteredUIData(filtersState) {
|
||||
document.getElementById('hiddenMessageNo').textContent = hiddenMessageNo;
|
||||
});
|
||||
}
|
||||
/* Call whenever game is changed or game menu / game table are rewritten. */
|
||||
function updateSelectedGame(gameFolder) {
|
||||
document.getElementById('gameMenu').value = gameFolder;
|
||||
|
||||
/* Also disable deletion of the game's row in the settings dialog. */
|
||||
const table = document.getElementById('gameTable');
|
||||
for (let i = 0; i < table.tBodies[0].rows.length; ++i) {
|
||||
if (table.tBodies[0].rows[i].getElementsByClassName('folder').length > 0) {
|
||||
if (table.tBodies[0].rows[i].getElementsByClassName('folder')[0].value === gameFolder) {
|
||||
table.setReadOnly(table.tBodies[0].rows[i], ['delete']);
|
||||
} else {
|
||||
table.setReadOnly(table.tBodies[0].rows[i], ['delete'], false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-228
@@ -1,110 +1,6 @@
|
||||
var loot = {
|
||||
installedGames: [],
|
||||
settings: {},
|
||||
game: {
|
||||
folder: '',
|
||||
globalMessages: [],
|
||||
masterlist: {},
|
||||
plugins: [],
|
||||
|
||||
/* Call whenever game is changed or game menu / game table are rewritten. */
|
||||
updateSelectedGame: function() {
|
||||
document.getElementById('gameMenu').value = this.folder;
|
||||
|
||||
/* Also disable deletion of the game's row in the settings dialog. */
|
||||
var table = document.getElementById('gameTable');
|
||||
for (var i = 0; i < table.tBodies[0].rows.length; ++i) {
|
||||
if (table.tBodies[0].rows[i].getElementsByClassName('folder').length > 0) {
|
||||
if (table.tBodies[0].rows[i].getElementsByClassName('folder')[0].value == this.folder) {
|
||||
table.setReadOnly(table.tBodies[0].rows[i], ['delete']);
|
||||
} else {
|
||||
table.setReadOnly(table.tBodies[0].rows[i], ['delete'], false);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/* Call whenever game is changed. */
|
||||
updateRedatePluginsButtonState: function() {
|
||||
/* Also enable/disable the redate plugins option. */
|
||||
var index = undefined;
|
||||
for (var i = 0; i < loot.settings.games.length; ++i) {
|
||||
if (loot.settings.games[i].folder == this.folder) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
var redateButton = document.getElementById('redatePluginsButton');
|
||||
if (index != undefined && loot.settings.games[index].type == 'Skyrim') {
|
||||
redateButton.removeAttribute('disabled');
|
||||
} else {
|
||||
redateButton.setAttribute('disabled', true);
|
||||
}
|
||||
},
|
||||
|
||||
pluginsObserver: function(changes) {
|
||||
changes.forEach(function(change){
|
||||
/* Need to handle plugin addition and removal.
|
||||
Update plugin and message counts. */
|
||||
var totalChange = 0;
|
||||
var warnChange = 0;
|
||||
var errorChange = 0;
|
||||
var activeChange = 0;
|
||||
var dirtyChange = 0;
|
||||
|
||||
if (change.addedCount > 0) {
|
||||
/* Addition */
|
||||
for (var i = change.index; i < change.index + change.addedCount; ++i) {
|
||||
if (change.object[i].isActive) {
|
||||
++activeChange;
|
||||
}
|
||||
if (change.object[i].isDirty) {
|
||||
++dirtyChange;
|
||||
}
|
||||
if (change.object[i].messages) {
|
||||
totalChange += change.object[i].messages.length;
|
||||
change.object[i].messages.forEach(function(message) {
|
||||
if (message.type == 'warn') {
|
||||
++warnChange;
|
||||
} else if (message.type == 'error') {
|
||||
++errorChange;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
if (change.removed.length > 0) {
|
||||
/* Removal */
|
||||
change.removed.forEach(function(plugin){
|
||||
if (plugin.isActive) {
|
||||
--activeChange;
|
||||
}
|
||||
if (plugin.isDirty) {
|
||||
--dirtyChange;
|
||||
}
|
||||
if (plugin.messages) {
|
||||
totalChange -= plugin.messages.length;
|
||||
plugin.messages.forEach(function(message) {
|
||||
if (message.type == 'warn') {
|
||||
--warnChange;
|
||||
} else if (message.type == 'error') {
|
||||
--errorChange;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
document.getElementById('filterTotalMessageNo').textContent = parseInt(document.getElementById('filterTotalMessageNo').textContent, 10) + totalChange;
|
||||
document.getElementById('totalMessageNo').textContent = document.getElementById('filterTotalMessageNo').textContent;
|
||||
document.getElementById('totalWarningNo').textContent = parseInt(document.getElementById('totalWarningNo').textContent, 10) + warnReduction;
|
||||
document.getElementById('totalErrorNo').textContent = parseInt(document.getElementById('totalErrorNo').textContent, 10) + errorReduction;
|
||||
document.getElementById('filterTotalPluginNo').textContent = parseInt(document.getElementById('filterTotalPluginNo').textContent, 10) + change.addedCount - change.removed.length;
|
||||
document.getElementById('totalPluginNo').textContent = document.getElementById('filterTotalPluginNo').textContent;
|
||||
document.getElementById('activePluginNo').textContent = parseInt(document.getElementById('activePluginNo').textContent, 10) + activeReduction;
|
||||
document.getElementById('dirtyPluginNo').textContent = parseInt(document.getElementById('dirtyPluginNo').textContent, 10) + dirtyReduction;
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/* Call whenever installedGames is changed or game menu is rewritten. */
|
||||
updateEnabledGames: function() {
|
||||
@@ -156,7 +52,7 @@ var loot = {
|
||||
document.getElementById('updateMasterlist').checked = this.settings.updateMasterlist;
|
||||
|
||||
this.updateEnabledGames();
|
||||
this.game.updateSelectedGame();
|
||||
updateSelectedGame(this.game.folder);
|
||||
},
|
||||
|
||||
/* Observer for loot members. */
|
||||
@@ -170,129 +66,6 @@ var loot = {
|
||||
});
|
||||
},
|
||||
|
||||
/* Observer for loot.game members. */
|
||||
gameObserver: function(changes) {
|
||||
changes.forEach(function(change){
|
||||
if (change.name == 'folder') {
|
||||
change.object.updateSelectedGame();
|
||||
change.object.updateRedatePluginsButtonState();
|
||||
} else if (change.name == 'masterlist') {
|
||||
if (change.object[change.name] && change.object[change.name].revision) {
|
||||
document.getElementById('masterlistRevision').textContent = change.object[change.name].revision;
|
||||
} else {
|
||||
document.getElementById('masterlistRevision').textContent = loot.l10n.translate("N/A");
|
||||
}
|
||||
if (change.object[change.name] && change.object[change.name].date) {
|
||||
document.getElementById('masterlistDate').textContent = change.object[change.name].date;
|
||||
} else {
|
||||
document.getElementById('masterlistDate').textContent = loot.l10n.translate("N/A");
|
||||
}
|
||||
} else if (change.name == 'globalMessages') {
|
||||
/* For the messages, they don't have a JS 'class' so need to everything
|
||||
here. Count up the global message types that exist, then remove them
|
||||
and add the new ones, counting their types, then update the message
|
||||
counts. I tried using an observer for this, but it wouldn't fire for
|
||||
some reason. */
|
||||
|
||||
var oldTotal = change.oldValue.length;
|
||||
var newTotal = 0;
|
||||
var oldWarn = 0;
|
||||
var newWarn = 0;
|
||||
var oldErr = 0;
|
||||
var newErr = 0;
|
||||
|
||||
/* Count up old warnings and errors. */
|
||||
change.oldValue.forEach(function(message){
|
||||
if (message.type == 'warn') {
|
||||
++oldWarn;
|
||||
} else if (message.type == 'error') {
|
||||
++oldErr;
|
||||
}
|
||||
});
|
||||
|
||||
/* Remove old messages from UI. */
|
||||
var generalMessagesList = document.getElementById('summary').getElementsByTagName('ul')[0];
|
||||
while (generalMessagesList.firstElementChild) {
|
||||
generalMessagesList.removeChild(generalMessagesList.firstElementChild);
|
||||
}
|
||||
|
||||
/* Add new messages. */
|
||||
if (change.object[change.name]) {
|
||||
newTotal = change.object[change.name].length;
|
||||
change.object[change.name].forEach(function(message){
|
||||
var li = document.createElement('li');
|
||||
li.className = message.type;
|
||||
/* Use the Marked library for Markdown formatting support. */
|
||||
li.innerHTML = marked(message.content[0].str);
|
||||
generalMessagesList.appendChild(li);
|
||||
|
||||
if (li.className == 'warn') {
|
||||
++newWarn;
|
||||
} else if (li.className == 'error') {
|
||||
++newErr;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* Update message counts in UI. */
|
||||
document.getElementById('filterTotalMessageNo').textContent = parseInt(document.getElementById('filterTotalMessageNo').textContent, 10) + newTotal - oldTotal;
|
||||
document.getElementById('totalMessageNo').textContent = document.getElementById('filterTotalMessageNo').textContent;
|
||||
document.getElementById('totalWarningNo').textContent = parseInt(document.getElementById('totalWarningNo').textContent, 10) + newWarn - oldWarn;
|
||||
document.getElementById('totalErrorNo').textContent = parseInt(document.getElementById('totalErrorNo').textContent, 10) + newErr - oldErr;
|
||||
} else if (change.name == 'plugins') {
|
||||
/* Update plugin and message counts. Unlike for global messages
|
||||
it's not worth calculating the count differences, just count
|
||||
from zero. */
|
||||
var totalMessageNo = 0;
|
||||
var warnMessageNo = 0;
|
||||
var errorMessageNo = 0;
|
||||
var activePluginNo = 0;
|
||||
var dirtyPluginNo = 0;
|
||||
|
||||
if (change.object.globalMessages) {
|
||||
totalMessageNo = change.object.globalMessages.length;
|
||||
change.object.globalMessages.forEach(function(message){
|
||||
if (message.type == 'warn') {
|
||||
++warnMessageNo;
|
||||
} else if (message.type == 'error') {
|
||||
++errorMessageNo;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
change.object[change.name].forEach(function(plugin) {
|
||||
if (plugin.isActive) {
|
||||
++activePluginNo;
|
||||
}
|
||||
if (plugin.isDirty) {
|
||||
++dirtyPluginNo;
|
||||
}
|
||||
if (plugin.messages) {
|
||||
totalMessageNo += plugin.messages.length;
|
||||
plugin.messages.forEach(function(message) {
|
||||
if (message.type == 'warn') {
|
||||
++warnMessageNo;
|
||||
} else if (message.type == 'error') {
|
||||
++errorMessageNo;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
document.getElementById('filterTotalMessageNo').textContent = totalMessageNo;
|
||||
document.getElementById('totalMessageNo').textContent = totalMessageNo;
|
||||
document.getElementById('totalWarningNo').textContent = warnMessageNo;
|
||||
document.getElementById('totalErrorNo').textContent = errorMessageNo;
|
||||
document.getElementById('filterTotalPluginNo').textContent = change.object[change.name].length;
|
||||
document.getElementById('totalPluginNo').textContent = change.object[change.name].length;
|
||||
document.getElementById('activePluginNo').textContent = activePluginNo;
|
||||
document.getElementById('dirtyPluginNo').textContent = dirtyPluginNo;
|
||||
|
||||
/* Register a new array observer. */
|
||||
Array.observe(change.object[change.name], change.object.pluginsObserver);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/* Returns a cefQuery as a Promise. */
|
||||
query: function(request) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
|
||||
@@ -12,9 +12,11 @@
|
||||
|
||||
<script>mocha.setup('bdd')</script>
|
||||
<script src="../../../../gui/html/js/filters.js"></script>
|
||||
<script src="../../../../gui/html/js/game.js"></script>
|
||||
<script src="../../../../gui/html/js/plugin.js"></script>
|
||||
<script src="../../../../gui/html/js/translator.js"></script>
|
||||
<script src="test_filters.js"></script>
|
||||
<script src="test_game.js"></script>
|
||||
<script src="test_plugin.js"></script>
|
||||
<script src="test_translator.js"></script>
|
||||
<script>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
'use strict';
|
||||
|
||||
/* Mock the Translator class. */
|
||||
class Translator {
|
||||
translate(text) {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
|
||||
describe('Filters', () => {
|
||||
/* Mock the Translator class. */
|
||||
class Translator {
|
||||
translate(text) {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
|
||||
let l10n;
|
||||
|
||||
beforeEach(() => {
|
||||
|
||||
@@ -0,0 +1,361 @@
|
||||
'use strict';
|
||||
|
||||
describe('Game', () => {
|
||||
/* Mock the Translator class. */
|
||||
class Translator {
|
||||
translate(text) {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
let l10n;
|
||||
|
||||
beforeEach(() => {
|
||||
l10n = new Translator();
|
||||
});
|
||||
|
||||
describe('#constructor()', () => {
|
||||
it('should throw if passed no paramters', () => {
|
||||
(() => { new loot.Game(); }).should.throw(); // eslint-disable-line no-new
|
||||
});
|
||||
|
||||
it('should throw if passed no l10n parameter', () => {
|
||||
(() => { new loot.Game({}); }).should.throw(); // eslint-disable-line no-new
|
||||
});
|
||||
|
||||
it('should not throw if passed an empty object as the first parameter', () => {
|
||||
(() => { new loot.Game({}, l10n); }).should.not.throw(); // eslint-disable-line no-new
|
||||
});
|
||||
|
||||
it('should set folder to a blank string by default', () => {
|
||||
const game = new loot.Game({}, l10n);
|
||||
game.folder.should.equal('');
|
||||
});
|
||||
|
||||
it('should set folder to the object\'s value if defined', () => {
|
||||
const game = new loot.Game({ folder: 'test' }, l10n);
|
||||
game.folder.should.equal('test');
|
||||
});
|
||||
|
||||
it('should set globalMessages to an empty array by default', () => {
|
||||
const game = new loot.Game({}, l10n);
|
||||
game.globalMessages.should.deepEqual([]);
|
||||
});
|
||||
|
||||
it('should set globalMessages to the object\'s value if defined', () => {
|
||||
const game = new loot.Game({ globalMessages: ['test'] }, l10n);
|
||||
game.globalMessages.should.deepEqual(['test']);
|
||||
});
|
||||
|
||||
it('should set masterlist to an empty object by default', () => {
|
||||
const game = new loot.Game({}, l10n);
|
||||
game.masterlist.should.deepEqual({});
|
||||
});
|
||||
|
||||
it('should set masterlist to the object\'s value if defined', () => {
|
||||
const game = new loot.Game({ masterlist: { revision: 0 } }, l10n);
|
||||
game.masterlist.should.deepEqual({ revision: 0 });
|
||||
});
|
||||
|
||||
it('should set plugins to an empty array by default', () => {
|
||||
const game = new loot.Game({}, l10n);
|
||||
game.plugins.should.deepEqual([]);
|
||||
});
|
||||
|
||||
it('should set plugins to the object\'s value if defined', () => {
|
||||
const game = new loot.Game({ plugins: ['test'] }, l10n);
|
||||
game.plugins.should.deepEqual(['test']);
|
||||
});
|
||||
|
||||
it('should set loadOrder to undefined by default', () => {
|
||||
const game = new loot.Game({}, l10n);
|
||||
should(game.loadOrder).be.undefined();
|
||||
});
|
||||
|
||||
it('should set loadOrder to undefined even if the object\'s value if defined', () => {
|
||||
const game = new loot.Game({ loadOrder: ['test'] }, l10n);
|
||||
should(game.loadOrder).be.undefined();
|
||||
});
|
||||
|
||||
it('should set oldLoadOrder to undefined by default', () => {
|
||||
const game = new loot.Game({}, l10n);
|
||||
should(game.oldLoadOrder).be.undefined();
|
||||
});
|
||||
|
||||
it('should set oldLoadOrder to undefined even if the object\'s value if defined', () => {
|
||||
const game = new loot.Game({ oldLoadOrder: ['test'] }, l10n);
|
||||
should(game.oldLoadOrder).be.undefined();
|
||||
});
|
||||
|
||||
it('should initialise _notApplicableString', () => {
|
||||
const game = new loot.Game({ oldLoadOrder: ['test'] }, l10n);
|
||||
game._notApplicableString.should.equal('N/A');
|
||||
});
|
||||
});
|
||||
|
||||
describe('#folder', () => {
|
||||
let game;
|
||||
let handleEvent;
|
||||
|
||||
beforeEach(() => {
|
||||
game = new loot.Game({}, l10n);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
document.removeEventListener('loot-game-folder-change', handleEvent);
|
||||
});
|
||||
|
||||
it('setting value should not dispatch an event if the new value is equal to the old one', (done) => {
|
||||
handleEvent = () => {
|
||||
done(new Error('Should not have fired an event'));
|
||||
};
|
||||
document.addEventListener('loot-game-folder-change', handleEvent);
|
||||
|
||||
game.folder = game.folder;
|
||||
setTimeout(done, 100);
|
||||
});
|
||||
|
||||
it('setting value should dispatch an event if the new value differs from the old one', (done) => {
|
||||
handleEvent = (evt) => {
|
||||
evt.detail.folder.should.equal('test');
|
||||
done();
|
||||
};
|
||||
document.addEventListener('loot-game-folder-change', handleEvent);
|
||||
|
||||
game.folder = 'test';
|
||||
});
|
||||
});
|
||||
|
||||
describe('#globalMessages', () => {
|
||||
let game;
|
||||
let handleEvent;
|
||||
|
||||
beforeEach(() => {
|
||||
game = new loot.Game({}, l10n);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
document.removeEventListener('loot-game-global-messages-change', handleEvent);
|
||||
});
|
||||
|
||||
it('setting value should not dispatch an event if the new value is equal to the old one', (done) => {
|
||||
handleEvent = () => {
|
||||
done(new Error('Should not have fired an event'));
|
||||
};
|
||||
document.addEventListener('loot-game-global-messages-change', handleEvent);
|
||||
|
||||
game.globalMessages = game.globalMessages;
|
||||
setTimeout(done, 100);
|
||||
});
|
||||
|
||||
it('setting value should dispatch an event if the new value differs from the old one', (done) => {
|
||||
const newMessages = [
|
||||
{ type: 'warn' },
|
||||
{ type: 'error' },
|
||||
];
|
||||
handleEvent = (evt) => {
|
||||
evt.detail.messages.should.deepEqual(newMessages);
|
||||
evt.detail.totalDiff.should.equal(2);
|
||||
evt.detail.errorDiff.should.equal(1);
|
||||
evt.detail.warningDiff.should.equal(1);
|
||||
done();
|
||||
};
|
||||
document.addEventListener('loot-game-global-messages-change', handleEvent);
|
||||
|
||||
game.globalMessages = newMessages;
|
||||
});
|
||||
});
|
||||
|
||||
describe('#masterlist', () => {
|
||||
let game;
|
||||
let handleEvent;
|
||||
|
||||
beforeEach(() => {
|
||||
game = new loot.Game({}, l10n);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
document.removeEventListener('loot-game-masterlist-change', handleEvent);
|
||||
});
|
||||
|
||||
it('setting value should not dispatch an event if the new value is equal to the old one', (done) => {
|
||||
handleEvent = () => {
|
||||
done(new Error('Should not have fired an event'));
|
||||
};
|
||||
document.addEventListener('loot-game-masterlist-change', handleEvent);
|
||||
|
||||
game.masterlist = game.masterlist;
|
||||
setTimeout(done, 100);
|
||||
});
|
||||
|
||||
it('setting value should dispatch an event if the new value differs from the old one', (done) => {
|
||||
const newMasterlist = {
|
||||
revision: 'foo',
|
||||
date: 'bar',
|
||||
};
|
||||
handleEvent = (evt) => {
|
||||
evt.detail.should.deepEqual(newMasterlist);
|
||||
done();
|
||||
};
|
||||
document.addEventListener('loot-game-masterlist-change', handleEvent);
|
||||
|
||||
game.masterlist = newMasterlist;
|
||||
});
|
||||
|
||||
it('setting value to undefined should dispatch an event with the details being the not applicable string', (done) => {
|
||||
handleEvent = (evt) => {
|
||||
evt.detail.revision.should.equal(game._notApplicableString);
|
||||
evt.detail.date.should.equal(game._notApplicableString);
|
||||
done();
|
||||
};
|
||||
document.addEventListener('loot-game-masterlist-change', handleEvent);
|
||||
|
||||
game.masterlist = undefined;
|
||||
});
|
||||
});
|
||||
|
||||
describe('#plugins', () => {
|
||||
let game;
|
||||
let handleEvent;
|
||||
|
||||
beforeEach(() => {
|
||||
game = new loot.Game({}, l10n);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
document.removeEventListener('loot-game-plugins-change', handleEvent);
|
||||
});
|
||||
|
||||
it('setting value should dispatch an event if the new value is equal to the old one', (done) => {
|
||||
handleEvent = () => {
|
||||
done();
|
||||
};
|
||||
document.addEventListener('loot-game-plugins-change', handleEvent);
|
||||
|
||||
game.plugins = game.plugins;
|
||||
});
|
||||
|
||||
it('setting value should dispatch an event if the new value differs from the old one', (done) => {
|
||||
const newPlugins = [
|
||||
{
|
||||
isActive: true,
|
||||
messages: [{ type: 'warn' }],
|
||||
},
|
||||
{
|
||||
isDirty: true,
|
||||
messages: [{ type: 'say' }],
|
||||
},
|
||||
];
|
||||
handleEvent = (evt) => {
|
||||
evt.detail.valuesAreTotals.should.be.true();
|
||||
evt.detail.totalMessageNo.should.equal(4);
|
||||
evt.detail.warnMessageNo.should.equal(2);
|
||||
evt.detail.errorMessageNo.should.equal(1);
|
||||
evt.detail.totalPluginNo.should.equal(2);
|
||||
evt.detail.activePluginNo.should.equal(1);
|
||||
evt.detail.dirtyPluginNo.should.equal(1);
|
||||
done();
|
||||
};
|
||||
document.addEventListener('loot-game-plugins-change', handleEvent);
|
||||
|
||||
/* Set global messages to check they are also counted in the totals. */
|
||||
game.globalMessages = [
|
||||
{ type: 'warn' },
|
||||
{ type: 'error' },
|
||||
];
|
||||
|
||||
game.plugins = newPlugins;
|
||||
});
|
||||
});
|
||||
|
||||
describe('#appendPlugin()', () => {
|
||||
let game;
|
||||
let handleEvent;
|
||||
|
||||
beforeEach(() => {
|
||||
game = new loot.Game({}, l10n);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
document.removeEventListener('loot-game-plugins-change', handleEvent);
|
||||
});
|
||||
|
||||
it('should append the passed plugin to the plugins array', () => {
|
||||
const newPlugin = {
|
||||
isActive: true,
|
||||
messages: [{ type: 'warn' }],
|
||||
};
|
||||
game.appendPlugin(newPlugin);
|
||||
|
||||
game.plugins[0].should.deepEqual(newPlugin);
|
||||
});
|
||||
|
||||
it('should dispatch an event with the correct counter differences', (done) => {
|
||||
handleEvent = (evt) => {
|
||||
evt.detail.valuesAreTotals.should.be.false();
|
||||
evt.detail.totalMessageNo.should.equal(1);
|
||||
evt.detail.warnMessageNo.should.equal(1);
|
||||
evt.detail.errorMessageNo.should.equal(0);
|
||||
evt.detail.totalPluginNo.should.equal(1);
|
||||
evt.detail.activePluginNo.should.equal(1);
|
||||
evt.detail.dirtyPluginNo.should.equal(0);
|
||||
done();
|
||||
};
|
||||
document.addEventListener('loot-game-plugins-change', handleEvent);
|
||||
|
||||
/* Set global messages to check they are also counted in the totals. */
|
||||
game.globalMessages = [
|
||||
{ type: 'warn' },
|
||||
{ type: 'error' },
|
||||
];
|
||||
|
||||
game.appendPlugin({
|
||||
isActive: true,
|
||||
messages: [{ type: 'warn' }],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#removePluginAtIndex()', () => {
|
||||
let game;
|
||||
let handleEvent;
|
||||
|
||||
beforeEach(() => {
|
||||
game = new loot.Game({}, l10n);
|
||||
game._plugins = [{
|
||||
isActive: true,
|
||||
messages: [{ type: 'warn' }],
|
||||
}];
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
document.removeEventListener('loot-game-plugins-change', handleEvent);
|
||||
});
|
||||
|
||||
it('should remove the passed plugin to the plugins array', () => {
|
||||
game.removePluginAtIndex(0);
|
||||
game.plugins.length.should.equal(0);
|
||||
});
|
||||
|
||||
it('should dispatch an event with the correct counter differences', (done) => {
|
||||
handleEvent = (evt) => {
|
||||
evt.detail.valuesAreTotals.should.be.false();
|
||||
evt.detail.totalMessageNo.should.equal(-1);
|
||||
evt.detail.warnMessageNo.should.equal(-1);
|
||||
evt.detail.errorMessageNo.should.equal(0);
|
||||
evt.detail.totalPluginNo.should.equal(-1);
|
||||
evt.detail.activePluginNo.should.equal(-1);
|
||||
evt.detail.dirtyPluginNo.should.equal(0);
|
||||
done();
|
||||
};
|
||||
document.addEventListener('loot-game-plugins-change', handleEvent);
|
||||
|
||||
/* Set global messages to check they are also counted in the totals. */
|
||||
game.globalMessages = [
|
||||
{ type: 'warn' },
|
||||
{ type: 'error' },
|
||||
];
|
||||
|
||||
game.removePluginAtIndex(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -699,7 +699,6 @@ describe('PluginCardContent', () => {
|
||||
});
|
||||
|
||||
describe('#messages', () => {
|
||||
|
||||
it('should return message objects mapped from the plugin\'s message objects', () => {
|
||||
plugin.getCardContent(filters).messages.should.deepEqual([
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user