From dd43f35bbe323cc34db7c510d388793cd98a0d7a Mon Sep 17 00:00:00 2001 From: Karsten Hassel Date: Tue, 7 Sep 2021 22:07:42 +0200 Subject: [PATCH] add unit tests --- .../default/updatenotification/git_helper.js | 69 +++++++++++++------ .../default/updatenotification/node_helper.js | 2 +- .../unit/functions/updatenotification_spec.js | 31 +++++++++ 3 files changed, 81 insertions(+), 21 deletions(-) create mode 100644 tests/unit/functions/updatenotification_spec.js diff --git a/modules/default/updatenotification/git_helper.js b/modules/default/updatenotification/git_helper.js index 323565e7..fbba6315 100644 --- a/modules/default/updatenotification/git_helper.js +++ b/modules/default/updatenotification/git_helper.js @@ -2,12 +2,21 @@ const util = require("util"); const exec = util.promisify(require("child_process").exec); const fs = require("fs"); const path = require("path"); -const Log = require("logger"); class gitHelper { - constructor(){ + constructor() { this.gitRepos = []; this.baseDir = path.normalize(__dirname + "/../../../"); + if (process.env.JEST_WORKER_ID === undefined) { + this.Log = require("logger"); + } else { + // if we are running with jest + this.Log = require("../../../tests/unit/mocks/logger.js"); + } + } + + getRefRegex(branch) { + return new RegExp("s*([a-z,0-9]+[.][.][a-z,0-9]+) " + branch, "g"); } async execShell(command) { @@ -22,7 +31,7 @@ class gitHelper { async isGitRepo(moduleFolder) { let res = await this.execShell("cd " + moduleFolder + " && git remote -v"); if (res.stderr) { - Log.error("Failed to fetch git data for " + moduleFolder + ": " + res.stderr); + this.Log.error("Failed to fetch git data for " + moduleFolder + ": " + res.stderr); return false; } else { return true; @@ -32,10 +41,10 @@ class gitHelper { add(moduleName) { let moduleFolder = this.baseDir; if (moduleName !== "default") { - moduleFolder = moduleFolder + 'modules/' + moduleName; + moduleFolder = moduleFolder + "modules/" + moduleName; } try { - Log.info("Checking git for module: " + moduleName); + this.Log.info("Checking git for module: " + moduleName); // Throws error if file doesn't exist fs.statSync(path.join(moduleFolder, ".git")); // Fetch the git or throw error if no remotes @@ -47,10 +56,9 @@ class gitHelper { // Error when directory .git doesn't exist or doesn't have any remotes // This module is not managed with git, skip } - } - async getRepoInfo(repo) { + async getStatusInfo(repo) { let gitInfo = { module: repo.module, // commits behind: @@ -60,20 +68,21 @@ class gitHelper { // current hash: hash: "", // remote branch: - tracking: "" + tracking: "", + isBehindInStatus: false }; let res; if (repo.module === "default") { // the hash is only needed for the mm repo res = await this.execShell("cd " + repo.folder + " && git rev-parse HEAD"); if (res.stderr) { - Log.error("Failed to get current commit hash for " + repo.module + ": " + res.stderr); + this.Log.error("Failed to get current commit hash for " + repo.module + ": " + res.stderr); } gitInfo.hash = res.stdout; } res = await this.execShell("cd " + repo.folder + " && git status -sb"); if (res.stderr) { - Log.error("Failed to get git status for " + repo.module + ": " + res.stderr); + this.Log.error("Failed to get git status for " + repo.module + ": " + res.stderr); // exit without git status info return; } @@ -95,26 +104,47 @@ class gitHelper { if (status[2]) { // git fetch was already called before so `git status -sb` delivers already the behind number gitInfo.behind = parseInt(status[2].substring(0, status[2].length - 1)); + gitInfo.isBehindInStatus = true; + } + return gitInfo; + } + + async getRepoInfo(repo) { + let gitInfo = await this.getStatusInfo(repo); + if (!gitInfo) { + return; + } + if (gitInfo.isBehindInStatus) { return gitInfo; } - res = await this.execShell("cd " + repo.folder + " && git fetch --dry-run"); + let res = await this.execShell("cd " + repo.folder + " && git fetch --dry-run"); // example output: // From https://github.com/MichMich/MagicMirror // e40ddd4..06389e3 develop -> origin/develop // here the result is in stderr (this is a git default, don't ask why ...) - if (res.stderr === "") return; - let refs = res.stderr.match(/s*([a-z,0-9]+[.][.][a-z,0-9]+)s*/g)[0]; - if (refs === "") { - // if match fails set behind to a number greater 0 and return - gitInfo.behind = 1; - return gitInfo; + const matches = res.stderr.match(this.getRefRegex(gitInfo.current)); + if (!matches || !matches[0]) { + // no refs found, nothing to do + return; } // get behind with refs - res = await this.execShell("cd " + repo.folder + " && git rev-list --ancestry-path --count " + refs); + res = await this.execShell("cd " + repo.folder + " && git rev-list --ancestry-path --count " + matches[0]); gitInfo.behind = parseInt(res.stdout); return gitInfo; } + async getStatus() { + const gitResultList = []; + for (let repo of this.gitRepos) { + const gitInfo = await this.getStatusInfo(repo); + if (gitInfo) { + gitResultList.unshift(gitInfo); + } + } + + return gitResultList; + } + async getRepos() { const gitResultList = []; for (let repo of this.gitRepos) { @@ -126,7 +156,6 @@ class gitHelper { return gitResultList; } - -}; +} module.exports.gitHelper = gitHelper; diff --git a/modules/default/updatenotification/node_helper.js b/modules/default/updatenotification/node_helper.js index f697aec9..9d836f19 100644 --- a/modules/default/updatenotification/node_helper.js +++ b/modules/default/updatenotification/node_helper.js @@ -8,7 +8,7 @@ module.exports = NodeHelper.create({ updateTimer: null, updateProcessStarted: false, - gitHelper: new git_Helper.gitHelper(), + gitHelper: new git_Helper.gitHelper(), start: function () {}, diff --git a/tests/unit/functions/updatenotification_spec.js b/tests/unit/functions/updatenotification_spec.js new file mode 100644 index 00000000..79018334 --- /dev/null +++ b/tests/unit/functions/updatenotification_spec.js @@ -0,0 +1,31 @@ +const path = require("path"); +const git_Helper = require("../../../modules/default/updatenotification/git_helper.js"); +const gitHelper = new git_Helper.gitHelper(); +gitHelper.add("default"); +let branch = ""; + +describe("Updatenotification", function () { + // it is assumed that we are at the HEAD of a branch when running this tests + // and we have no foreign modules installed. + + it("should return 0 for repo count", async function () { + const arr = await gitHelper.getRepos(); + expect(arr.length).toBe(0); + }, 15000); + + it("should return valid output for git status", async function () { + const arr = await gitHelper.getStatus(); + expect(arr.length).toBe(1); + const gitInfo = arr[0]; + branch = gitInfo.current; + expect(gitInfo.current).not.toBe(""); + expect(gitInfo.tracking).not.toBe(""); + expect(gitInfo.hash).not.toBe(""); + }, 15000); + + it("should return no refs for git fetch", async function () { + const baseDir = path.normalize(__dirname + "/../../../"); + const res = await gitHelper.execShell("cd " + baseDir + " && git fetch --dry-run"); + expect(res.stderr.match(gitHelper.getRefRegex(branch))).toBe(null); + }); +});