mirror of
https://github.com/tdurieux/anonymous_github.git
synced 2026-04-22 21:36:09 +02:00
170 lines
5.6 KiB
JavaScript
170 lines
5.6 KiB
JavaScript
const { expect } = require("chai");
|
|
|
|
/**
|
|
* Tests for AnonymousError.toString() formatting logic.
|
|
*
|
|
* The toString() method has branching logic based on the type of the
|
|
* `value` property (Repository, AnonymizedFile, GitHubRepository, User,
|
|
* GitHubBase, or plain object). We simulate these types to test each
|
|
* branch without importing the actual classes.
|
|
*/
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Simulated AnonymousError
|
|
// ---------------------------------------------------------------------------
|
|
|
|
class AnonymousError extends Error {
|
|
constructor(message, opt) {
|
|
super(message);
|
|
this.value = opt?.object;
|
|
this.httpStatus = opt?.httpStatus;
|
|
this.cause = opt?.cause;
|
|
}
|
|
|
|
toString() {
|
|
let out = "";
|
|
let detail = this.value ? JSON.stringify(this.value) : null;
|
|
|
|
// Simulate the instanceof checks with duck typing
|
|
if (this.value && this.value.__type === "Repository") {
|
|
detail = this.value.repoId;
|
|
} else if (this.value && this.value.__type === "AnonymizedFile") {
|
|
detail = `/r/${this.value.repository.repoId}/${this.value.anonymizedPath}`;
|
|
} else if (this.value && this.value.__type === "GitHubRepository") {
|
|
detail = `${this.value.fullName}`;
|
|
} else if (this.value && this.value.__type === "User") {
|
|
detail = `${this.value.username}`;
|
|
} else if (this.value && this.value.__type === "GitHubBase") {
|
|
detail = `GHDownload ${this.value.data.repoId}`;
|
|
}
|
|
|
|
out += this.message;
|
|
if (detail) {
|
|
out += `: ${detail}`;
|
|
}
|
|
if (this.cause) {
|
|
out += `\n\tCause by ${this.cause}\n${this.cause.stack}`;
|
|
}
|
|
return out;
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Tests
|
|
// ---------------------------------------------------------------------------
|
|
|
|
describe("AnonymousError.toString()", function () {
|
|
describe("message formatting", function () {
|
|
it("outputs the error message", function () {
|
|
const err = new AnonymousError("repo_not_found");
|
|
expect(err.toString()).to.equal("repo_not_found");
|
|
});
|
|
|
|
it("outputs message with httpStatus on the object", function () {
|
|
const err = new AnonymousError("repo_not_found", { httpStatus: 404 });
|
|
expect(err.httpStatus).to.equal(404);
|
|
expect(err.toString()).to.equal("repo_not_found");
|
|
});
|
|
});
|
|
|
|
describe("detail from value types", function () {
|
|
it("formats Repository value as repoId", function () {
|
|
const err = new AnonymousError("error", {
|
|
object: { __type: "Repository", repoId: "my-anon-repo" },
|
|
});
|
|
expect(err.toString()).to.equal("error: my-anon-repo");
|
|
});
|
|
|
|
it("formats AnonymizedFile value as /r/{repoId}/{path}", function () {
|
|
const err = new AnonymousError("file_not_found", {
|
|
object: {
|
|
__type: "AnonymizedFile",
|
|
repository: { repoId: "abc123" },
|
|
anonymizedPath: "src/XXXX-1/file.ts",
|
|
},
|
|
});
|
|
expect(err.toString()).to.equal(
|
|
"file_not_found: /r/abc123/src/XXXX-1/file.ts"
|
|
);
|
|
});
|
|
|
|
it("formats GitHubRepository value as fullName", function () {
|
|
const err = new AnonymousError("error", {
|
|
object: { __type: "GitHubRepository", fullName: "owner/repo" },
|
|
});
|
|
expect(err.toString()).to.equal("error: owner/repo");
|
|
});
|
|
|
|
it("formats User value as username", function () {
|
|
const err = new AnonymousError("error", {
|
|
object: { __type: "User", username: "jdoe" },
|
|
});
|
|
expect(err.toString()).to.equal("error: jdoe");
|
|
});
|
|
|
|
it("formats GitHubBase value as GHDownload {repoId}", function () {
|
|
const err = new AnonymousError("error", {
|
|
object: {
|
|
__type: "GitHubBase",
|
|
data: { repoId: "download-123" },
|
|
},
|
|
});
|
|
expect(err.toString()).to.equal("error: GHDownload download-123");
|
|
});
|
|
|
|
it("formats plain object as JSON.stringify", function () {
|
|
const err = new AnonymousError("error", {
|
|
object: { key: "value" },
|
|
});
|
|
expect(err.toString()).to.equal('error: {"key":"value"}');
|
|
});
|
|
|
|
it("formats string value as JSON string", function () {
|
|
const err = new AnonymousError("error", {
|
|
object: "some-id",
|
|
});
|
|
expect(err.toString()).to.equal('error: "some-id"');
|
|
});
|
|
|
|
it("formats number value", function () {
|
|
const err = new AnonymousError("error", {
|
|
object: 42,
|
|
});
|
|
expect(err.toString()).to.equal("error: 42");
|
|
});
|
|
});
|
|
|
|
describe("null/undefined value", function () {
|
|
it("outputs only message when value is null", function () {
|
|
const err = new AnonymousError("error", { object: null });
|
|
expect(err.toString()).to.equal("error");
|
|
});
|
|
|
|
it("outputs only message when value is undefined", function () {
|
|
const err = new AnonymousError("error", { object: undefined });
|
|
expect(err.toString()).to.equal("error");
|
|
});
|
|
|
|
it("outputs only message when no opt is passed", function () {
|
|
const err = new AnonymousError("error");
|
|
expect(err.toString()).to.equal("error");
|
|
});
|
|
});
|
|
|
|
describe("cause formatting", function () {
|
|
it("includes cause message and stack when cause is present", function () {
|
|
const cause = new Error("original error");
|
|
const err = new AnonymousError("wrapper", { cause });
|
|
const str = err.toString();
|
|
expect(str).to.include("wrapper");
|
|
expect(str).to.include("Cause by");
|
|
expect(str).to.include("original error");
|
|
});
|
|
|
|
it("omits cause section when no cause", function () {
|
|
const err = new AnonymousError("error", { object: "test" });
|
|
expect(err.toString()).to.not.include("Cause by");
|
|
});
|
|
});
|
|
});
|