From 9bf556424108c1334467978c7eef661ac6591c98 Mon Sep 17 00:00:00 2001 From: Stanislav Jakuschevskij Date: Sat, 11 Nov 2023 16:52:43 +0100 Subject: [PATCH] refactor: speeded up unit tests Replaced beforeEach with beforeAll. Added console reporter and npm commands. Issue-Ref: #184 --- backend/package.json | 3 + .../game-identifier/game.identifier.spec.js | 402 +++++----- .../services/game.service.spec.js | 66 +- .../player.history.aggregator.spec.js | 12 +- .../services/player.history.service.spec.js | 4 +- .../steam.apps.aggregator.spec.js | 10 +- backend/src/models/game.spec.js | 36 +- backend/src/models/history.check.spec.js | 4 +- backend/src/models/player.history.spec.js | 18 +- backend/src/models/steam.app.spec.js | 24 +- backend/src/models/tracked.players.spec.js | 14 +- backend/src/utils/runner.spec.js | 2 +- package-lock.json | 707 ++++++++++++++++++ 13 files changed, 1006 insertions(+), 296 deletions(-) diff --git a/backend/package.json b/backend/package.json index 4b2951cdf..8edd91d82 100644 --- a/backend/package.json +++ b/backend/package.json @@ -4,6 +4,8 @@ "description": "Steam game stats backend.", "main": "src/main.js", "scripts": { + "unit-test:report": "jasmine --config=jasmine-unit.json --reporter=jasmine-console-reporter", + "integration-test:report": "jasmine --config=jasmine-integration.json --reporter=jasmine-console-reporter", "unit-test": "jasmine --config=jasmine-unit.json", "integration-test": "jasmine --config=jasmine-integration.json", "start": "node src/main.js", @@ -31,6 +33,7 @@ "devDependencies": { "eslint": "8.11.0", "jasmine": "4.0.2", + "jasmine-console-reporter": "3.1.0", "mongodb-memory-server": "8.12.2", "pino-pretty": "10.2.0", "prettier": "2.6.0" diff --git a/backend/src/features/game-identifier/game.identifier.spec.js b/backend/src/features/game-identifier/game.identifier.spec.js index 02e17ce6c..089420f07 100644 --- a/backend/src/features/game-identifier/game.identifier.spec.js +++ b/backend/src/features/game-identifier/game.identifier.spec.js @@ -20,7 +20,7 @@ import { getXGamesWithoutDetails } from "../../models/game.mocks.js"; describe("game.identifier.js", function () { describe(".tryViaSteamWeb", function () { describe("gets zero steamApps from the database and stops. So,", function () { - beforeEach(async function () { + beforeAll(async function () { this.options = { batchSize: 1, unitDelay: 0, @@ -76,7 +76,7 @@ describe("game.identifier.js", function () { }); describe("gets one game out of a batch of one steamApp, and inserts it into the database. So,", function () { - beforeEach(async function () { + beforeAll(async function () { this.options = { batchSize: 1, unitDelay: 0, @@ -195,7 +195,7 @@ describe("game.identifier.js", function () { }); describe("gets one game out of a batch of two steamApps, and inserts it into the database. So,", function () { - beforeEach(async function () { + beforeAll(async function () { this.options = { batchSize: 1, unitDelay: 0, @@ -327,7 +327,7 @@ describe("game.identifier.js", function () { }); describe("gets two games out of a batch of three steamApps, and inserts them into the database. So,", function () { - beforeEach(async function () { + beforeAll(async function () { this.options = { batchSize: 1, unitDelay: 0, @@ -464,7 +464,7 @@ describe("game.identifier.js", function () { describe(".tryViaSteamchartsWeb", function () { describe("gets zero steamApps from the database and stops. So,", function () { - beforeEach(async function () { + beforeAll(async function () { this.options = { batchSize: 1, unitDelay: 0, @@ -522,7 +522,7 @@ describe("game.identifier.js", function () { }); describe("gets one game from a batch of two steamApps from the database and inserts them into the database. So,", function () { - beforeEach(async function () { + beforeAll(async function () { this.options = { batchSize: 1, unitDelay: 0, @@ -653,7 +653,7 @@ describe("game.identifier.js", function () { }); describe("gets two games from a batch of three steamApps from the database and inserts them into the database. So,", function () { - beforeEach(async function () { + beforeAll(async function () { this.options = { batchSize: 1, unitDelay: 0, @@ -792,230 +792,230 @@ describe("game.identifier.js", function () { }); }); }); -}); -describe(".updateGamesWithoutDetails.", function () { - describe("Finds no missing game properties in the database and stops", function () { - beforeEach(async function () { - this.options = { - batchSize: 1, - }; - - this.steamClientMock = createSteamMock([]); - this.steamAppsRepository = createSteamAppsRepositoryMock(); - this.gamesRepository = createGamesRepositoryMock([]); - this.historyChecksRepository = createHistoryChecksRepositoryMock(); - - this.identifier = new GameIdentifier( - this.steamClientMock, - this.steamAppsRepository, - this.gamesRepository, - this.historyChecksRepository, - createLoggerMock(), - this.options, - ); - - await this.identifier.updateGamesWithoutDetails(); - }); + describe(".updateGamesWithoutDetails.", function () { + describe("Finds no missing game properties in the database and stops", function () { + beforeAll(async function () { + this.options = { + batchSize: 1, + }; - it("getGamesWithoutDetails was called once", function () { - expect(this.gamesRepository.getGamesWithoutDetails).toHaveBeenCalledTimes(1); - }); + this.steamClientMock = createSteamMock([]); + this.steamAppsRepository = createSteamAppsRepositoryMock(); + this.gamesRepository = createGamesRepositoryMock([]); + this.historyChecksRepository = createHistoryChecksRepositoryMock(); - it("getGamesWithoutDetails was called with 'this.options.batchSize'", function () { - expect(this.gamesRepository.getGamesWithoutDetails).toHaveBeenCalledWith( - this.options.batchSize, - ); - }); + this.identifier = new GameIdentifier( + this.steamClientMock, + this.steamAppsRepository, + this.gamesRepository, + this.historyChecksRepository, + createLoggerMock(), + this.options, + ); - it("getSteamDbHtmlDetailsPage was not called", function () { - expect(this.steamClientMock.getSteamDbHtmlDetailsPage).toHaveBeenCalledTimes(0); - }); + await this.identifier.updateGamesWithoutDetails(); + }); - it("updateGameDetails was not called", function () { - expect(this.gamesRepository.updateGameDetails).toHaveBeenCalledTimes(0); - }); - }); + it("getGamesWithoutDetails was called once", function () { + expect(this.gamesRepository.getGamesWithoutDetails).toHaveBeenCalledTimes(1); + }); - describe("Finds two games with missing properties", function () { - beforeEach(async function () { - this.options = { - batchSize: 2, - unitDelay: 0, - }; - - this.gamesRepoReturn = getXGamesWithoutDetails(2); - - this.steamClientMock = createSteamMock([ - counterStrikeHtmlDetailsSteamDb, - riskOfRainHtmlDetailsSteamDb, - ]); - this.steamAppsRepository = createSteamAppsRepositoryMock(); - this.gamesRepository = createGamesRepositoryMock(this.gamesRepoReturn); - this.historyChecksRepository = createHistoryChecksRepositoryMock(); - - this.identifier = new GameIdentifier( - this.steamClientMock, - this.steamAppsRepository, - this.gamesRepository, - this.historyChecksRepository, - createLoggerMock(), - this.options, - ); - - await this.identifier.updateGamesWithoutDetails(); - }); + it("getGamesWithoutDetails was called with 'this.options.batchSize'", function () { + expect(this.gamesRepository.getGamesWithoutDetails).toHaveBeenCalledWith( + this.options.batchSize, + ); + }); - it("getGamesWithoutDetails was called once", function () { - expect(this.gamesRepository.getGamesWithoutDetails).toHaveBeenCalledTimes(1); - }); + it("getSteamDbHtmlDetailsPage was not called", function () { + expect(this.steamClientMock.getSteamDbHtmlDetailsPage).toHaveBeenCalledTimes(0); + }); - it("getGamesWithoutDetails was called with 'this.options.batchSize'", function () { - expect(this.gamesRepository.getGamesWithoutDetails).toHaveBeenCalledWith( - this.options.batchSize, - ); + it("updateGameDetails was not called", function () { + expect(this.gamesRepository.updateGameDetails).toHaveBeenCalledTimes(0); + }); }); - it("getGamesWithoutDetails was called before getSteamDbHtmlDetailsPage", function () { - expect(this.gamesRepository.getGamesWithoutDetails).toHaveBeenCalledBefore( - this.steamClientMock.getSteamDbHtmlDetailsPage, - ); - }); + describe("Finds two games with missing properties", function () { + beforeAll(async function () { + this.options = { + batchSize: 2, + unitDelay: 0, + }; - it("getSteamDbHtmlDetailsPage was called twice", function () { - expect(this.steamClientMock.getSteamDbHtmlDetailsPage).toHaveBeenCalledTimes(2); - }); + this.gamesRepoReturn = getXGamesWithoutDetails(2); - it("getSteamDbHtmlDetailsPage was called with the correct ids", function () { - expect(this.steamClientMock.getSteamDbHtmlDetailsPage).toHaveBeenCalledWith( - this.gamesRepoReturn[0].id, - ); - expect(this.steamClientMock.getSteamDbHtmlDetailsPage).toHaveBeenCalledWith( - this.gamesRepoReturn[1].id, - ); - }); + this.steamClientMock = createSteamMock([ + counterStrikeHtmlDetailsSteamDb, + riskOfRainHtmlDetailsSteamDb, + ]); + this.steamAppsRepository = createSteamAppsRepositoryMock(); + this.gamesRepository = createGamesRepositoryMock(this.gamesRepoReturn); + this.historyChecksRepository = createHistoryChecksRepositoryMock(); - it("getSteamDbHtmlDetailsPage was called before updateGameDetails", function () { - expect(this.steamClientMock.getSteamDbHtmlDetailsPage).toHaveBeenCalledBefore( - this.gamesRepository.updateGameDetails, - ); - }); + this.identifier = new GameIdentifier( + this.steamClientMock, + this.steamAppsRepository, + this.gamesRepository, + this.historyChecksRepository, + createLoggerMock(), + this.options, + ); - it("updateGameDetails was called once", function () { - expect(this.gamesRepository.updateGameDetails).toHaveBeenCalledTimes(1); - }); - }); -}); + await this.identifier.updateGamesWithoutDetails(); + }); -describe(".updateGamesWithoutReleaseDates.", function () { - describe("Finds no games with missing release dates in the database and stops", function () { - beforeEach(async function () { - this.options = { - batchSize: 1, - }; - - this.steamClientMock = createSteamMock([]); - this.steamAppsRepository = createSteamAppsRepositoryMock(); - this.gamesRepository = createGamesRepositoryMock([]); - this.historyChecksRepository = createHistoryChecksRepositoryMock(); - - this.identifier = new GameIdentifier( - this.steamClientMock, - this.steamAppsRepository, - this.gamesRepository, - this.historyChecksRepository, - createLoggerMock(), - this.options, - ); - - await this.identifier.updateGamesWithoutReleaseDates(); - }); + it("getGamesWithoutDetails was called once", function () { + expect(this.gamesRepository.getGamesWithoutDetails).toHaveBeenCalledTimes(1); + }); - it("getGamesWithoutReleaseDates was called once", function () { - expect(this.gamesRepository.getGamesWithoutReleaseDates).toHaveBeenCalledTimes(1); - }); + it("getGamesWithoutDetails was called with 'this.options.batchSize'", function () { + expect(this.gamesRepository.getGamesWithoutDetails).toHaveBeenCalledWith( + this.options.batchSize, + ); + }); - it("getGamesWithoutReleaseDates was called with 'this.options.batchSize'", function () { - expect(this.gamesRepository.getGamesWithoutReleaseDates).toHaveBeenCalledWith( - this.options.batchSize, - ); - }); + it("getGamesWithoutDetails was called before getSteamDbHtmlDetailsPage", function () { + expect(this.gamesRepository.getGamesWithoutDetails).toHaveBeenCalledBefore( + this.steamClientMock.getSteamDbHtmlDetailsPage, + ); + }); - it("getSteamDbHtmlDetailsPage was not called", function () { - expect(this.steamClientMock.getSteamDbHtmlDetailsPage).toHaveBeenCalledTimes(0); - }); + it("getSteamDbHtmlDetailsPage was called twice", function () { + expect(this.steamClientMock.getSteamDbHtmlDetailsPage).toHaveBeenCalledTimes(2); + }); + + it("getSteamDbHtmlDetailsPage was called with the correct ids", function () { + expect(this.steamClientMock.getSteamDbHtmlDetailsPage).toHaveBeenCalledWith( + this.gamesRepoReturn[0].id, + ); + expect(this.steamClientMock.getSteamDbHtmlDetailsPage).toHaveBeenCalledWith( + this.gamesRepoReturn[1].id, + ); + }); + + it("getSteamDbHtmlDetailsPage was called before updateGameDetails", function () { + expect(this.steamClientMock.getSteamDbHtmlDetailsPage).toHaveBeenCalledBefore( + this.gamesRepository.updateGameDetails, + ); + }); - it("updateReleaseDates was not called", function () { - expect(this.gamesRepository.updateReleaseDates).toHaveBeenCalledTimes(0); + it("updateGameDetails was called once", function () { + expect(this.gamesRepository.updateGameDetails).toHaveBeenCalledTimes(1); + }); }); }); - describe("Finds two games with missing release dates", function () { - beforeEach(async function () { - this.options = { - batchSize: 2, - unitDelay: 0, - }; - - this.gamesRepoReturn = Game.manyFromDbEntry(getXGamesWithoutDetails(2)); - - this.steamClientMock = createSteamMock([ - counterStrikeHtmlDetailsSteamDb, - riskOfRainHtmlDetailsSteamDb, - ]); - this.steamAppsRepository = createSteamAppsRepositoryMock(); - this.gamesRepository = createGamesRepositoryMock(this.gamesRepoReturn); - this.historyChecksRepository = createHistoryChecksRepositoryMock(); - - this.identifier = new GameIdentifier( - this.steamClientMock, - this.steamAppsRepository, - this.gamesRepository, - this.historyChecksRepository, - createLoggerMock(), - this.options, - ); - - await this.identifier.updateGamesWithoutReleaseDates(); - }); + describe(".updateGamesWithoutReleaseDates.", function () { + describe("Finds no games with missing release dates in the database and stops", function () { + beforeAll(async function () { + this.options = { + batchSize: 1, + }; - it("getGamesWithoutReleaseDates was called once", function () { - expect(this.gamesRepository.getGamesWithoutReleaseDates).toHaveBeenCalledTimes(1); - }); + this.steamClientMock = createSteamMock([]); + this.steamAppsRepository = createSteamAppsRepositoryMock(); + this.gamesRepository = createGamesRepositoryMock([]); + this.historyChecksRepository = createHistoryChecksRepositoryMock(); - it("getGamesWithoutReleaseDates was called with 'this.options.batchSize'", function () { - expect(this.gamesRepository.getGamesWithoutReleaseDates).toHaveBeenCalledWith( - this.options.batchSize, - ); - }); + this.identifier = new GameIdentifier( + this.steamClientMock, + this.steamAppsRepository, + this.gamesRepository, + this.historyChecksRepository, + createLoggerMock(), + this.options, + ); - it("getGamesWithoutReleaseDates was called before getSteamDbHtmlDetailsPage", function () { - expect(this.gamesRepository.getGamesWithoutReleaseDates).toHaveBeenCalledBefore( - this.steamClientMock.getSteamDbHtmlDetailsPage, - ); - }); + await this.identifier.updateGamesWithoutReleaseDates(); + }); - it("getSteamDbHtmlDetailsPage was called twice", function () { - expect(this.steamClientMock.getSteamDbHtmlDetailsPage).toHaveBeenCalledTimes(2); - }); + it("getGamesWithoutReleaseDates was called once", function () { + expect(this.gamesRepository.getGamesWithoutReleaseDates).toHaveBeenCalledTimes(1); + }); - it("getSteamDbHtmlDetailsPage was called with the correct ids", function () { - expect(this.steamClientMock.getSteamDbHtmlDetailsPage).toHaveBeenCalledWith( - this.gamesRepoReturn[0].id, - ); - expect(this.steamClientMock.getSteamDbHtmlDetailsPage).toHaveBeenCalledWith( - this.gamesRepoReturn[1].id, - ); - }); + it("getGamesWithoutReleaseDates was called with 'this.options.batchSize'", function () { + expect(this.gamesRepository.getGamesWithoutReleaseDates).toHaveBeenCalledWith( + this.options.batchSize, + ); + }); + + it("getSteamDbHtmlDetailsPage was not called", function () { + expect(this.steamClientMock.getSteamDbHtmlDetailsPage).toHaveBeenCalledTimes(0); + }); - it("getSteamDbHtmlDetailsPage was called before updateReleaseDates", function () { - expect(this.steamClientMock.getSteamDbHtmlDetailsPage).toHaveBeenCalledBefore( - this.gamesRepository.updateReleaseDates, - ); + it("updateReleaseDates was not called", function () { + expect(this.gamesRepository.updateReleaseDates).toHaveBeenCalledTimes(0); + }); }); - it("updateReleaseDates was called once", function () { - expect(this.gamesRepository.updateReleaseDates).toHaveBeenCalledTimes(1); + describe("Finds two games with missing release dates", function () { + beforeAll(async function () { + this.options = { + batchSize: 2, + unitDelay: 0, + }; + + this.gamesRepoReturn = Game.manyFromDbEntry(getXGamesWithoutDetails(2)); + + this.steamClientMock = createSteamMock([ + counterStrikeHtmlDetailsSteamDb, + riskOfRainHtmlDetailsSteamDb, + ]); + this.steamAppsRepository = createSteamAppsRepositoryMock(); + this.gamesRepository = createGamesRepositoryMock(this.gamesRepoReturn); + this.historyChecksRepository = createHistoryChecksRepositoryMock(); + + this.identifier = new GameIdentifier( + this.steamClientMock, + this.steamAppsRepository, + this.gamesRepository, + this.historyChecksRepository, + createLoggerMock(), + this.options, + ); + + await this.identifier.updateGamesWithoutReleaseDates(); + }); + + it("getGamesWithoutReleaseDates was called once", function () { + expect(this.gamesRepository.getGamesWithoutReleaseDates).toHaveBeenCalledTimes(1); + }); + + it("getGamesWithoutReleaseDates was called with 'this.options.batchSize'", function () { + expect(this.gamesRepository.getGamesWithoutReleaseDates).toHaveBeenCalledWith( + this.options.batchSize, + ); + }); + + it("getGamesWithoutReleaseDates was called before getSteamDbHtmlDetailsPage", function () { + expect(this.gamesRepository.getGamesWithoutReleaseDates).toHaveBeenCalledBefore( + this.steamClientMock.getSteamDbHtmlDetailsPage, + ); + }); + + it("getSteamDbHtmlDetailsPage was called twice", function () { + expect(this.steamClientMock.getSteamDbHtmlDetailsPage).toHaveBeenCalledTimes(2); + }); + + it("getSteamDbHtmlDetailsPage was called with the correct ids", function () { + expect(this.steamClientMock.getSteamDbHtmlDetailsPage).toHaveBeenCalledWith( + this.gamesRepoReturn[0].id, + ); + expect(this.steamClientMock.getSteamDbHtmlDetailsPage).toHaveBeenCalledWith( + this.gamesRepoReturn[1].id, + ); + }); + + it("getSteamDbHtmlDetailsPage was called before updateReleaseDates", function () { + expect(this.steamClientMock.getSteamDbHtmlDetailsPage).toHaveBeenCalledBefore( + this.gamesRepository.updateReleaseDates, + ); + }); + + it("updateReleaseDates was called once", function () { + expect(this.gamesRepository.updateReleaseDates).toHaveBeenCalledTimes(1); + }); }); }); }); diff --git a/backend/src/features/game-identifier/services/game.service.spec.js b/backend/src/features/game-identifier/services/game.service.spec.js index 8bfffd0cf..43336b4c5 100644 --- a/backend/src/features/game-identifier/services/game.service.spec.js +++ b/backend/src/features/game-identifier/services/game.service.spec.js @@ -85,7 +85,7 @@ describe("game.service.js", () => { describe(".discoverGamesFromSteamWeb", function () { describe("discovers one game out of a batch of one stemApp, so", function () { - beforeEach(function () { + beforeAll(function () { this.steamApps = [ { appid: 1, @@ -111,7 +111,7 @@ describe("game.service.js", () => { }); describe("discovers one game out of a batch of two steamApps, so", function () { - beforeEach(function () { + beforeAll(function () { this.steamApps = [ { appid: 1, @@ -145,7 +145,7 @@ describe("game.service.js", () => { }); describe("discovers two games out of a batch of three steamApps, so", function () { - beforeEach(function () { + beforeAll(function () { this.steamApps = [ { appid: 1, @@ -194,7 +194,7 @@ describe("game.service.js", () => { describe(".getReleaseDate checks for a release date in the provided HTML page.", function () { describe("if the provided HTML page does not include a release date section,", function () { - beforeEach(function () { + beforeAll(function () { this.result = getReleaseDate(riskOfRainHtmlDetailsPageMissingInfo); }); @@ -204,7 +204,7 @@ describe("game.service.js", () => { }); describe("if the provided HTML page includes a release date,", function () { - beforeEach(function () { + beforeAll(function () { this.result = getReleaseDate(mortalDarknessGameHtmlDetailsPage); }); @@ -219,7 +219,7 @@ describe("game.service.js", () => { describe(".getDevelopers checks for developers in the provided HTML page.", function () { describe("if the provided HTML page does not include any developers,", function () { - beforeEach(function () { + beforeAll(function () { this.result = getDevelopers(riskOfRainHtmlDetailsPageMissingInfo); }); @@ -229,7 +229,7 @@ describe("game.service.js", () => { }); describe("if the provided HTML page includes one developer,", function () { - beforeEach(function () { + beforeAll(function () { this.result = getDevelopers(mortalDarknessGameHtmlDetailsPage); }); @@ -243,7 +243,7 @@ describe("game.service.js", () => { }); describe("if the provided HTML page includes two developers,", function () { - beforeEach(function () { + beforeAll(function () { this.result = getDevelopers(crusaderKingsDetailsPage); }); @@ -263,7 +263,7 @@ describe("game.service.js", () => { describe(".getGenres checks for genres in the provided HTML page.", function () { describe("if the provided HTML page does not include any genres,", function () { - beforeEach(function () { + beforeAll(function () { this.result = getGenres(riskOfRainHtmlDetailsPageMissingInfo); }); @@ -273,7 +273,7 @@ describe("game.service.js", () => { }); describe("if the provided HTML page includes genres,", function () { - beforeEach(function () { + beforeAll(function () { this.result = getGenres(mortalDarknessGameHtmlDetailsPage); }); @@ -291,7 +291,7 @@ describe("game.service.js", () => { describe(".getDescription checks for a game's description in the provided HTML page.", function () { describe("if the provided HTML page does not include a game description,", function () { - beforeEach(function () { + beforeAll(function () { this.result = getGameDescription(riskOfRainHtmlDetailsPageMissingInfo); }); @@ -301,7 +301,7 @@ describe("game.service.js", () => { }); describe("if the provided HTML page includes a description,", function () { - beforeEach(function () { + beforeAll(function () { this.result = getGameDescription(mortalDarknessGameHtmlDetailsPage); }); @@ -315,7 +315,7 @@ describe("game.service.js", () => { describe(".updateTypeSideEffectFree", function () { describe("discovers one steamApp out of a batch of one, so", function () { - beforeEach(function () { + beforeAll(function () { this.apps = [ { appid: 1, @@ -357,7 +357,7 @@ describe("game.service.js", () => { }); describe("discovers one game and one downloadable content out of a batch of three steamApps, so", function () { - beforeEach(function () { + beforeAll(function () { this.apps = [ { appid: 1, @@ -462,7 +462,7 @@ describe("game.service.js", () => { describe(".identifyGames", function () { describe("checks which steam apps are games and instantiates them, so", function () { describe("when no games out of a batch of one steamApp is passed in,", function () { - beforeEach(function () { + beforeAll(function () { this.updatedSteamApps = [ { appid: 1, @@ -480,7 +480,7 @@ describe("game.service.js", () => { }); describe("when one game out of a batch of two steamApps is passed in,", function () { - beforeEach(function () { + beforeAll(function () { this.updatedSteamApps = [ { appid: 1, @@ -508,7 +508,7 @@ describe("game.service.js", () => { }); describe("when two games out of a batch of three steamApps is passed in,", function () { - beforeEach(function () { + beforeAll(function () { this.updatedSteamApps = [ { appid: 1, @@ -549,7 +549,7 @@ describe("game.service.js", () => { describe(".assignType", function () { describe("checks if result contains a value. If so, sets the type property to 'games'. So", function () { describe("when result does not contain a value,", function () { - beforeEach(function () { + beforeAll(function () { this.app = { id: 1, name: "Feartress" }; this.steamApp = SteamApp.oneFromSteamApi(this.app); @@ -562,7 +562,7 @@ describe("game.service.js", () => { }); describe("when the result contains a value,", function () { - beforeEach(function () { + beforeAll(function () { this.app = { id: 1, name: "Feartress" }; this.steamApp = SteamApp.oneFromSteamApi(this.app); @@ -578,7 +578,7 @@ describe("game.service.js", () => { describe(".updateMissingDetails.", function () { describe("When we try to update two games with missing details,", function () { - beforeEach(function () { + beforeAll(function () { this.games = getXsteamchartsInstantiatedGames(2); const htmlDetailsPages = [ @@ -613,7 +613,7 @@ describe("game.service.js", () => { describe(".getSteamDbReleaseDate.", function () { describe("When we provide a html page that doesn't contain a valid date,", function () { - beforeEach(function () { + beforeAll(function () { this.result = getSteamDbReleaseDate(karmazooHtmlDetailsPageSteamDb); }); @@ -623,7 +623,7 @@ describe("game.service.js", () => { }); describe("When we provide a html page that contains a valid date,", function () { - beforeEach(function () { + beforeAll(function () { this.date = new Date("11 August 2020 UTC"); this.result = getSteamDbReleaseDate(riskOfRainHtmlDetailsSteamDb); @@ -639,7 +639,7 @@ describe("game.service.js", () => { }); describe("When we provide a html page that doesn't contain a date section", function () { - beforeEach(function () { + beforeAll(function () { this.result = getSteamDbReleaseDate(riskOfRainHtmlDetailsPageMissingInfo); }); @@ -651,7 +651,7 @@ describe("game.service.js", () => { describe(".getSteamDbDevelopers.", function () { describe("When we provide a html page that contains two developers,", function () { - beforeEach(function () { + beforeAll(function () { this.result = getSteamDbDevelopers(counterStrikeHtmlDetailsSteamDb); }); @@ -669,7 +669,7 @@ describe("game.service.js", () => { }); describe("When we provide a html page that doesn't contain a developer section", function () { - beforeEach(function () { + beforeAll(function () { this.result = getSteamDbDevelopers(riskOfRainHtmlDetailsPageMissingInfo); }); @@ -681,7 +681,7 @@ describe("game.service.js", () => { describe(".getSteamDbGenres.", function () { describe("When we provide a html page that contains the genres,", function () { - beforeEach(function () { + beforeAll(function () { this.result = getSteamDbGenres(riskOfRainHtmlDetailsSteamDb); }); @@ -699,7 +699,7 @@ describe("game.service.js", () => { }); describe("When we provide a html page that doesn't contain a genres section,", function () { - beforeEach(function () { + beforeAll(function () { this.result = getSteamDbGenres(riskOfRainHtmlDetailsPageMissingInfo); }); @@ -711,7 +711,7 @@ describe("game.service.js", () => { describe(".getSteamDbDescription.", function () { describe("When we provide a html page that contains the description,", function () { - beforeEach(function () { + beforeAll(function () { this.result = getSteamDbDescription(riskOfRainHtmlDetailsSteamDb); }); @@ -723,7 +723,7 @@ describe("game.service.js", () => { }); describe("When we provide a html page that doesn't contain a description section,", function () { - beforeEach(function () { + beforeAll(function () { this.result = getSteamDbDescription(riskOfRainHtmlDetailsPageMissingInfo); }); @@ -735,7 +735,7 @@ describe("game.service.js", () => { describe(".updateMissingReleaseDates.", function () { describe("When we try to update two games with missing release dates,", function () { - beforeEach(function () { + beforeAll(function () { this.games = getXsteamchartsInstantiatedGames(2); const htmlDetailsPages = [ @@ -762,7 +762,7 @@ describe("game.service.js", () => { describe(".getSteamDbReleaseDate.", function () { describe("When we provide a html page that doesn't contain a valid release date,", function () { - beforeEach(function () { + beforeAll(function () { this.result = getSteamDbReleaseDate(karmazooHtmlDetailsPageSteamDb); }); @@ -772,7 +772,7 @@ describe("game.service.js", () => { }); describe("When we provide a html page that contains a valid release date,", function () { - beforeEach(function () { + beforeAll(function () { this.date = new Date("11 August 2020 UTC"); this.result = getSteamDbReleaseDate(riskOfRainHtmlDetailsSteamDb); @@ -788,7 +788,7 @@ describe("game.service.js", () => { }); describe("When we provide a html page that doesn't contain a date section", function () { - beforeEach(function () { + beforeAll(function () { this.result = getSteamDbReleaseDate(riskOfRainHtmlDetailsPageMissingInfo); }); diff --git a/backend/src/features/player-history-aggregator/player.history.aggregator.spec.js b/backend/src/features/player-history-aggregator/player.history.aggregator.spec.js index ab7f90dda..b05a62e19 100644 --- a/backend/src/features/player-history-aggregator/player.history.aggregator.spec.js +++ b/backend/src/features/player-history-aggregator/player.history.aggregator.spec.js @@ -10,7 +10,7 @@ import { createLoggerMock } from "../../utils/logger.mock.js"; describe("PlayerHistoryAggregator", function () { describe(".addPlayerHistoryFromSteamcharts", function () { describe("finds the player history for one game in a batch of one and updates the game data", function () { - beforeEach(async function () { + beforeAll(async function () { this.steamClientMock = createSteamMock([crushTheCastleHtmlDetailsSteamcharts]); this.gamesRepositoryMock = createGamesRepositoryMock( @@ -96,7 +96,7 @@ describe("PlayerHistoryAggregator", function () { }); describe("finds the player history for one game in a batch of two and updates the game data", () => { - beforeEach(async function () { + beforeAll(async function () { this.steamClientMock = createSteamMock([crushTheCastleHtmlDetailsSteamcharts]); this.gamesRepositoryMock = createGamesRepositoryMock( @@ -184,7 +184,7 @@ describe("PlayerHistoryAggregator", function () { }); describe("finds no games in the database and finishes", () => { - beforeEach(async function () { + beforeAll(async function () { this.steamClientMock = createSteamMock([], ""); this.gamesRepositoryMock = createGamesRepositoryMock([]); @@ -231,7 +231,7 @@ describe("PlayerHistoryAggregator", function () { describe(".addCurrentPlayers()", () => { describe("does not have any games to check for current player numbers", function () { - beforeEach(async function () { + beforeAll(async function () { this.gamesRepositoryMock = createGamesRepositoryMock("", []); this.historyChecksRepositoryMock = createHistoryChecksRepositoryMock(); this.playerHistoryRepositoryMock = createPlayerHistoryRepositoryMock(); @@ -269,7 +269,7 @@ describe("PlayerHistoryAggregator", function () { }); describe("gets current players for one game in a batch of one, and adds the players", function () { - beforeEach(async function () { + beforeAll(async function () { jasmine.clock().mockDate(new Date()); this.gamesRepositoryMock = createGamesRepositoryMock( @@ -301,7 +301,7 @@ describe("PlayerHistoryAggregator", function () { await agg.addCurrentPlayers(); }); - afterEach(function () { + afterAll(function () { jasmine.clock().uninstall(); }); diff --git a/backend/src/features/player-history-aggregator/services/player.history.service.spec.js b/backend/src/features/player-history-aggregator/services/player.history.service.spec.js index 25f98f34a..84430a15b 100644 --- a/backend/src/features/player-history-aggregator/services/player.history.service.spec.js +++ b/backend/src/features/player-history-aggregator/services/player.history.service.spec.js @@ -7,7 +7,7 @@ import { PlayerHistory } from "../../../models/player.history.js"; describe("player.history.service.js", function () { describe(".addPlayerHistoriesFromSteamcharts adds the player histories from Steamcharts to each game object", function () { describe("When a map of games and its corresponding Steamcharts pages is provided the player histories are parsed from the pages, so that", function () { - beforeEach(function () { + beforeAll(function () { const map = new Map(); const firstPage = eldenRingHttpDetailsSteamcharts; const secondPage = crushTheCastleHtmlDetailsSteamcharts; @@ -55,7 +55,7 @@ describe("player.history.service.js", function () { }); describe("When the gamesPagesMap's page value is an empty string", function () { - beforeEach(function () { + beforeAll(function () { const map = new Map(); const game = { diff --git a/backend/src/features/steam-apps-aggregator/steam.apps.aggregator.spec.js b/backend/src/features/steam-apps-aggregator/steam.apps.aggregator.spec.js index acba3115e..2193ad87b 100644 --- a/backend/src/features/steam-apps-aggregator/steam.apps.aggregator.spec.js +++ b/backend/src/features/steam-apps-aggregator/steam.apps.aggregator.spec.js @@ -17,7 +17,7 @@ describe("SteamAppsAggregator", () => { }); describe("collects steam apps for the first time and finishes", () => { - beforeEach(async () => { + beforeAll(async () => { steamClientMock = createSteamMock(smallestGamesMock); steamAppsUpdateTimestampsRepositoryMock = @@ -92,7 +92,7 @@ describe("SteamAppsAggregator", () => { let steamAppsDifference; describe("while finding new games and finishes", () => { - beforeEach(async () => { + beforeAll(async () => { steamClientMock = createSteamMock(gamesMock); steamAppsUpdateTimestampsRepositoryMock = @@ -178,7 +178,7 @@ describe("SteamAppsAggregator", () => { }); describe("without new games and finishes", () => { - beforeEach(async () => { + beforeAll(async () => { steamClientMock = createSteamMock(smallestGamesMock); steamAppsUpdateTimestampsRepositoryMock = @@ -253,7 +253,7 @@ describe("SteamAppsAggregator", () => { }); describe("executes successfully by not performing any updates", () => { - beforeEach(async () => { + beforeAll(async () => { steamClientMock = createSteamMock(smallestGamesMock); steamAppsUpdateTimestampsRepositoryMock = @@ -275,7 +275,7 @@ describe("SteamAppsAggregator", () => { await agg.collectSteamApps(); }); - afterEach(function () { + afterAll(function () { jasmine.clock().uninstall(); }); diff --git a/backend/src/models/game.spec.js b/backend/src/models/game.spec.js index 7f15eeff6..b943db7de 100644 --- a/backend/src/models/game.spec.js +++ b/backend/src/models/game.spec.js @@ -13,7 +13,7 @@ describe("game.js", function () { }); describe("is called with incomplete arguments, ", function () { - beforeEach(function () { + beforeAll(function () { this.testObject = { id: 123, name: "test game", @@ -26,7 +26,7 @@ describe("game.js", function () { }); describe("is called with appropriate attributes, the returned value", function () { - beforeEach(function () { + beforeAll(function () { this.testObject = { appid: 123, name: "test game", @@ -103,7 +103,7 @@ describe("game.js", function () { }); describe("is called with appropriate attributes, but the releaseDate and Developers are empty the returned value", function () { - beforeEach(function () { + beforeAll(function () { this.testObject = { appid: 123, name: "test game", @@ -161,7 +161,7 @@ describe("game.js", function () { }); describe("is called with incomplete arguments, ", function () { - beforeEach(function () { + beforeAll(function () { this.testObject = { id: 123, name: "test game", @@ -174,7 +174,7 @@ describe("game.js", function () { }); describe("is called with appropriate attributes, the returned value", function () { - beforeEach(function () { + beforeAll(function () { this.testObject = { appid: 123, name: "test game", @@ -233,7 +233,7 @@ describe("game.js", function () { }); describe("is called with incomplete arguments, ", function () { - beforeEach(function () { + beforeAll(function () { this.testObject = { id: 123, name: "test game", @@ -246,7 +246,7 @@ describe("game.js", function () { }); describe("is called with appropriate attributes, the returned value", function () { - beforeEach(function () { + beforeAll(function () { this.testObject = { id: 123, name: "test game", @@ -310,7 +310,7 @@ describe("game.js", function () { describe(".pushCurrentPlayers creates a new player history entry or updates an existing one.", function () { describe("When this month's player history entry already exists,", function () { describe("players are added to the existing entry.", function () { - beforeEach(function () { + beforeAll(function () { this.currentPlayers = 45; const playerHistory = [ @@ -350,7 +350,7 @@ describe("game.js", function () { describe("When this month's player history entry does not exist yet", function () { describe("An entry for the current month is created. So,", function () { - beforeEach(function () { + beforeAll(function () { this.currentPlayers = 33; const playerHistory = [ @@ -392,7 +392,7 @@ describe("game.js", function () { }); describe(".pushSteamchartsPlayerHistory adds player histories from Steamcharts to existing entries while keeping the order intact.", function () { - beforeEach(function () { + beforeAll(function () { const steamApp = getXSampleSteamApps(1); this.releaseDate = ""; @@ -444,7 +444,7 @@ describe("game.js", function () { describe(".updateGameDetails", function () { describe("When we try to update missing developers,", function () { - beforeEach(function () { + beforeAll(function () { this.developers = ["Valve", "Test Dev"]; this.game = getXGamesWithoutDetails(1)[0]; @@ -462,7 +462,7 @@ describe("game.js", function () { }); describe("When we try to update existing developers,", function () { - beforeEach(function () { + beforeAll(function () { this.game = getOneSteamAppInstantiatedGame(); this.game.updateGameDetails(["Test Dev"], [], ""); @@ -478,7 +478,7 @@ describe("game.js", function () { }); describe("When we try to update the missing genres,", function () { - beforeEach(function () { + beforeAll(function () { this.genres = ["RPG", "Strategy"]; this.game = getXGamesWithoutDetails(1)[0]; @@ -496,7 +496,7 @@ describe("game.js", function () { }); describe("When we try to update existing genres,", function () { - beforeEach(function () { + beforeAll(function () { this.game = getOneSteamAppInstantiatedGame(); this.game.updateGameDetails([], ["Test Genre"], ""); @@ -512,7 +512,7 @@ describe("game.js", function () { }); describe("When we try to update the missing description,", function () { - beforeEach(function () { + beforeAll(function () { this.description = "Test description"; this.game = getXGamesWithoutDetails(1)[0]; @@ -530,7 +530,7 @@ describe("game.js", function () { }); describe("When we try to update an existing description,", function () { - beforeEach(function () { + beforeAll(function () { this.game = getOneSteamAppInstantiatedGame(); this.game.updateGameDetails([], [], "Test description"); @@ -548,7 +548,7 @@ describe("game.js", function () { describe(".updateReleaseDate", function () { describe("When we try to update a missing release date,", function () { - beforeEach(function () { + beforeAll(function () { this.releaseDate = new Date("23 July 2023"); this.game = getXGamesWithoutDetails(1)[0]; @@ -566,7 +566,7 @@ describe("game.js", function () { }); describe("When we try to update an existing release date,", function () { - beforeEach(function () { + beforeAll(function () { this.game = getOneSteamAppInstantiatedGame(); this.game.updateReleaseDate("22 July 2019"); diff --git a/backend/src/models/history.check.spec.js b/backend/src/models/history.check.spec.js index 56511e2ea..f91cdbfe9 100644 --- a/backend/src/models/history.check.spec.js +++ b/backend/src/models/history.check.spec.js @@ -5,7 +5,7 @@ describe("history.check.js", function () { describe("HistoryCheck", function () { describe(".manyFromSteamchartsPages adds a HistoryCheck instance for each game in the gamesPagesMap.", function () { describe("When the gamesPagesMap's pages properties contain one truthy and one falsy value", function () { - beforeEach(function () { + beforeAll(function () { this.firstGame = { id: 1 }; this.secondGame = { id: 2 }; @@ -65,7 +65,7 @@ describe("history.check.js", function () { describe(".manyFromGames adds a HistoryCheck instance for each game in games array", function () { describe("when the games array has two game values", function () { - beforeEach(function () { + beforeAll(function () { this.games = [{ id: 1 }, { id: 2 }]; this.result = HistoryCheck.manyFromGames(this.games); diff --git a/backend/src/models/player.history.spec.js b/backend/src/models/player.history.spec.js index e06162dfb..481672b98 100644 --- a/backend/src/models/player.history.spec.js +++ b/backend/src/models/player.history.spec.js @@ -4,7 +4,7 @@ import { TrackedPlayers } from "./tracked.players.js"; describe("PlayerHistory", function () { describe(".manyFromDbEntry creates a list of PlayerHistory instances from a list of PlayerHistory database documents.", function () { describe("When a list of history objects is passed in, ", function () { - beforeEach(function () { + beforeAll(function () { const firstDate = new Date("December 2022"); const secondDate = new Date("November 2022"); @@ -62,7 +62,7 @@ describe("PlayerHistory", function () { }); describe("When no documents are provided,", function () { - beforeEach(function () { + beforeAll(function () { this.result = PlayerHistory.manyFromDbEntry([]); }); @@ -74,7 +74,7 @@ describe("PlayerHistory", function () { describe(".fromRawData creates a new PlayerHistory instance.", function () { describe("When players and a date are passed in,", function () { - beforeEach(function () { + beforeAll(function () { this.players = 62; this.date = "September 2014"; @@ -109,14 +109,14 @@ describe("PlayerHistory", function () { describe(".newMonthlyEntry creates a new PlayerHistory instance for the current month.", function () { describe("When players are passed in,", function () { - beforeEach(function () { + beforeAll(function () { jasmine.clock().mockDate(new Date()); this.players = 42; this.result = PlayerHistory.newMonthlyEntry(this.players); }); - afterEach(function () { + afterAll(function () { jasmine.clock().uninstall(); }); @@ -148,7 +148,7 @@ describe("PlayerHistory", function () { describe(".pushTrackedPlayers adds an new instance of tracked players to PlayerHistory and calculates the average players property.", function () { describe("When players are passed in,", function () { - beforeEach(function () { + beforeAll(function () { jasmine.clock().mockDate(new Date()); this.players = 10; @@ -158,7 +158,7 @@ describe("PlayerHistory", function () { this.result.pushTrackedPlayers(this.players); }); - afterEach(function () { + afterAll(function () { jasmine.clock().uninstall(); }); @@ -180,7 +180,7 @@ describe("PlayerHistory", function () { }); describe("When players and a date are passed in,", function () { - beforeEach(function () { + beforeAll(function () { this.players = 10; this.date = "October 2020"; @@ -206,7 +206,7 @@ describe("PlayerHistory", function () { }); describe(".calcAveragePlayers calculates the PlayerHistory's average players. When the method runs,", function () { - beforeEach(function () { + beforeAll(function () { const firstPlayers = "102"; const secondPlayers = "53"; const pastDate = "August 2019"; diff --git a/backend/src/models/steam.app.spec.js b/backend/src/models/steam.app.spec.js index 1e7f4d901..09d0c19a4 100644 --- a/backend/src/models/steam.app.spec.js +++ b/backend/src/models/steam.app.spec.js @@ -6,7 +6,7 @@ import { SteamApp } from "./steam.app.js"; describe("SteamApp", function () { describe(".copy", function () { describe("creates a copy of a steamApp instance. When this is done,", function () { - beforeEach(function () { + beforeAll(function () { this.app = { name: "Castlevania", appid: 1, @@ -33,7 +33,7 @@ describe("SteamApp", function () { describe(".triedViaSteamWeb", function () { describe("pushes 'steamWeb' into the triedVia property. When this is done,", function () { - beforeEach(function () { + beforeAll(function () { this.app = { name: "Castlevania", appid: 1, @@ -52,7 +52,7 @@ describe("SteamApp", function () { describe(".triedViaSteamchartsWeb", function () { describe("pushes 'steamCharts' into the triedVia property. When this is done,", function () { - beforeEach(function () { + beforeAll(function () { this.app = { name: "Castlevania", appid: 1, @@ -74,7 +74,7 @@ describe("SteamApp", function () { describe(".isGame", function () { describe("checks if the type property of the class instance equals 'games'. So, ", function () { describe("if an app's type property equals 'game'", function () { - beforeEach(function () { + beforeAll(function () { this.app = { name: "Castlevania", appid: 1, @@ -90,7 +90,7 @@ describe("SteamApp", function () { }); describe("if an app's type property does not equal 'game'", function () { - beforeEach(function () { + beforeAll(function () { this.app = { name: "Castlevania", appid: 1, @@ -109,7 +109,7 @@ describe("SteamApp", function () { describe(".appType", function () { describe("sets the 'type' property to whatever was passed in as an argument. When this is done,", function () { - beforeEach(function () { + beforeAll(function () { this.app = { name: "Castlevania", appid: 1, @@ -130,7 +130,7 @@ describe("SteamApp", function () { describe(".manyFromSteamApi returns an array of SteamApp instances.", function () { describe("When two apps are passed into it,", function () { - beforeEach(function () { + beforeAll(function () { this.apps = [ { name: "Castlevania", @@ -161,7 +161,7 @@ describe("SteamApp", function () { describe(".oneFromSteamApi returns an instance of steamApp.", function () { describe("When an 'app' object is passed in, the returned instance", function () { - beforeEach(function () { + beforeAll(function () { this.app = { name: "Castlevania", appid: 1, @@ -186,7 +186,7 @@ describe("SteamApp", function () { describe(".manyFromDbEntries returns an array of SteamApp instances.", function () { describe("When dbEntries is passed into it,", function () { - beforeEach(function () { + beforeAll(function () { this.dbEntries = [ { name: "Castlevania", @@ -224,7 +224,7 @@ describe("SteamApp", function () { describe(".oneFromDbEntry returns an instance of SteamApp.", function () { describe("When a dbEntry is passed in, the resulting SteamApp instance", function () { - beforeEach(function () { + beforeAll(function () { this.dbEntry = { name: "Castlevania", appid: 1, @@ -264,7 +264,7 @@ describe("SteamApp", function () { describe(".diff", function () { describe("finds the diff of two arrays of steam apps successfully in a big data set", function () { - beforeEach(function () { + beforeAll(function () { this.array = SteamApp.diff(gamesMock, smallestGamesMock); }); @@ -274,7 +274,7 @@ describe("SteamApp", function () { }); describe("finds the diff of two arrays of steam apps in a tiny data set", function () { - beforeEach(function () { + beforeAll(function () { this.appsFromApi = [ { appid: 9821, diff --git a/backend/src/models/tracked.players.spec.js b/backend/src/models/tracked.players.spec.js index 379389dad..4653919d8 100644 --- a/backend/src/models/tracked.players.spec.js +++ b/backend/src/models/tracked.players.spec.js @@ -3,13 +3,13 @@ import { TrackedPlayers } from "./tracked.players.js"; describe("TrackedPlayers", function () { describe("Instantiates the TrackedPlayers class.", function () { describe("When no date is provided", function () { - beforeEach(function () { + beforeAll(function () { jasmine.clock().mockDate(new Date()); this.players = new TrackedPlayers("24"); }); - afterEach(function () { + afterAll(function () { jasmine.clock().uninstall(); }); @@ -19,7 +19,7 @@ describe("TrackedPlayers", function () { }); describe("when a date with specified hour, minute or seconds is provided", function () { - beforeEach(function () { + beforeAll(function () { this.currentDate = new Date("11:24 September 2000"); this.players = new TrackedPlayers("24", "11:24 September 2000"); @@ -31,7 +31,7 @@ describe("TrackedPlayers", function () { }); describe("when a date without specified hours, minutes or seconds is provided", function () { - beforeEach(function () { + beforeAll(function () { const date = new Date("September 2000"); this.players = new TrackedPlayers("24", date); @@ -51,7 +51,7 @@ describe("TrackedPlayers", function () { describe(".manyFromDbEntry creates a list of TrackedPlayers instances from a list of PlayerHistory objects", function () { describe("When an list of PlayerHistory objects is passed in,", function () { - beforeEach(function () { + beforeAll(function () { jasmine.clock().mockDate(new Date()); this.currentDate = new Date(); @@ -70,7 +70,7 @@ describe("TrackedPlayers", function () { this.result = TrackedPlayers.manyFromDbEntry(this.trackedPlayersArray); }); - afterEach(function () { + afterAll(function () { jasmine.clock().uninstall(); }); @@ -100,7 +100,7 @@ describe("TrackedPlayers", function () { }); describe("When the passed in array is empty,", function () { - beforeEach(function () { + beforeAll(function () { this.result = TrackedPlayers.manyFromDbEntry([]); }); diff --git a/backend/src/utils/runner.spec.js b/backend/src/utils/runner.spec.js index b1c0e4d4b..a84b2fc85 100644 --- a/backend/src/utils/runner.spec.js +++ b/backend/src/utils/runner.spec.js @@ -126,7 +126,7 @@ describe("runner.js", () => { }); describe("when one running function throws an unexpected error,", function () { - beforeEach(function () { + beforeAll(function () { this.unexpectedErrorThrower = async function () { throw new UnexpectedError(); }; diff --git a/package-lock.json b/package-lock.json index aa90ea036..14344d01c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,6 +30,7 @@ "devDependencies": { "eslint": "8.11.0", "jasmine": "4.0.2", + "jasmine-console-reporter": "3.1.0", "mongodb-memory-server": "8.12.2", "pino-pretty": "10.2.0", "prettier": "2.6.0" @@ -7256,6 +7257,30 @@ "node": ">= 10.0" } }, + "node_modules/cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==", + "dev": true, + "dependencies": { + "restore-cursor": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.1.tgz", + "integrity": "sha512-jHgecW0pxkonBJdrKsqxgRX9AcG+u/5k0Q7WPDfi8AogLAdwxEkyYYNWwZ5GvVFoFx2uiY1eNcSK00fh+1+FyQ==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -7266,6 +7291,15 @@ "wrap-ansi": "^7.0.0" } }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -8058,6 +8092,18 @@ "node": ">= 10" } }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dev": true, + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/define-lazy-prop": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", @@ -11202,6 +11248,103 @@ "jasmine": "bin/jasmine.js" } }, + "node_modules/jasmine-console-reporter": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jasmine-console-reporter/-/jasmine-console-reporter-3.1.0.tgz", + "integrity": "sha512-fNP6XlgkIyNvfr6JVMJudZL9qWNY2K7l934Ojj4k8J09/QXf4xYf2Mc7MUgcsDhqIb2zTkLd2LsBJWFvJz41/w==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "chalk": "^2.4.1", + "ci-info": "^1.4.0", + "node-emoji": "^1.8.1", + "ora": "^3.0.0", + "perfy": "^1.1.5" + }, + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jasmine": ">=3.0.0" + } + }, + "node_modules/jasmine-console-reporter/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jasmine-console-reporter/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jasmine-console-reporter/node_modules/ci-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", + "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", + "dev": true + }, + "node_modules/jasmine-console-reporter/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/jasmine-console-reporter/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/jasmine-console-reporter/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/jasmine-console-reporter/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/jasmine-console-reporter/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/jasmine-core": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-4.6.0.tgz", @@ -13646,6 +13789,89 @@ "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" }, + "node_modules/log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "dev": true, + "dependencies": { + "chalk": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/log-symbols/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/log-symbols/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/log-symbols/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/log-symbols/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/log-symbols/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/log-symbols/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -14140,6 +14366,15 @@ "tslib": "^2.0.3" } }, + "node_modules/node-emoji": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", + "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", + "dev": true, + "dependencies": { + "lodash": "^4.17.21" + } + }, "node_modules/node-forge": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", @@ -14439,6 +14674,115 @@ "node": ">= 0.8.0" } }, + "node_modules/ora": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-3.4.0.tgz", + "integrity": "sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg==", + "dev": true, + "dependencies": { + "chalk": "^2.4.2", + "cli-cursor": "^2.1.0", + "cli-spinners": "^2.0.0", + "log-symbols": "^2.2.0", + "strip-ansi": "^5.2.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ora/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ora/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ora/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ora/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/ora/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/ora/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/ora/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ora/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ora/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -14604,6 +14948,12 @@ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" }, + "node_modules/perfy": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/perfy/-/perfy-1.1.5.tgz", + "integrity": "sha512-/ieVBpMaPTJf83YTUl2TImsSwMEJ23qGP2w27pE6aX+NrB/ZRGqOnQZpl7J719yFwd+ebDiHguPNFeMSamyK7w==", + "dev": true + }, "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -16860,6 +17210,40 @@ "node": ">=10" } }, + "node_modules/restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==", + "dev": true, + "dependencies": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/restore-cursor/node_modules/mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/restore-cursor/node_modules/onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/ret": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/ret/-/ret-0.2.2.tgz", @@ -18863,6 +19247,15 @@ "minimalistic-assert": "^1.0.0" } }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dev": true, + "dependencies": { + "defaults": "^1.0.3" + } + }, "node_modules/web-vitals": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-2.1.4.tgz", @@ -24669,6 +25062,7 @@ "fastify": "4.6.0", "fastify-healthcheck": "4.4.0", "jasmine": "4.0.2", + "jasmine-console-reporter": "3.1.0", "linkedom": "0.16.1", "lodash.clonedeep": "4.5.0", "mongodb": "4.5.0", @@ -25031,6 +25425,21 @@ "source-map": "~0.6.0" } }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==", + "dev": true, + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "cli-spinners": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.1.tgz", + "integrity": "sha512-jHgecW0pxkonBJdrKsqxgRX9AcG+u/5k0Q7WPDfi8AogLAdwxEkyYYNWwZ5GvVFoFx2uiY1eNcSK00fh+1+FyQ==", + "dev": true + }, "cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -25041,6 +25450,12 @@ "wrap-ansi": "^7.0.0" } }, + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true + }, "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -25611,6 +26026,15 @@ "execa": "^5.0.0" } }, + "defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dev": true, + "requires": { + "clone": "^1.0.2" + } + }, "define-lazy-prop": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", @@ -27911,6 +28335,84 @@ "jasmine-core": "^4.0.0" } }, + "jasmine-console-reporter": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jasmine-console-reporter/-/jasmine-console-reporter-3.1.0.tgz", + "integrity": "sha512-fNP6XlgkIyNvfr6JVMJudZL9qWNY2K7l934Ojj4k8J09/QXf4xYf2Mc7MUgcsDhqIb2zTkLd2LsBJWFvJz41/w==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "chalk": "^2.4.1", + "ci-info": "^1.4.0", + "node-emoji": "^1.8.1", + "ora": "^3.0.0", + "perfy": "^1.1.5" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "ci-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", + "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", + "dev": true + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, "jasmine-core": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-4.6.0.tgz", @@ -29865,6 +30367,73 @@ "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" }, + "log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "dev": true, + "requires": { + "chalk": "^2.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -30239,6 +30808,15 @@ "tslib": "^2.0.3" } }, + "node-emoji": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", + "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", + "dev": true, + "requires": { + "lodash": "^4.17.21" + } + }, "node-forge": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", @@ -30448,6 +31026,93 @@ "type-check": "^0.4.0" } }, + "ora": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-3.4.0.tgz", + "integrity": "sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "cli-cursor": "^2.1.0", + "cli-spinners": "^2.0.0", + "log-symbols": "^2.2.0", + "strip-ansi": "^5.2.0", + "wcwidth": "^1.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, "p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -30576,6 +31241,12 @@ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" }, + "perfy": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/perfy/-/perfy-1.1.5.tgz", + "integrity": "sha512-/ieVBpMaPTJf83YTUl2TImsSwMEJ23qGP2w27pE6aX+NrB/ZRGqOnQZpl7J719yFwd+ebDiHguPNFeMSamyK7w==", + "dev": true + }, "picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -32044,6 +32715,33 @@ "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.1.tgz", "integrity": "sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ==" }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==", + "dev": true, + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + }, + "dependencies": { + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + } + } + }, "ret": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/ret/-/ret-0.2.2.tgz", @@ -33545,6 +34243,15 @@ "minimalistic-assert": "^1.0.0" } }, + "wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dev": true, + "requires": { + "defaults": "^1.0.3" + } + }, "web-vitals": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-2.1.4.tgz",