add unit tests

This commit is contained in:
Karsten Hassel 2021-09-07 22:07:42 +02:00
parent 093988e136
commit dd43f35bbe
3 changed files with 81 additions and 21 deletions

View File

@ -2,12 +2,21 @@ const util = require("util");
const exec = util.promisify(require("child_process").exec); const exec = util.promisify(require("child_process").exec);
const fs = require("fs"); const fs = require("fs");
const path = require("path"); const path = require("path");
const Log = require("logger");
class gitHelper { class gitHelper {
constructor() { constructor() {
this.gitRepos = []; this.gitRepos = [];
this.baseDir = path.normalize(__dirname + "/../../../"); 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) { async execShell(command) {
@ -22,7 +31,7 @@ class gitHelper {
async isGitRepo(moduleFolder) { async isGitRepo(moduleFolder) {
let res = await this.execShell("cd " + moduleFolder + " && git remote -v"); let res = await this.execShell("cd " + moduleFolder + " && git remote -v");
if (res.stderr) { 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; return false;
} else { } else {
return true; return true;
@ -32,10 +41,10 @@ class gitHelper {
add(moduleName) { add(moduleName) {
let moduleFolder = this.baseDir; let moduleFolder = this.baseDir;
if (moduleName !== "default") { if (moduleName !== "default") {
moduleFolder = moduleFolder + 'modules/' + moduleName; moduleFolder = moduleFolder + "modules/" + moduleName;
} }
try { try {
Log.info("Checking git for module: " + moduleName); this.Log.info("Checking git for module: " + moduleName);
// Throws error if file doesn't exist // Throws error if file doesn't exist
fs.statSync(path.join(moduleFolder, ".git")); fs.statSync(path.join(moduleFolder, ".git"));
// Fetch the git or throw error if no remotes // 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 // Error when directory .git doesn't exist or doesn't have any remotes
// This module is not managed with git, skip // This module is not managed with git, skip
} }
} }
async getRepoInfo(repo) { async getStatusInfo(repo) {
let gitInfo = { let gitInfo = {
module: repo.module, module: repo.module,
// commits behind: // commits behind:
@ -60,20 +68,21 @@ class gitHelper {
// current hash: // current hash:
hash: "", hash: "",
// remote branch: // remote branch:
tracking: "" tracking: "",
isBehindInStatus: false
}; };
let res; let res;
if (repo.module === "default") { if (repo.module === "default") {
// the hash is only needed for the mm repo // the hash is only needed for the mm repo
res = await this.execShell("cd " + repo.folder + " && git rev-parse HEAD"); res = await this.execShell("cd " + repo.folder + " && git rev-parse HEAD");
if (res.stderr) { 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; gitInfo.hash = res.stdout;
} }
res = await this.execShell("cd " + repo.folder + " && git status -sb"); res = await this.execShell("cd " + repo.folder + " && git status -sb");
if (res.stderr) { 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 // exit without git status info
return; return;
} }
@ -95,26 +104,47 @@ class gitHelper {
if (status[2]) { if (status[2]) {
// git fetch was already called before so `git status -sb` delivers already the behind number // 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.behind = parseInt(status[2].substring(0, status[2].length - 1));
gitInfo.isBehindInStatus = true;
}
return gitInfo; return gitInfo;
} }
res = await this.execShell("cd " + repo.folder + " && git fetch --dry-run");
async getRepoInfo(repo) {
let gitInfo = await this.getStatusInfo(repo);
if (!gitInfo) {
return;
}
if (gitInfo.isBehindInStatus) {
return gitInfo;
}
let res = await this.execShell("cd " + repo.folder + " && git fetch --dry-run");
// example output: // example output:
// From https://github.com/MichMich/MagicMirror // From https://github.com/MichMich/MagicMirror
// e40ddd4..06389e3 develop -> origin/develop // e40ddd4..06389e3 develop -> origin/develop
// here the result is in stderr (this is a git default, don't ask why ...) // here the result is in stderr (this is a git default, don't ask why ...)
if (res.stderr === "") return; const matches = res.stderr.match(this.getRefRegex(gitInfo.current));
let refs = res.stderr.match(/s*([a-z,0-9]+[.][.][a-z,0-9]+)s*/g)[0]; if (!matches || !matches[0]) {
if (refs === "") { // no refs found, nothing to do
// if match fails set behind to a number greater 0 and return return;
gitInfo.behind = 1;
return gitInfo;
} }
// get behind with refs // 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); gitInfo.behind = parseInt(res.stdout);
return gitInfo; 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() { async getRepos() {
const gitResultList = []; const gitResultList = [];
for (let repo of this.gitRepos) { for (let repo of this.gitRepos) {
@ -126,7 +156,6 @@ class gitHelper {
return gitResultList; return gitResultList;
} }
}
};
module.exports.gitHelper = gitHelper; module.exports.gitHelper = gitHelper;

View File

@ -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);
});
});