diff --git a/CHANGELOG.md b/CHANGELOG.md index b61657d7..0204550d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,6 +45,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Basic set of tests for clock module - Run e2e test in Travis - Estonian Translation. +- Add test for compliments module for parts of day ### Fixed diff --git a/js/main.js b/js/main.js index fde5564d..e1a13d8a 100644 --- a/js/main.js +++ b/js/main.js @@ -308,43 +308,36 @@ var MM = (function() { var setSelectionMethodsForModules = function(modules) { /* withClass(className) - * filters a collection of modules based on classname(s). + * calls modulesByClass to filter modules with the specified classes. * * argument className string/array - one or multiple classnames. (array or space divided) * * return array - Filtered collection of modules. */ var withClass = function(className) { - var searchClasses = className; - if (typeof className === "string") { - searchClasses = className.split(" "); - } - - var newModules = modules.filter(function(module) { - var classes = module.data.classes.toLowerCase().split(" "); - - for (var c in searchClasses) { - var searchClass = searchClasses[c]; - if (classes.indexOf(searchClass.toLowerCase()) !== -1) { - return true; - } - } - - return false; - }); - - setSelectionMethodsForModules(newModules); - return newModules; + return modulesByClass(className, true); }; /* exceptWithClass(className) - * filters a collection of modules based on classname(s). (NOT) + * calls modulesByClass to filter modules without the specified classes. * * argument className string/array - one or multiple classnames. (array or space divided) * * return array - Filtered collection of modules. */ var exceptWithClass = function(className) { + return modulesByClass(className, false); + }; + + /* modulesByClass(className, include) + * filters a collection of modules based on classname(s). + * + * argument className string/array - one or multiple classnames. (array or space divided) + * argument include boolean - if the filter should include or exclude the modules with the specific classes. + * + * return array - Filtered collection of modules. + */ + var modulesByClass = function(className, include) { var searchClasses = className; if (typeof className === "string") { searchClasses = className.split(" "); @@ -356,11 +349,11 @@ var MM = (function() { for (var c in searchClasses) { var searchClass = searchClasses[c]; if (classes.indexOf(searchClass.toLowerCase()) !== -1) { - return false; + return include; } } - return true; + return !include; }); setSelectionMethodsForModules(newModules); diff --git a/js/module.js b/js/module.js index dfd5f2bc..457b9772 100644 --- a/js/module.js +++ b/js/module.js @@ -203,22 +203,7 @@ var Module = Class.extend({ * argument callback function - Function called when done. */ loadStyles: function (callback) { - var self = this; - var styles = this.getStyles(); - - var loadNextStyle = function () { - if (styles.length > 0) { - var nextStyle = styles[0]; - Loader.loadFile(nextStyle, self, function () { - styles = styles.slice(1); - loadNextStyle(); - }); - } else { - callback(); - } - }; - - loadNextStyle(); + this.loadDependencies("getStyles", callback); }, /* loadScripts() @@ -227,22 +212,32 @@ var Module = Class.extend({ * argument callback function - Function called when done. */ loadScripts: function (callback) { - var self = this; - var scripts = this.getScripts(); + this.loadDependencies("getScripts", callback); + }, - var loadNextScript = function () { - if (scripts.length > 0) { - var nextScript = scripts[0]; - Loader.loadFile(nextScript, self, function () { - scripts = scripts.slice(1); - loadNextScript(); + /* loadDependencies(funcName, callback) + * Helper method to load all dependencies. + * + * argument funcName string - Function name to call to get scripts or styles. + * argument callback function - Function called when done. + */ + loadDependencies: function (funcName, callback) { + var self = this; + var dependencies = this[funcName](); + + var loadNextDependency = function () { + if (dependencies.length > 0) { + var nextDependency = dependencies[0]; + Loader.loadFile(nextDependency, self, function () { + dependencies = dependencies.slice(1); + loadNextDependency(); }); } else { callback(); } }; - loadNextScript(); + loadNextDependency(); }, /* loadScripts() diff --git a/modules/default/calendar/calendar.js b/modules/default/calendar/calendar.js index 72808c1f..19440998 100644 --- a/modules/default/calendar/calendar.js +++ b/modules/default/calendar/calendar.js @@ -327,54 +327,54 @@ Module.register("calendar", { /* symbolForUrl(url) * Retrieves the symbol for a specific url. * - * argument url sting - Url to look for. + * argument url string - Url to look for. * * return string - The Symbol */ symbolForUrl: function (url) { - for (var c in this.config.calendars) { - var calendar = this.config.calendars[c]; - if (calendar.url === url && typeof calendar.symbol === "string") { - return calendar.symbol; - } - } - - return this.config.defaultSymbol; + return this.getCalendarProperty(url, "symbol", this.config.defaultSymbol); }, /* colorForUrl(url) * Retrieves the color for a specific url. * - * argument url sting - Url to look for. + * argument url string - Url to look for. * * return string - The Color */ colorForUrl: function (url) { - for (var c in this.config.calendars) { - var calendar = this.config.calendars[c]; - if (calendar.url === url && typeof calendar.color === "string") { - return calendar.color; - } - } - - return "#fff"; + return this.getCalendarProperty(url, "color", "#fff"); }, + /* countTitleForUrl(url) * Retrieves the name for a specific url. * - * argument url sting - Url to look for. + * argument url string - Url to look for. * * return string - The Symbol */ countTitleForUrl: function (url) { + return this.getCalendarProperty(url, "repeatingCountTitle", this.config.defaultRepeatingCountTitle); + }, + + /* getCalendarProperty(url, property, defaultValue) + * Helper method to retrieve the property for a specific url. + * + * argument url string - Url to look for. + * argument property string - Property to look for. + * argument defaultValue string - Value if property is not found. + * + * return string - The Property + */ + getCalendarProperty: function (url, property, defaultValue) { for (var c in this.config.calendars) { var calendar = this.config.calendars[c]; - if (calendar.url === url && typeof calendar.repeatingCountTitle === "string") { - return calendar.repeatingCountTitle; + if (calendar.url === url && typeof calendar[property] === "string") { + return calendar[property]; } } - return this.config.defaultRepeatingCountTitle; + return defaultValue; }, /* shorten(string, maxLength) diff --git a/modules/default/calendar/calendarfetcher.js b/modules/default/calendar/calendarfetcher.js index e24ee004..d5ca075e 100644 --- a/modules/default/calendar/calendarfetcher.js +++ b/modules/default/calendar/calendarfetcher.js @@ -52,6 +52,10 @@ var CalendarFetcher = function(url, reloadInterval, maximumEntries, maximumNumbe var limitFunction = function(date, i) {return i < maximumEntries;}; + var eventDate = function(event, time) { + return (event[time].length === 8) ? moment(event[time], "YYYYMMDD") : moment(new Date(event[time])); + }; + for (var e in data) { var event = data[e]; var now = new Date(); @@ -70,10 +74,10 @@ var CalendarFetcher = function(url, reloadInterval, maximumEntries, maximumNumbe if (event.type === "VEVENT") { - var startDate = (event.start.length === 8) ? moment(event.start, "YYYYMMDD") : moment(new Date(event.start)); + var startDate = eventDate(event, "start"); var endDate; if (typeof event.end !== "undefined") { - endDate = (event.end.length === 8) ? moment(event.end, "YYYYMMDD") : moment(new Date(event.end)); + endDate = eventDate(event, "end"); } else { if (!isFacebookBirthday) { endDate = startDate; diff --git a/modules/default/clock/clock.js b/modules/default/clock/clock.js index 1882c52e..e15fbbbd 100644 --- a/modules/default/clock/clock.js +++ b/modules/default/clock/clock.js @@ -74,23 +74,18 @@ Module.register("clock",{ if (this.config.timezone) { now.tz(this.config.timezone); } - if (this.config.clockBold === true) { - timeString = now.format("HH[]mm[]"); - } else { - timeString = now.format("HH:mm"); + + var hourSymbol = "HH"; + if (this.config.timeFormat !== 24) { + hourSymbol = "h"; } - if (this.config.timeFormat !== 24) { - // var now = new Date(); - // var hours = now.getHours() % 12 || 12; - if (this.config.clockBold === true) { - //timeString = hours + moment().format("[]mm[]"); - timeString = now.format("h[]mm[]"); - } else { - //timeString = hours + moment().format(":mm"); - timeString = now.format("h:mm"); - } + if (this.config.clockBold === true) { + timeString = now.format(hourSymbol + "[]mm[]"); + } else { + timeString = now.format(hourSymbol + ":mm"); } + if(this.config.showDate){ dateWrapper.innerHTML = now.format("dddd, LL"); } @@ -203,30 +198,29 @@ Module.register("clock",{ digitalWrapper.appendChild(dateWrapper); digitalWrapper.appendChild(timeWrapper); + var appendClocks = function(condition, pos1, pos2) { + var padding = [0,0,0,0]; + padding[(placement === condition) ? pos1 : pos2] = "20px"; + analogWrapper.style.padding = padding.join(" "); + if (placement === condition) { + wrapper.appendChild(analogWrapper); + wrapper.appendChild(digitalWrapper); + } else { + wrapper.appendChild(digitalWrapper); + wrapper.appendChild(analogWrapper); + } + }; + if (placement === "left" || placement === "right") { digitalWrapper.style.display = "inline-block"; digitalWrapper.style.verticalAlign = "top"; analogWrapper.style.display = "inline-block"; - if (placement === "left") { - analogWrapper.style.padding = "0 20px 0 0"; - wrapper.appendChild(analogWrapper); - wrapper.appendChild(digitalWrapper); - } else { - analogWrapper.style.padding = "0 0 0 20px"; - wrapper.appendChild(digitalWrapper); - wrapper.appendChild(analogWrapper); - } + + appendClocks("left", 1, 3); } else { digitalWrapper.style.textAlign = "center"; - if (placement === "top") { - analogWrapper.style.padding = "0 0 20px 0"; - wrapper.appendChild(analogWrapper); - wrapper.appendChild(digitalWrapper); - } else { - analogWrapper.style.padding = "20px 0 0 0"; - wrapper.appendChild(digitalWrapper); - wrapper.appendChild(analogWrapper); - } + + appendClocks("top", 2, 0); } } diff --git a/tests/configs/modules/compliments/compliments_parts_day.js b/tests/configs/modules/compliments/compliments_parts_day.js new file mode 100644 index 00000000..8d47fe22 --- /dev/null +++ b/tests/configs/modules/compliments/compliments_parts_day.js @@ -0,0 +1,42 @@ +/* Magic Mirror Test config for default compliments + * + * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com + * MIT Licensed. + */ + +var config = { + port: 8080, + ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], + + language: "en", + timeFormat: 12, + units: "metric", + electronOptions: { + webPreferences: { + nodeIntegration: true, + }, + }, + + modules: [ + { + module: "compliments", + position: "middle_center", + config: { + compliments: { + morning: [ + "Hi", "Good Morning", "Morning test" + ], + afternoon: [ + "Hello", "Good Afternoon", "Afternoon test" + ], + evening: [ + "Hello There", "Good Evening", "Evening test" + ] + } + } + } + ] +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") {module.exports = config;} diff --git a/tests/e2e/modules/compliments_spec.js b/tests/e2e/modules/compliments_spec.js new file mode 100644 index 00000000..15790177 --- /dev/null +++ b/tests/e2e/modules/compliments_spec.js @@ -0,0 +1,78 @@ +const Application = require("spectron").Application; +const path = require("path"); +const chai = require("chai"); +const expect = chai.expect; +const chaiAsPromised = require("chai-as-promised"); + +var electronPath = path.join(__dirname, "../../../", "node_modules", ".bin", "electron"); + +if (process.platform === "win32") { + electronPath += ".cmd"; +} + +var appPath = path.join(__dirname, "../../../js/electron.js"); + +var app = new Application({ + path: electronPath, + args: [appPath] +}); + +global.before(function () { + chai.should(); + chai.use(chaiAsPromised); +}); + +describe("Compliments module", function () { + this.timeout(10000); + + describe("parts of days", function() { + before(function() { + // Set config sample for use in test + process.env.MM_CONFIG_FILE = "tests/configs/modules/compliments/compliments_parts_day.js"; + }); + + beforeEach(function (done) { + app.start().then(function() { done(); } ); + }); + + afterEach(function (done) { + app.stop().then(function() { done(); }); + }); + + + it("if Morning compliments for that part of day", function () { + var hour = new Date().getHours(); + if (hour >= 3 && hour < 12) { + // if morning check + return app.client.waitUntilWindowLoaded() + .getText(".compliments").then(function (text) { + expect(text).to.be.oneOf(["Hi", "Good Morning", "Morning test"]); + }) + } + }); + + it("if Afternoon show Compliments for that part of day", function () { + var hour = new Date().getHours(); + if (hour >= 12 && hour < 17) { + // if morning check + return app.client.waitUntilWindowLoaded() + .getText(".compliments").then(function (text) { + expect(text).to.be.oneOf(["Hello", "Good Afternoon", "Afternoon test"]); + }) + } + }); + + it("if Evening show Compliments for that part of day", function () { + var hour = new Date().getHours(); + if (!(hour >= 3 && hour < 12) && !(hour >= 12 && hour < 17)) { + // if evening check + return app.client.waitUntilWindowLoaded() + .getText(".compliments").then(function (text) { + expect(text).to.be.oneOf(["Hello There", "Good Evening", "Evening test"]); + }) + } + }); + + }); + +}); diff --git a/tests/unit/global_vars/root_path_spec.js b/tests/unit/global_vars/root_path_spec.js index 3da29be1..197ee6a7 100644 --- a/tests/unit/global_vars/root_path_spec.js +++ b/tests/unit/global_vars/root_path_spec.js @@ -61,5 +61,11 @@ describe("'global.root_path' set in js/app.js", function() { it("should not modify global.version for testing", function() { expect(global.version).to.equal(undefined); }); + + it("should expect the global.version equals package.json file", function() { + version_package = JSON.parse(fs.readFileSync("package.json", "utf8")).version; + expect(this.sandbox.global.version).to.equal(version_package); + }); + });