Release 2.24.0 (#3141)

Signed-off-by: naveen <172697+naveensrinivasan@users.noreply.github.com>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Karsten Hassel <hassel@gmx.de>
Co-authored-by: Malte Hallström <46646495+SkySails@users.noreply.github.com>
Co-authored-by: Veeck <github@veeck.de>
Co-authored-by: veeck <michael@veeck.de>
Co-authored-by: dWoolridge <dwoolridge@charter.net>
Co-authored-by: Johan <jojjepersson@yahoo.se>
Co-authored-by: Dario Mratovich <dario_mratovich@hotmail.com>
Co-authored-by: Dario Mratovich <dario.mratovich@outlook.com>
Co-authored-by: Magnus <34011212+MagMar94@users.noreply.github.com>
Co-authored-by: Naveen <172697+naveensrinivasan@users.noreply.github.com>
Co-authored-by: buxxi <buxxi@omfilm.net>
Co-authored-by: Thomas Hirschberger <47733292+Tom-Hirschberger@users.noreply.github.com>
Co-authored-by: Kristjan ESPERANTO <35647502+KristjanESPERANTO@users.noreply.github.com>
Co-authored-by: Andrés Vanegas Jiménez <142350+angeldeejay@users.noreply.github.com>
Co-authored-by: Dave Child <dave@addedbytes.com>
Co-authored-by: grenagit <46225780+grenagit@users.noreply.github.com>
Co-authored-by: Grena <grena@grenabox.fr>
Co-authored-by: Magnus Marthinsen <magmar@online.no>
Co-authored-by: Patrick <psieg@users.noreply.github.com>
Co-authored-by: Piotr Rajnisz <56397164+rajniszp@users.noreply.github.com>
Co-authored-by: Suthep Yonphimai <tomzt@users.noreply.github.com>
Co-authored-by: CarJem Generations (Carter Wallace) <cwallacecs@gmail.com>
Co-authored-by: Nicholas Fogal <nfogal.misc@gmail.com>
Co-authored-by: JakeBinney <126349119+JakeBinney@users.noreply.github.com>
Co-authored-by: OWL4C <124401812+OWL4C@users.noreply.github.com>
Co-authored-by: Oscar Björkman <17575446+oscarb@users.noreply.github.com>
Co-authored-by: Ismar Slomic <ismar@slomic.no>
Co-authored-by: Jørgen Veum-Wahlberg <jorgen.wahlberg@amedia.no>
Co-authored-by: Eddie Hung <6740044+eddiehung@users.noreply.github.com>
Co-authored-by: Bugsounet - Cédric <github@bugsounet.fr>
Co-authored-by: bugsounet <bugsounet@bugsounet.fr>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This commit is contained in:
Michael Teeuw
2023-07-01 21:17:31 +02:00
committed by GitHub
parent abe5c08a52
commit e87f50e64a
74 changed files with 2570 additions and 2437 deletions

View File

@@ -9,7 +9,8 @@ let config = {
position: "middle_center",
config: {
displayType: "analog",
analogFace: "face-006"
analogFace: "face-006",
showDate: false
}
}
]

View File

