Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FIX] Resolve properly absolute path for ui5HomeDir #588

Merged
merged 3 commits into from
Mar 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion lib/ui5Framework/AbstractResolver.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,11 @@ class AbstractResolver {
throw new Error(`AbstractResolver: Missing parameter "version"`);
}

this._ui5HomeDir = ui5HomeDir ? path.resolve(ui5HomeDir) : path.join(os.homedir(), ".ui5");
// In some CI environments, the homedir might be set explicitly to a relative
// path (e.g. "./"), but tooling requires an absolute path
this._ui5HomeDir = path.resolve(
ui5HomeDir || path.join(os.homedir(), ".ui5")
);
this._cwd = cwd ? path.resolve(cwd) : process.cwd();
this._version = version;
}
Expand Down
71 changes: 66 additions & 5 deletions test/lib/ui5framework/AbstractResolver.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,30 @@ import path from "node:path";
import os from "node:os";
import {fileURLToPath} from "node:url";
import {readFile} from "node:fs/promises";
import AbstractResolver from "../../../lib/ui5Framework/AbstractResolver.js";
import esmock from "esmock";

class MyResolver extends AbstractResolver {
static async fetchAllVersions() {}
}
test.beforeEach(async (t) => {
t.context.osHomeDirStub = sinon.stub().callsFake(() => os.homedir());
t.context.AbstractResolver = await esmock.p("../../../lib/ui5Framework/AbstractResolver.js", {
"node:os": {
homedir: t.context.osHomeDirStub
}
});

test.afterEach.always(() => {
class MyResolver extends t.context.AbstractResolver {
static async fetchAllVersions() {}
}

t.context.MyResolver = MyResolver;
});

test.afterEach.always((t) => {
esmock.purge(t.context.AbstractResolver);
sinon.restore();
});

test("AbstractResolver: abstract constructor should throw", async (t) => {
const {AbstractResolver} = t.context;
await t.throwsAsync(async () => {
new AbstractResolver({
cwd: "/test-project/",
Expand All @@ -24,6 +37,7 @@ test("AbstractResolver: abstract constructor should throw", async (t) => {
});

test("AbstractResolver: constructor", (t) => {
const {MyResolver, AbstractResolver} = t.context;
const resolver = new MyResolver({
cwd: "/test-project/",
version: "1.75.0"
Expand All @@ -33,12 +47,14 @@ test("AbstractResolver: constructor", (t) => {
});

test("AbstractResolver: constructor requires 'version'", (t) => {
const {MyResolver} = t.context;
t.throws(() => {
new MyResolver({});
}, {message: `AbstractResolver: Missing parameter "version"`});
});

test("AbstractResolver: Set absolute 'cwd'", (t) => {
const {MyResolver} = t.context;
const resolver = new MyResolver({
version: "1.75.0",
cwd: "/my-cwd"
Expand All @@ -47,6 +63,7 @@ test("AbstractResolver: Set absolute 'cwd'", (t) => {
});

test("AbstractResolver: Set relative 'cwd'", (t) => {
const {MyResolver} = t.context;
const resolver = new MyResolver({
version: "1.75.0",
cwd: "./my-cwd"
Expand All @@ -55,6 +72,7 @@ test("AbstractResolver: Set relative 'cwd'", (t) => {
});

test("AbstractResolver: Defaults 'cwd' to process.cwd()", (t) => {
const {MyResolver} = t.context;
const resolver = new MyResolver({
version: "1.75.0",
ui5HomeDir: "/ui5home"
Expand All @@ -63,6 +81,7 @@ test("AbstractResolver: Defaults 'cwd' to process.cwd()", (t) => {
});

test("AbstractResolver: Set absolute 'ui5HomeDir'", (t) => {
const {MyResolver} = t.context;
const resolver = new MyResolver({
version: "1.75.0",
ui5HomeDir: "/my-ui5HomeDir"
Expand All @@ -71,14 +90,27 @@ test("AbstractResolver: Set absolute 'ui5HomeDir'", (t) => {
});

test("AbstractResolver: Set relative 'ui5HomeDir'", (t) => {
const {MyResolver} = t.context;
const resolver = new MyResolver({
version: "1.75.0",
ui5HomeDir: "./my-ui5HomeDir"
});
t.is(resolver._ui5HomeDir, path.resolve("./my-ui5HomeDir"), "Should be resolved 'ui5HomeDir'");
});

test("AbstractResolver: 'ui5HomeDir' overriden os.homedir()", (t) => {
const {MyResolver, osHomeDirStub} = t.context;

osHomeDirStub.returns("./");

const resolver = new MyResolver({
version: "1.75.0"
});
t.is(resolver._ui5HomeDir, path.resolve("./.ui5"), "Should be resolved 'ui5HomeDir'");
});

test("AbstractResolver: Defaults 'ui5HomeDir' to ~/.ui5", (t) => {
const {MyResolver} = t.context;
const resolver = new MyResolver({
version: "1.75.0",
cwd: "/test-project/"
Expand All @@ -87,6 +119,7 @@ test("AbstractResolver: Defaults 'ui5HomeDir' to ~/.ui5", (t) => {
});

test("AbstractResolver: getLibraryMetadata should throw an Error when not implemented", async (t) => {
const {MyResolver} = t.context;
await t.throwsAsync(async () => {
const resolver = new MyResolver({
cwd: "/test-project/",
Expand All @@ -97,6 +130,7 @@ test("AbstractResolver: getLibraryMetadata should throw an Error when not implem
});

test("AbstractResolver: handleLibrary should throw an Error when not implemented", async (t) => {
const {MyResolver} = t.context;
await t.throwsAsync(async () => {
const resolver = new MyResolver({
cwd: "/test-project/",
Expand All @@ -107,6 +141,7 @@ test("AbstractResolver: handleLibrary should throw an Error when not implemented
});

test("AbstractResolver: install", async (t) => {
const {MyResolver} = t.context;
const resolver = new MyResolver({
cwd: "/test-project/",
version: "1.75.0"
Expand Down Expand Up @@ -175,6 +210,7 @@ test("AbstractResolver: install", async (t) => {
});

test("AbstractResolver: install error handling (rejection of metadata/install)", async (t) => {
const {MyResolver} = t.context;
const resolver = new MyResolver({
cwd: "/test-project/",
version: "1.75.0"
Expand Down Expand Up @@ -204,6 +240,7 @@ Failed to resolve library sap.ui.lib2: Error installing sap.ui.lib2`});
});

test("AbstractResolver: install error handling (rejection of dependency metadata/install)", async (t) => {
const {MyResolver} = t.context;
const resolver = new MyResolver({
cwd: "/test-project/",
version: "1.75.0"
Expand Down Expand Up @@ -234,6 +271,7 @@ Failed to resolve library sap.ui.lib2: Error installing sap.ui.lib2`});
});

test("AbstractResolver: install error handling (rejection of dependency install)", async (t) => {
const {MyResolver} = t.context;
const resolver = new MyResolver({
cwd: "/test-project/",
version: "1.75.0"
Expand Down Expand Up @@ -276,6 +314,7 @@ Failed to resolve library sap.ui.lib3: Error installing sap.ui.lib3`});
});

test("AbstractResolver: install error handling (handleLibrary throws error)", async (t) => {
const {MyResolver} = t.context;
const resolver = new MyResolver({
cwd: "/test-project/",
version: "1.75.0"
Expand All @@ -297,12 +336,14 @@ Failed to resolve library sap.ui.lib2: Error within handleLibrary: sap.ui.lib2`}
});

test("AbstractResolver: static fetchAllVersions should throw an Error when not implemented", async (t) => {
const {AbstractResolver} = t.context;
await t.throwsAsync(async () => {
await AbstractResolver.fetchAllVersions();
}, {message: `AbstractResolver: static fetchAllVersions must be implemented!`});
});

test.serial("AbstractResolver: Static resolveVersion resolves 'latest'", async (t) => {
const {MyResolver} = t.context;
const fetchAllVersionsStub = sinon.stub(MyResolver, "fetchAllVersions")
.returns(["1.75.0", "1.75.1", "1.76.0"]);

Expand All @@ -321,6 +362,7 @@ test.serial("AbstractResolver: Static resolveVersion resolves 'latest'", async (
});

test.serial("AbstractResolver: Static resolveVersion resolves 'MAJOR.MINOR'", async (t) => {
const {MyResolver} = t.context;
const fetchAllVersionsStub = sinon.stub(MyResolver, "fetchAllVersions")
.returns(["1.75.0", "1.75.1", "1.76.0"]);

Expand All @@ -339,6 +381,7 @@ test.serial("AbstractResolver: Static resolveVersion resolves 'MAJOR.MINOR'", as
});

test.serial("AbstractResolver: Static resolveVersion resolves 'MAJOR.MINOR.PATCH'", async (t) => {
const {MyResolver} = t.context;
const fetchAllVersionsStub = sinon.stub(MyResolver, "fetchAllVersions")
.returns(["1.75.0", "1.75.1", "1.76.0"]);

Expand All @@ -357,6 +400,7 @@ test.serial("AbstractResolver: Static resolveVersion resolves 'MAJOR.MINOR.PATCH
});

test.serial("AbstractResolver: Static resolveVersion resolves 'MAJOR.MINOR.PATCH-prerelease'", async (t) => {
const {MyResolver} = t.context;
const fetchAllVersionsStub = sinon.stub(MyResolver, "fetchAllVersions")
.returns(["1.76.0", "1.77.0", "1.78.0", "1.79.0-SNAPSHOT"]);

Expand All @@ -375,6 +419,7 @@ test.serial("AbstractResolver: Static resolveVersion resolves 'MAJOR.MINOR.PATCH
});

test.serial("AbstractResolver: Static resolveVersion does not include prereleases for 'latest' version", async (t) => {
const {MyResolver} = t.context;
const fetchAllVersionsStub = sinon.stub(MyResolver, "fetchAllVersions")
.returns(["1.76.0", "1.77.0", "1.78.0", "1.79.0-SNAPSHOT"]);

Expand All @@ -393,6 +438,7 @@ test.serial("AbstractResolver: Static resolveVersion does not include prerelease
});

test.serial("AbstractResolver: Static resolveVersion without options", async (t) => {
const {MyResolver} = t.context;
const fetchAllVersionsStub = sinon.stub(MyResolver, "fetchAllVersions")
.returns(["1.75.0"]);

Expand All @@ -406,6 +452,7 @@ test.serial("AbstractResolver: Static resolveVersion without options", async (t)
});

test.serial("AbstractResolver: Static resolveVersion throws error for 'lts'", async (t) => {
const {MyResolver} = t.context;
const fetchAllVersionsStub = sinon.stub(MyResolver, "fetchAllVersions");

const error = await t.throwsAsync(MyResolver.resolveVersion("lts", {
Expand All @@ -419,6 +466,7 @@ test.serial("AbstractResolver: Static resolveVersion throws error for 'lts'", as
});

test.serial("AbstractResolver: Static resolveVersion throws error for '1'", async (t) => {
const {MyResolver} = t.context;
const fetchAllVersionsStub = sinon.stub(MyResolver, "fetchAllVersions");

const error = await t.throwsAsync(MyResolver.resolveVersion("1", {
Expand All @@ -432,6 +480,7 @@ test.serial("AbstractResolver: Static resolveVersion throws error for '1'", asyn
});

test.serial("AbstractResolver: Static resolveVersion throws error for '1.x'", async (t) => {
const {MyResolver} = t.context;
const fetchAllVersionsStub = sinon.stub(MyResolver, "fetchAllVersions");

const error = await t.throwsAsync(MyResolver.resolveVersion("1.x", {
Expand All @@ -445,6 +494,7 @@ test.serial("AbstractResolver: Static resolveVersion throws error for '1.x'", as
});

test.serial("AbstractResolver: Static resolveVersion throws error for '1.75.x'", async (t) => {
const {MyResolver} = t.context;
const fetchAllVersionsStub = sinon.stub(MyResolver, "fetchAllVersions");

const error = await t.throwsAsync(MyResolver.resolveVersion("1.75.x", {
Expand All @@ -458,6 +508,7 @@ test.serial("AbstractResolver: Static resolveVersion throws error for '1.75.x'",
});

test.serial("AbstractResolver: Static resolveVersion throws error for '^1.75.0'", async (t) => {
const {MyResolver} = t.context;
const fetchAllVersionsStub = sinon.stub(MyResolver, "fetchAllVersions");

const error = await t.throwsAsync(MyResolver.resolveVersion("^1.75.0", {
Expand All @@ -471,6 +522,7 @@ test.serial("AbstractResolver: Static resolveVersion throws error for '^1.75.0'"
});

test.serial("AbstractResolver: Static resolveVersion throws error for '~1.75.0'", async (t) => {
const {MyResolver} = t.context;
const fetchAllVersionsStub = sinon.stub(MyResolver, "fetchAllVersions");

const error = await t.throwsAsync(MyResolver.resolveVersion("~1.75.0", {
Expand All @@ -484,6 +536,7 @@ test.serial("AbstractResolver: Static resolveVersion throws error for '~1.75.0'"
});

test.serial("AbstractResolver: Static resolveVersion throws error for version not found", async (t) => {
const {MyResolver} = t.context;
sinon.stub(MyResolver, "fetchAllVersions")
.returns(["1.75.0", "1.75.1", "1.76.0"]);

Expand All @@ -498,6 +551,7 @@ test.serial("AbstractResolver: Static resolveVersion throws error for version no

test.serial(
"AbstractResolver: Static resolveVersion throws error for version lower than lowest OpenUI5 version", async (t) => {
const {AbstractResolver} = t.context;
class Openui5Resolver extends AbstractResolver {
static async fetchAllVersions() {}
}
Expand All @@ -517,6 +571,7 @@ test.serial(

test.serial(
"AbstractResolver: Static resolveVersion throws error for version lower than lowest SAPUI5 version", async (t) => {
const {AbstractResolver} = t.context;
class Sapui5Resolver extends AbstractResolver {
static async fetchAllVersions() {}
}
Expand All @@ -536,6 +591,7 @@ test.serial(

test.serial(
"AbstractResolver: Static resolveVersion throws error when latest OpenUI5 version cannot be found", async (t) => {
const {AbstractResolver} = t.context;
class Openui5Resolver extends AbstractResolver {
static async fetchAllVersions() {}
}
Expand All @@ -554,6 +610,7 @@ test.serial(

test.serial(
"AbstractResolver: Static resolveVersion throws error when latest SAPUI5 version cannot be found", async (t) => {
const {AbstractResolver} = t.context;
class Sapui5Resolver extends AbstractResolver {
static async fetchAllVersions() {}
}
Expand All @@ -572,6 +629,7 @@ test.serial(

test.serial(
"AbstractResolver: Static resolveVersion throws error when OpenUI5 version range cannot be resolved", async (t) => {
const {AbstractResolver} = t.context;
class Openui5Resolver extends AbstractResolver {
static async fetchAllVersions() {}
}
Expand All @@ -590,6 +648,7 @@ test.serial(

test.serial(
"AbstractResolver: Static resolveVersion throws error when SAPUI5 version range cannot be resolved", async (t) => {
const {AbstractResolver} = t.context;
class Sapui5Resolver extends AbstractResolver {
static async fetchAllVersions() {}
}
Expand All @@ -607,6 +666,8 @@ test.serial(
});

test.serial("AbstractResolver: SEMVER_VERSION_REGEXP should be aligned with JSON schema", async (t) => {
const {AbstractResolver} = t.context;

const projectSchema = JSON.parse(
await readFile(fileURLToPath(
new URL("../../../lib/validation/schema/specVersion/kind/project.json", import.meta.url)
Expand Down