@@ -0,0 +1,25 @@
/* MagicMirror² Test config for default clock module
*
* By Johan Hammar
* MIT Licensed.
*/
let config = {
timeFormat: 12,
modules: [
{
module: "clock",
position: "middle_center",
config: {
showTime: true,
showDate: true,
displayType: "analog"
}
}
]
};
/*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {
module.exports = config;
}

View File

@@ -3,7 +3,7 @@
* By Rodrigo Ramírez Norambuena https://rodrigoramirez.com
* MIT Licensed.
*/
let config = require(process.cwd() + "/tests/configs/default.js").configFactory({
let config = require(`${process.cwd()}/tests/configs/default.js`).configFactory({
port: ${MM_PORT}
});

View File

@@ -1,10 +1,17 @@
/**
* Suppresses errors concerning web server already shut down.
*
* @param {string} err The error message.
*/
const mockError = (err) => {
if (err.includes("ECONNREFUSED") || err.includes("ECONNRESET") || err.includes("socket hang up") || err.includes("exports is not defined") || err.includes("write EPIPE")) {
if (
err.includes("ECONNREFUSED") ||
err.includes("ECONNRESET") ||
err.includes("socket hang up") ||
err.includes("exports is not defined") ||
err.includes("write EPIPE") ||
err.includes("AggregateError") ||
err.includes("ERR_SOCKET_CONNECTION_TIMEOUT")
) {
jest.fn();
} else {
console.dir(err);

View File

@@ -107,4 +107,18 @@ describe("Clock module", () => {
expect(elem).not.toBe(null);
});
});
describe("with analog clock face and date enabled", () => {
beforeAll(async () => {
await helpers.startApplication("tests/configs/modules/clock/clock_showDateAnalog.js");
await helpers.getDocument();
});
it("should show the analog clock face and the date", async () => {
const elemClock = helpers.waitForElement(".clock-circle");
await expect(elemClock).not.toBe(null);
const elemDate = helpers.waitForElement(".clock .date");
await expect(elemDate).not.toBe(null);
});
});
});

View File

@@ -3,7 +3,6 @@ const helpers = require("../helpers/global-setup");
describe("Compliments module", () => {
/**
* move similar tests in function doTest
*
* @param {Array} complimentsArray The array of compliments.
*/
const doTest = async (complimentsArray) => {
@@ -25,7 +24,7 @@ describe("Compliments module", () => {
await helpers.getDocument();
});
it("Show anytime because if configure empty parts of day compliments and set anytime compliments", async () => {
it("shows anytime because if configure empty parts of day compliments and set anytime compliments", async () => {
await doTest(["Anytime here"]);
});
});
@@ -36,7 +35,7 @@ describe("Compliments module", () => {
await helpers.getDocument();
});
it("Show anytime compliments", async () => {
it("shows anytime compliments", async () => {
await doTest(["Anytime here"]);
});
});

View File

@@ -9,13 +9,13 @@ describe("Check configuration without modules", () => {
await helpers.stopApplication();
});
it("Show the message MagicMirror² title", async () => {
it("shows the message MagicMirror² title", async () => {
const elem = await helpers.waitForElement("#module_1_helloworld .module-content");
expect(elem).not.toBe(null);
expect(elem.textContent).toContain("MagicMirror²");
});
it("Show the url of michael's website", async () => {
it("shows the url of michael's website", async () => {
const elem = await helpers.waitForElement("#module_5_helloworld .module-content");
expect(elem).not.toBe(null);
expect(elem.textContent).toContain("www.michaelteeuw.nl");

View File

@@ -0,0 +1,28 @@
const helpers = require("./helpers/global-setup");
const delay = (time) => {
return new Promise((resolve) => setTimeout(resolve, time));
};
describe("App environment", () => {
let serverProcess;
beforeAll(async () => {
process.env.MM_CONFIG_FILE = "tests/configs/default.js";
serverProcess = await require("child_process").spawn("npm", ["run", "server"], { env: process.env, detached: true });
// we have to wait until the server is startet
await delay(2000);
});
afterAll(async () => {
await process.kill(-serverProcess.pid);
});
it("get request from http://localhost:8080 should return 200", async () => {
const res = await helpers.fetch("http://localhost:8080");
expect(res.status).toBe(200);
});
it("get request from http://localhost:8080/nothing should return 404", async () => {
const res = await helpers.fetch("http://localhost:8080/nothing");
expect(res.status).toBe(404);
});
});

View File

@@ -3,7 +3,6 @@ const helpers = require("../helpers/global-setup");
describe("Calendar module", () => {
/**
* move similar tests in function doTest
*
* @param {string} cssClass css selector
*/
const doTest = async (cssClass) => {

View File

@@ -3,7 +3,6 @@ const helpers = require("../helpers/global-setup");
describe("Compliments module", () => {
/**
* move similar tests in function doTest
*
* @param {Array} complimentsArray The array of compliments.
*/
const doTest = async (complimentsArray) => {
@@ -36,7 +35,7 @@ describe("Compliments module", () => {
describe("Feature date in compliments module", () => {
describe("Set date and empty compliments for anytime, morning, evening and afternoon", () => {
it("Show happy new year compliment on new years day", async () => {
it("shows happy new year compliment on new years day", async () => {
await helpers.startApplication("tests/configs/modules/compliments/compliments_date.js", "01 Jan 2022 10:00:00 GMT");
await doTest(["Happy new year!"]);
});

View File

@@ -0,0 +1,3 @@
module.exports = async () => {
process.env.TZ = "Europe/Berlin";
};

View File

@@ -0,0 +1,53 @@
global.moment = require("moment-timezone");
const CalendarFetcherUtils = require("../../../../../modules/default/calendar/calendarfetcherutils");
describe("Calendar fetcher utils test", () => {
const defaultConfig = {
excludedEvents: [],
includePastEvents: false,
maximumEntries: 10,
maximumNumberOfDays: 365
};
describe("filterEvents", () => {
it("should return only ongoing and upcoming non full day events", () => {
const minusOneHour = moment().subtract(1, "hours").toDate();
const minusTwoHours = moment().subtract(2, "hours").toDate();
const plusOneHour = moment().add(1, "hours").toDate();
const plusTwoHours = moment().add(2, "hours").toDate();
const filteredEvents = CalendarFetcherUtils.filterEvents(
{
pastEvent: { type: "VEVENT", start: minusTwoHours, end: minusOneHour, summary: "pastEvent" },
ongoingEvent: { type: "VEVENT", start: minusOneHour, end: plusOneHour, summary: "ongoingEvent" },
upcomingEvent: { type: "VEVENT", start: plusOneHour, end: plusTwoHours, summary: "upcomingEvent" }
},
defaultConfig
);
expect(filteredEvents.length).toEqual(2);
expect(filteredEvents[0].title).toBe("ongoingEvent");
expect(filteredEvents[1].title).toBe("upcomingEvent");
});
it("should return only ongoing and upcoming full day events", () => {
const yesterday = moment().subtract(1, "days").startOf("day").toDate();
const today = moment().startOf("day").toDate();
const tomorrow = moment().add(1, "days").startOf("day").toDate();
const filteredEvents = CalendarFetcherUtils.filterEvents(
{
pastEvent: { type: "VEVENT", start: yesterday, end: yesterday, summary: "pastEvent" },
ongoingEvent: { type: "VEVENT", start: today, end: today, summary: "ongoingEvent" },
upcomingEvent: { type: "VEVENT", start: tomorrow, end: tomorrow, summary: "upcomingEvent" }
},
defaultConfig
);
expect(filteredEvents.length).toEqual(2);
expect(filteredEvents[0].title).toBe("ongoingEvent");
expect(filteredEvents[1].title).toBe("upcomingEvent");
});
});
});

View File

@@ -1,18 +1,8 @@
global.moment = require("moment");
describe("Functions into modules/default/calendar/calendar.js", () => {
// Fake for use by calendar.js
Module = {};
Module.definitions = {};
Module.register = (name, moduleDefinition) => {
Module.definitions[name] = moduleDefinition;
};
beforeAll(() => {
// load calendar.js
require("../../../modules/default/calendar/calendar");
});
const CalendarUtils = require("../../../../../modules/default/calendar/calendarutils");
describe("Calendar utils tests", () => {
describe("capFirst", () => {
const words = {
rodrigo: "Rodrigo",
@@ -24,68 +14,88 @@ describe("Functions into modules/default/calendar/calendar.js", () => {
Object.keys(words).forEach((word) => {
it(`for '${word}' should return '${words[word]}'`, () => {
expect(Module.definitions.calendar.capFirst(word)).toBe(words[word]);
expect(CalendarUtils.capFirst(word)).toBe(words[word]);
});
});
it("should not capitalize other letters", () => {
expect(CalendarUtils.capFirst("event")).not.toBe("EVent");
});
});
describe("getLocaleSpecification", () => {
it("should return a valid moment.LocaleSpecification for a 12-hour format", () => {
expect(Module.definitions.calendar.getLocaleSpecification(12)).toEqual({ longDateFormat: { LT: "h:mm A" } });
expect(CalendarUtils.getLocaleSpecification(12)).toEqual({ longDateFormat: { LT: "h:mm A" } });
});
it("should return a valid moment.LocaleSpecification for a 24-hour format", () => {
expect(Module.definitions.calendar.getLocaleSpecification(24)).toEqual({ longDateFormat: { LT: "HH:mm" } });
expect(CalendarUtils.getLocaleSpecification(24)).toEqual({ longDateFormat: { LT: "HH:mm" } });
});
it("should return the current system locale when called without timeFormat number", () => {
expect(Module.definitions.calendar.getLocaleSpecification()).toEqual({ longDateFormat: { LT: moment.localeData().longDateFormat("LT") } });
expect(CalendarUtils.getLocaleSpecification()).toEqual({ longDateFormat: { LT: moment.localeData().longDateFormat("LT") } });
});
it("should return a 12-hour longDateFormat when using the 'en' locale", () => {
const localeBackup = moment.locale();
moment.locale("en");
expect(Module.definitions.calendar.getLocaleSpecification()).toEqual({ longDateFormat: { LT: "h:mm A" } });
expect(CalendarUtils.getLocaleSpecification()).toEqual({ longDateFormat: { LT: "h:mm A" } });
moment.locale(localeBackup);
});
it("should return a 12-hour longDateFormat when using the 'au' locale", () => {
const localeBackup = moment.locale();
moment.locale("au");
expect(Module.definitions.calendar.getLocaleSpecification()).toEqual({ longDateFormat: { LT: "h:mm A" } });
expect(CalendarUtils.getLocaleSpecification()).toEqual({ longDateFormat: { LT: "h:mm A" } });
moment.locale(localeBackup);
});
it("should return a 12-hour longDateFormat when using the 'eg' locale", () => {
const localeBackup = moment.locale();
moment.locale("eg");
expect(Module.definitions.calendar.getLocaleSpecification()).toEqual({ longDateFormat: { LT: "h:mm A" } });
expect(CalendarUtils.getLocaleSpecification()).toEqual({ longDateFormat: { LT: "h:mm A" } });
moment.locale(localeBackup);
});
it("should return a 24-hour longDateFormat when using the 'nl' locale", () => {
const localeBackup = moment.locale();
moment.locale("nl");
expect(Module.definitions.calendar.getLocaleSpecification()).toEqual({ longDateFormat: { LT: "HH:mm" } });
expect(CalendarUtils.getLocaleSpecification()).toEqual({ longDateFormat: { LT: "HH:mm" } });
moment.locale(localeBackup);
});
it("should return a 24-hour longDateFormat when using the 'fr' locale", () => {
const localeBackup = moment.locale();
moment.locale("fr");
expect(Module.definitions.calendar.getLocaleSpecification()).toEqual({ longDateFormat: { LT: "HH:mm" } });
expect(CalendarUtils.getLocaleSpecification()).toEqual({ longDateFormat: { LT: "HH:mm" } });
moment.locale(localeBackup);
});
it("should return a 24-hour longDateFormat when using the 'uk' locale", () => {
const localeBackup = moment.locale();
moment.locale("uk");
expect(Module.definitions.calendar.getLocaleSpecification()).toEqual({ longDateFormat: { LT: "HH:mm" } });
expect(CalendarUtils.getLocaleSpecification()).toEqual({ longDateFormat: { LT: "HH:mm" } });
moment.locale(localeBackup);
});
});
describe("shorten", () => {
it("should not shorten if short enough", () => {
expect(CalendarUtils.shorten("Event 1", 10, false, 1)).toBe("Event 1");
});
it("should shorten into one line", () => {
expect(CalendarUtils.shorten("Example event at 12 o clock", 10, true, 1)).toBe("Example …");
});
it("should shorten into three lines", () => {
expect(CalendarUtils.shorten("Example event at 12 o clock", 10, true, 3)).toBe("Example <br>event at 12 o <br>clock");
});
it("should not shorten into three lines if wrap is false", () => {
expect(CalendarUtils.shorten("Example event at 12 o clock", 10, false, 3)).toBe("Example ev…");
});
const strings = {
" String with whitespace at the beginning that needs trimming": { length: 16, return: "String with whit…" },
"long string that needs shortening": { length: 16, return: "long string that…" },
@@ -95,34 +105,44 @@ describe("Functions into modules/default/calendar/calendar.js", () => {
Object.keys(strings).forEach((string) => {
it(`for '${string}' should return '${strings[string].return}'`, () => {
expect(Module.definitions.calendar.shorten(string, strings[string].length)).toBe(strings[string].return);
expect(CalendarUtils.shorten(string, strings[string].length)).toBe(strings[string].return);
});
});
it("should return an empty string if shorten is called with a non-string", () => {
expect(Module.definitions.calendar.shorten(100)).toBe("");
expect(CalendarUtils.shorten(100)).toBe("");
});
it("should not shorten the string if shorten is called with a non-number maxLength", () => {
expect(Module.definitions.calendar.shorten("This is a test string", "This is not a number")).toBe("This is a test string");
expect(CalendarUtils.shorten("This is a test string", "This is not a number")).toBe("This is a test string");
});
it("should wrap the string instead of shorten it if shorten is called with wrapEvents = true (with maxLength defined as 20)", () => {
expect(Module.definitions.calendar.shorten("This is a wrapEvent test. Should wrap the string instead of shorten it if called with wrapEvent = true", 20, true)).toBe(
expect(CalendarUtils.shorten("This is a wrapEvent test. Should wrap the string instead of shorten it if called with wrapEvent = true", 20, true)).toBe(
"This is a <br>wrapEvent test. Should wrap <br>the string instead of <br>shorten it if called with <br>wrapEvent = true"
);
});
it("should wrap the string instead of shorten it if shorten is called with wrapEvents = true (without maxLength defined, default 25)", () => {
expect(Module.definitions.calendar.shorten("This is a wrapEvent test. Should wrap the string instead of shorten it if called with wrapEvent = true", undefined, true)).toBe(
expect(CalendarUtils.shorten("This is a wrapEvent test. Should wrap the string instead of shorten it if called with wrapEvent = true", undefined, true)).toBe(
"This is a wrapEvent <br>test. Should wrap the string <br>instead of shorten it if called <br>with wrapEvent = true"
);
});
it("should wrap and shorten the string in the second line if called with wrapEvents = true and maxTitleLines = 2", () => {
expect(Module.definitions.calendar.shorten("This is a wrapEvent and maxTitleLines test. Should wrap and shorten the string in the second line if called with wrapEvents = true and maxTitleLines = 2", undefined, true, 2)).toBe(
expect(CalendarUtils.shorten("This is a wrapEvent and maxTitleLines test. Should wrap and shorten the string in the second line if called with wrapEvents = true and maxTitleLines = 2", undefined, true, 2)).toBe(
"This is a wrapEvent and <br>maxTitleLines test. Should wrap and …"
);
});
});
describe("titleTransform and shorten combined", () => {
it("should replace the birthday and wrap nicely", () => {
const transformedTitle = CalendarUtils.titleTransform("Michael Teeuw's birthday", {
"De verjaardag van ": "",
"'s birthday": ""
});
expect(CalendarUtils.shorten(transformedTitle, 10, true, 2)).toBe("Michael <br>Teeuw");
});
});
});

View File

@@ -1,23 +1,22 @@
const { performWebRequest } = require("../../../../modules/default/utils");
global.moment = require("moment-timezone");
const { performWebRequest, formatTime } = require("../../../../modules/default/utils");
const nodeVersion = process.version.match(/^v(\d+)\.*/)[1];
describe("Utils tests", () => {
describe("The performWebRequest-method", () => {
describe("Default modules utils tests", () => {
describe("performWebRequest", () => {
if (nodeVersion > 18) {
const locationHost = "localhost:8080";
const locationProtocol = "http";
let fetchResponse;
let fetchMock;
let url;
let urlToCall;
beforeEach(() => {
fetchResponse = new Response();
global.fetch = jest.fn(() => Promise.resolve(fetchResponse));
fetchMock = global.fetch;
url = "www.test.com";
});
describe("When using cors proxy", () => {
@@ -29,24 +28,23 @@ describe("Utils tests", () => {
});
test("Calls correct URL once", async () => {
const urlToCall = "http://www.test.com/path?param1=value1";
url = urlToCall;
urlToCall = "http://www.test.com/path?param1=value1";
await performWebRequest(url, "json", true);
await performWebRequest(urlToCall, "json", true);
expect(fetchMock.mock.calls.length).toBe(1);
expect(fetchMock.mock.calls[0][0]).toBe(`${locationProtocol}//${locationHost}/cors?url=${urlToCall}`);
});
test("Sends correct headers", async () => {
const urlToCall = "http://www.test.com/path?param1=value1";
url = urlToCall;
urlToCall = "http://www.test.com/path?param1=value1";
const headers = [
{ name: "header1", value: "value1" },
{ name: "header2", value: "value2" }
];
await performWebRequest(url, "json", true, headers);
await performWebRequest(urlToCall, "json", true, headers);
expect(fetchMock.mock.calls.length).toBe(1);
expect(fetchMock.mock.calls[0][0]).toBe(`${locationProtocol}//${locationHost}/cors?sendheaders=header1:value1,header2:value2&url=${urlToCall}`);
@@ -55,24 +53,22 @@ describe("Utils tests", () => {
describe("When not using cors proxy", () => {
test("Calls correct URL once", async () => {
const urlToCall = "http://www.test.com/path?param1=value1";
url = urlToCall;
urlToCall = "http://www.test.com/path?param1=value1";
await performWebRequest(url);
await performWebRequest(urlToCall);
expect(fetchMock.mock.calls.length).toBe(1);
expect(fetchMock.mock.calls[0][0]).toBe(urlToCall);
});
test("Sends correct headers", async () => {
const urlToCall = "http://www.test.com/path?param1=value1";
url = urlToCall;
urlToCall = "http://www.test.com/path?param1=value1";
const headers = [
{ name: "header1", value: "value1" },
{ name: "header2", value: "value2" }
];
await performWebRequest(url, "json", false, headers);
await performWebRequest(urlToCall, "json", false, headers);
const expectedHeaders = { headers: { header1: "value1", header2: "value2" } };
expect(fetchMock.mock.calls.length).toBe(1);
@@ -82,23 +78,27 @@ describe("Utils tests", () => {
describe("When receiving json format", () => {
test("Returns undefined when no data is received", async () => {
const response = await performWebRequest(url);
urlToCall = "www.test.com";
const response = await performWebRequest(urlToCall);
expect(response).toBe(undefined);
});
test("Returns object when data is received", async () => {
urlToCall = "www.test.com";
fetchResponse = new Response('{"body": "some content"}');
const response = await performWebRequest(url);
const response = await performWebRequest(urlToCall);
expect(response.body).toBe("some content");
});
test("Returns expected headers when data is received", async () => {
urlToCall = "www.test.com";
fetchResponse = new Response('{"body": "some content"}', { headers: { header1: "value1", header2: "value2" } });
const response = await performWebRequest(url, "json", false, undefined, ["header1"]);
const response = await performWebRequest(urlToCall, "json", false, undefined, ["header1"]);
expect(response.headers.length).toBe(1);
expect(response.headers[0].name).toBe("header1");
@@ -109,4 +109,64 @@ describe("Utils tests", () => {
test("Always ok, need one test", () => {});
}
});
describe("formatTime", () => {
const time = new Date();
beforeEach(async () => {
time.setHours(13, 13);
});
it("should convert correctly according to the config", () => {
expect(
formatTime(
{
timeFormat: 24
},
time
)
).toBe("13:13");
expect(
formatTime(
{
showPeriod: true,
showPeriodUpper: true,
timeFormat: 12
},
time
)
).toBe("1:13 PM");
expect(
formatTime(
{
showPeriod: true,
showPeriodUpper: false,
timeFormat: 12
},
time
)
).toBe("1:13 pm");
expect(
formatTime(
{
showPeriod: false,
timeFormat: 12
},
time
)
).toBe("1:13");
});
it("should convert correctly into another timezone", () => {
expect(
formatTime(
{
timeFormat: 24,
timezone: "America/Toronto"
},
time
)
).toBe("07:13");
});
});
});

View File

@@ -1,5 +1,4 @@
const WeatherObject = require("../../../modules/default/weather/weatherobject");
const WeatherUtils = require("../../../modules/default/weather/weatherutils");
const WeatherObject = require("../../../../../modules/default/weather/weatherobject");
global.moment = require("moment-timezone");
global.SunCalc = require("suncalc");
@@ -47,38 +46,3 @@ describe("WeatherObject", () => {
moment.tz.setDefault(originalTimeZone);
});
});
describe("WeatherUtils", () => {
it("should convert windspeed correctly from mps to beaufort", () => {
expect(Math.round(WeatherUtils.convertWind(5, "beaufort"))).toBe(3);
expect(Math.round(WeatherUtils.convertWind(300, "beaufort"))).toBe(12);
});
it("should convert windspeed correctly from mps to kmh", () => {
expect(Math.round(WeatherUtils.convertWind(11.75, "kmh"))).toBe(42);
});
it("should convert windspeed correctly from mps to knots", () => {
expect(Math.round(WeatherUtils.convertWind(10, "knots"))).toBe(19);
});
it("should convert windspeed correctly from mph to mps", () => {
expect(Math.round(WeatherUtils.convertWindToMetric(93.951324266285))).toBe(42);
});
it("should convert windspeed correctly from kmh to mps", () => {
expect(Math.round(WeatherUtils.convertWindToMs(151.2))).toBe(42);
});
it("should convert wind direction correctly from cardinal to value", () => {
expect(WeatherUtils.convertWindDirection("SSE")).toBe(157);
});
it("should return a calculated feelsLike info", () => {
expect(WeatherUtils.calculateFeelsLike(0, 20, 40)).toBe(-9.444444444444445);
});
it("should return a calculated feelsLike info", () => {
expect(WeatherUtils.calculateFeelsLike(30, 0, 60)).toBe(32.8320322777777);
});
});

View File

@@ -1,45 +1,99 @@
const weather = require("../../../../../modules/default/weather/weatherutils");
const WeatherUtils = require("../../../../../modules/default/weather/weatherutils");
describe("Weather utils tests", () => {
describe("convertPrecipitationUnit tests", () => {
it("Should keep value and unit if outputUnit is undefined", () => {
describe("windspeed conversion", () => {
it("should convert windspeed correctly from mps to beaufort", () => {
expect(Math.round(WeatherUtils.convertWind(5, "beaufort"))).toBe(3);
expect(Math.round(WeatherUtils.convertWind(300, "beaufort"))).toBe(12);
});
it("should convert windspeed correctly from mps to mps", () => {
expect(WeatherUtils.convertWind(11.75, "FOOBAR")).toBe(11.75);
});
it("should convert windspeed correctly from mps to kmh", () => {
expect(Math.round(WeatherUtils.convertWind(11.75, "kmh"))).toBe(42);
});
it("should convert windspeed correctly from mps to knots", () => {
expect(Math.round(WeatherUtils.convertWind(10, "knots"))).toBe(19);
});
it("should convert windspeed correctly from mph to mps", () => {
expect(Math.round(WeatherUtils.convertWindToMetric(93.951324266285))).toBe(42);
});
it("should convert windspeed correctly from kmh to mps", () => {
expect(Math.round(WeatherUtils.convertWindToMs(151.2))).toBe(42);
});
});
describe("wind direction conversion", () => {
it("should convert wind direction correctly from cardinal to value", () => {
expect(WeatherUtils.convertWindDirection("SSE")).toBe(157);
});
});
describe("feelsLike calculation", () => {
it("should return a calculated feelsLike info", () => {
expect(WeatherUtils.calculateFeelsLike(0, 20, 40)).toBe(-9.444444444444445);
});
it("should return a calculated feelsLike info", () => {
expect(WeatherUtils.calculateFeelsLike(30, 0, 60)).toBe(32.8320322777777);
});
});
describe("precipitationUnit conversion", () => {
it("should keep value and unit if outputUnit is undefined", () => {
const values = [1, 2];
const units = ["mm", "cm"];
for (let i = 0; i < values.length; i++) {
var result = weather.convertPrecipitationUnit(values[i], units[i], undefined);
const result = weather.convertPrecipitationUnit(values[i], units[i], undefined);
expect(result).toBe(`${values[i].toFixed(2)} ${units[i]}`);
}
});
it("Should keep value and unit if outputUnit is metric", () => {
it("should keep value and unit if outputUnit is metric", () => {
const values = [1, 2];
const units = ["mm", "cm"];
for (let i = 0; i < values.length; i++) {
var result = weather.convertPrecipitationUnit(values[i], units[i], "metric");
const result = weather.convertPrecipitationUnit(values[i], units[i], "metric");
expect(result).toBe(`${values[i].toFixed(2)} ${units[i]}`);
}
});
it("Should use mm unit if input unit is undefined", () => {
it("should use mm unit if input unit is undefined", () => {
const values = [1, 2];
for (let i = 0; i < values.length; i++) {
var result = weather.convertPrecipitationUnit(values[i], undefined, "metric");
const result = weather.convertPrecipitationUnit(values[i], undefined, "metric");
expect(result).toBe(`${values[i].toFixed(2)} mm`);
}
});
it("Should convert value and unit if outputUnit is imperial", () => {
it("should convert value and unit if outputUnit is imperial", () => {
const values = [1, 2];
const units = ["mm", "cm"];
const expectedValues = [0.04, 0.79];
for (let i = 0; i < values.length; i++) {
var result = weather.convertPrecipitationUnit(values[i], units[i], "imperial");
const result = weather.convertPrecipitationUnit(values[i], units[i], "imperial");
expect(result).toBe(`${expectedValues[i]} in`);
}
});
it("should round percentage values regardless of output units", () => {
const values = [0.1, 2.22, 9.999];
const output = [undefined, "imperial", "metric"];
const result = ["0 %", "2 %", "10 %"];
for (let i = 0; i < values.length; i++) {
expect(weather.convertPrecipitationUnit(values[i], "%", output[i])).toBe(result[i]);
}
});
});
});