835 lines
27 KiB
TypeScript
835 lines
27 KiB
TypeScript
import * as Cause from "effect/Cause"
|
|
import * as Context from "effect/Context"
|
|
import { pipe } from "effect/Function"
|
|
import * as Option from "effect/Option"
|
|
import * as Result from "effect/Result"
|
|
import assert from "node:assert/strict"
|
|
import { describe, it } from "vitest"
|
|
|
|
describe("Cause", () => {
|
|
describe("TypeId", () => {
|
|
it("is a string constant", () => {
|
|
assert.strictEqual(Cause.TypeId, "~effect/Cause")
|
|
})
|
|
})
|
|
|
|
describe("ReasonTypeId", () => {
|
|
it("is a string constant", () => {
|
|
assert.strictEqual(Cause.ReasonTypeId, "~effect/Cause/Reason")
|
|
})
|
|
})
|
|
|
|
describe("isCause", () => {
|
|
it("returns true for Cause values", () => {
|
|
assert.strictEqual(Cause.isCause(Cause.empty), true)
|
|
assert.strictEqual(Cause.isCause(Cause.fail("error")), true)
|
|
assert.strictEqual(Cause.isCause(Cause.die("defect")), true)
|
|
assert.strictEqual(Cause.isCause(Cause.interrupt(1)), true)
|
|
})
|
|
|
|
it("returns false for non-Cause values", () => {
|
|
assert.strictEqual(Cause.isCause(null), false)
|
|
assert.strictEqual(Cause.isCause(undefined), false)
|
|
assert.strictEqual(Cause.isCause("string"), false)
|
|
assert.strictEqual(Cause.isCause(42), false)
|
|
assert.strictEqual(Cause.isCause({}), false)
|
|
assert.strictEqual(Cause.isCause([]), false)
|
|
})
|
|
})
|
|
|
|
describe("isReason", () => {
|
|
it("returns true for Reason values", () => {
|
|
assert.strictEqual(Cause.isReason(Cause.makeFailReason("error")), true)
|
|
assert.strictEqual(Cause.isReason(Cause.makeDieReason("defect")), true)
|
|
assert.strictEqual(Cause.isReason(Cause.makeInterruptReason(1)), true)
|
|
})
|
|
|
|
it("returns true for reasons extracted from a cause", () => {
|
|
const reason = Cause.fail("error").reasons[0]
|
|
assert.strictEqual(Cause.isReason(reason), true)
|
|
})
|
|
|
|
it("returns false for non-Reason values", () => {
|
|
assert.strictEqual(Cause.isReason(null), false)
|
|
assert.strictEqual(Cause.isReason("string"), false)
|
|
assert.strictEqual(Cause.isReason(Cause.fail("error")), false)
|
|
})
|
|
})
|
|
|
|
describe("isFailReason", () => {
|
|
it("narrows Fail reasons", () => {
|
|
const reason = Cause.fail("error").reasons[0]
|
|
assert.strictEqual(Cause.isFailReason(reason), true)
|
|
})
|
|
|
|
it("rejects Die and Interrupt reasons", () => {
|
|
const die = Cause.die("defect").reasons[0]
|
|
const interrupt = Cause.interrupt(1).reasons[0]
|
|
assert.strictEqual(Cause.isFailReason(die), false)
|
|
assert.strictEqual(Cause.isFailReason(interrupt), false)
|
|
})
|
|
})
|
|
|
|
describe("isDieReason", () => {
|
|
it("narrows Die reasons", () => {
|
|
const reason = Cause.die("defect").reasons[0]
|
|
assert.strictEqual(Cause.isDieReason(reason), true)
|
|
})
|
|
|
|
it("rejects Fail and Interrupt reasons", () => {
|
|
const fail = Cause.fail("error").reasons[0]
|
|
const interrupt = Cause.interrupt(1).reasons[0]
|
|
assert.strictEqual(Cause.isDieReason(fail), false)
|
|
assert.strictEqual(Cause.isDieReason(interrupt), false)
|
|
})
|
|
})
|
|
|
|
describe("isInterruptReason", () => {
|
|
it("narrows Interrupt reasons", () => {
|
|
const reason = Cause.interrupt(1).reasons[0]
|
|
assert.strictEqual(Cause.isInterruptReason(reason), true)
|
|
})
|
|
|
|
it("rejects Fail and Die reasons", () => {
|
|
const fail = Cause.fail("error").reasons[0]
|
|
const die = Cause.die("defect").reasons[0]
|
|
assert.strictEqual(Cause.isInterruptReason(fail), false)
|
|
assert.strictEqual(Cause.isInterruptReason(die), false)
|
|
})
|
|
})
|
|
|
|
describe("empty", () => {
|
|
it("has no reasons", () => {
|
|
assert.strictEqual(Cause.empty.reasons.length, 0)
|
|
})
|
|
|
|
it("is a Cause", () => {
|
|
assert.strictEqual(Cause.isCause(Cause.empty), true)
|
|
})
|
|
})
|
|
|
|
describe("fail", () => {
|
|
it("creates a cause with a single Fail reason", () => {
|
|
const cause = Cause.fail("error")
|
|
assert.strictEqual(cause.reasons.length, 1)
|
|
assert.strictEqual(Cause.isFailReason(cause.reasons[0]), true)
|
|
})
|
|
|
|
it("preserves the error value", () => {
|
|
const cause = Cause.fail("error")
|
|
const reason = cause.reasons[0]
|
|
if (Cause.isFailReason(reason)) {
|
|
assert.strictEqual(reason.error, "error")
|
|
}
|
|
})
|
|
|
|
it("works with various error types", () => {
|
|
const obj = { key: "value" }
|
|
const cause = Cause.fail(obj)
|
|
const reason = cause.reasons[0]
|
|
if (Cause.isFailReason(reason)) {
|
|
assert.strictEqual(reason.error, obj)
|
|
}
|
|
})
|
|
})
|
|
|
|
describe("die", () => {
|
|
it("creates a cause with a single Die reason", () => {
|
|
const cause = Cause.die("defect")
|
|
assert.strictEqual(cause.reasons.length, 1)
|
|
assert.strictEqual(Cause.isDieReason(cause.reasons[0]), true)
|
|
})
|
|
|
|
it("preserves the defect value", () => {
|
|
const cause = Cause.die("defect")
|
|
const reason = cause.reasons[0]
|
|
if (Cause.isDieReason(reason)) {
|
|
assert.strictEqual(reason.defect, "defect")
|
|
}
|
|
})
|
|
|
|
it("works with Error instances", () => {
|
|
const err = new Error("boom")
|
|
const cause = Cause.die(err)
|
|
const reason = cause.reasons[0]
|
|
if (Cause.isDieReason(reason)) {
|
|
assert.strictEqual(reason.defect, err)
|
|
}
|
|
})
|
|
})
|
|
|
|
describe("interrupt", () => {
|
|
it("creates a cause with a single Interrupt reason", () => {
|
|
const cause = Cause.interrupt(123)
|
|
assert.strictEqual(cause.reasons.length, 1)
|
|
assert.strictEqual(Cause.isInterruptReason(cause.reasons[0]), true)
|
|
})
|
|
|
|
it("preserves the fiber ID", () => {
|
|
const cause = Cause.interrupt(42)
|
|
const reason = cause.reasons[0]
|
|
if (Cause.isInterruptReason(reason)) {
|
|
assert.strictEqual(reason.fiberId, 42)
|
|
}
|
|
})
|
|
|
|
it("allows undefined fiber ID", () => {
|
|
const cause = Cause.interrupt()
|
|
const reason = cause.reasons[0]
|
|
if (Cause.isInterruptReason(reason)) {
|
|
assert.strictEqual(reason.fiberId, undefined)
|
|
}
|
|
})
|
|
})
|
|
|
|
describe("fromReasons", () => {
|
|
it("creates a cause from an array of reasons", () => {
|
|
const reasons = [
|
|
Cause.makeFailReason("err1"),
|
|
Cause.makeFailReason("err2")
|
|
]
|
|
const cause = Cause.fromReasons(reasons)
|
|
assert.strictEqual(cause.reasons.length, 2)
|
|
})
|
|
|
|
it("creates empty cause from empty array", () => {
|
|
const cause = Cause.fromReasons([])
|
|
assert.strictEqual(cause.reasons.length, 0)
|
|
})
|
|
|
|
it("supports mixed reason types", () => {
|
|
const reasons = [
|
|
Cause.makeFailReason("error"),
|
|
Cause.makeDieReason("defect"),
|
|
Cause.makeInterruptReason(1)
|
|
]
|
|
const cause = Cause.fromReasons(reasons)
|
|
assert.strictEqual(cause.reasons.length, 3)
|
|
})
|
|
})
|
|
|
|
describe("makeFailReason", () => {
|
|
it("creates a Fail reason with _tag and error", () => {
|
|
const reason = Cause.makeFailReason("error")
|
|
assert.strictEqual(reason._tag, "Fail")
|
|
assert.strictEqual(reason.error, "error")
|
|
})
|
|
})
|
|
|
|
describe("makeDieReason", () => {
|
|
it("creates a Die reason with _tag and defect", () => {
|
|
const reason = Cause.makeDieReason("defect")
|
|
assert.strictEqual(reason._tag, "Die")
|
|
assert.strictEqual(reason.defect, "defect")
|
|
})
|
|
})
|
|
|
|
describe("makeInterruptReason", () => {
|
|
it("creates an Interrupt reason with _tag and fiberId", () => {
|
|
const reason = Cause.makeInterruptReason(42)
|
|
assert.strictEqual(reason._tag, "Interrupt")
|
|
assert.strictEqual(reason.fiberId, 42)
|
|
})
|
|
|
|
it("allows undefined fiberId", () => {
|
|
const reason = Cause.makeInterruptReason()
|
|
assert.strictEqual(reason._tag, "Interrupt")
|
|
assert.strictEqual(reason.fiberId, undefined)
|
|
})
|
|
})
|
|
|
|
describe("hasFails", () => {
|
|
it("returns true when cause has Fail reasons", () => {
|
|
assert.strictEqual(Cause.hasFails(Cause.fail("error")), true)
|
|
})
|
|
|
|
it("returns false when cause has no Fail reasons", () => {
|
|
assert.strictEqual(Cause.hasFails(Cause.die("defect")), false)
|
|
assert.strictEqual(Cause.hasFails(Cause.interrupt(1)), false)
|
|
assert.strictEqual(Cause.hasFails(Cause.empty), false)
|
|
})
|
|
|
|
it("returns true for combined cause with at least one Fail", () => {
|
|
const combined = Cause.combine(Cause.die("defect"), Cause.fail("error"))
|
|
assert.strictEqual(Cause.hasFails(combined), true)
|
|
})
|
|
})
|
|
|
|
describe("hasDies", () => {
|
|
it("returns true when cause has Die reasons", () => {
|
|
assert.strictEqual(Cause.hasDies(Cause.die("defect")), true)
|
|
})
|
|
|
|
it("returns false when cause has no Die reasons", () => {
|
|
assert.strictEqual(Cause.hasDies(Cause.fail("error")), false)
|
|
assert.strictEqual(Cause.hasDies(Cause.interrupt(1)), false)
|
|
assert.strictEqual(Cause.hasDies(Cause.empty), false)
|
|
})
|
|
})
|
|
|
|
describe("hasInterrupts", () => {
|
|
it("returns true when cause has Interrupt reasons", () => {
|
|
assert.strictEqual(Cause.hasInterrupts(Cause.interrupt(1)), true)
|
|
})
|
|
|
|
it("returns false when cause has no Interrupt reasons", () => {
|
|
assert.strictEqual(Cause.hasInterrupts(Cause.fail("error")), false)
|
|
assert.strictEqual(Cause.hasInterrupts(Cause.die("defect")), false)
|
|
assert.strictEqual(Cause.hasInterrupts(Cause.empty), false)
|
|
})
|
|
})
|
|
|
|
describe("hasInterruptsOnly", () => {
|
|
it("returns true when all reasons are Interrupts", () => {
|
|
assert.strictEqual(Cause.hasInterruptsOnly(Cause.interrupt(1)), true)
|
|
const combined = Cause.combine(Cause.interrupt(1), Cause.interrupt(2))
|
|
assert.strictEqual(Cause.hasInterruptsOnly(combined), true)
|
|
})
|
|
|
|
it("returns false for empty cause", () => {
|
|
assert.strictEqual(Cause.hasInterruptsOnly(Cause.empty), false)
|
|
})
|
|
|
|
it("returns false when mixed with other reason types", () => {
|
|
const combined = Cause.combine(Cause.interrupt(1), Cause.fail("error"))
|
|
assert.strictEqual(Cause.hasInterruptsOnly(combined), false)
|
|
})
|
|
})
|
|
|
|
describe("squash", () => {
|
|
it("returns the first Fail error", () => {
|
|
assert.strictEqual(Cause.squash(Cause.fail("error")), "error")
|
|
})
|
|
|
|
it("returns the first Die defect when no Fail", () => {
|
|
assert.strictEqual(Cause.squash(Cause.die("defect")), "defect")
|
|
})
|
|
|
|
it("returns an Error for interrupt-only cause", () => {
|
|
const result = Cause.squash(Cause.interrupt(1))
|
|
assert.ok(result instanceof Error)
|
|
})
|
|
|
|
it("returns an Error for empty cause", () => {
|
|
const result = Cause.squash(Cause.empty)
|
|
assert.ok(result instanceof Error)
|
|
})
|
|
|
|
it("prefers Fail over Die", () => {
|
|
const combined = Cause.combine(Cause.die("defect"), Cause.fail("error"))
|
|
assert.strictEqual(Cause.squash(combined), "error")
|
|
})
|
|
})
|
|
|
|
describe("findFail", () => {
|
|
it("returns success with the first Fail reason", () => {
|
|
const result = Cause.findFail(Cause.fail("error"))
|
|
assert.strictEqual(Result.isSuccess(result), true)
|
|
if (Result.isSuccess(result)) {
|
|
assert.strictEqual(result.success.error, "error")
|
|
assert.strictEqual(result.success._tag, "Fail")
|
|
}
|
|
})
|
|
|
|
it("returns failure when no Fail reason exists", () => {
|
|
const result = Cause.findFail(Cause.die("defect"))
|
|
assert.strictEqual(Result.isFailure(result), true)
|
|
})
|
|
|
|
it("returns failure for empty cause", () => {
|
|
const result = Cause.findFail(Cause.empty)
|
|
assert.strictEqual(Result.isFailure(result), true)
|
|
})
|
|
})
|
|
|
|
describe("findError", () => {
|
|
it("returns success with the error value", () => {
|
|
const result = Cause.findError(Cause.fail("error"))
|
|
assert.strictEqual(Result.isSuccess(result), true)
|
|
if (Result.isSuccess(result)) {
|
|
assert.strictEqual(result.success, "error")
|
|
}
|
|
})
|
|
|
|
it("returns failure when no Fail reason exists", () => {
|
|
const result = Cause.findError(Cause.die("defect"))
|
|
assert.strictEqual(Result.isFailure(result), true)
|
|
})
|
|
})
|
|
|
|
describe("findErrorOption", () => {
|
|
it("returns Some with the error value", () => {
|
|
const result = Cause.findErrorOption(Cause.fail("error"))
|
|
assert.strictEqual(Option.isSome(result), true)
|
|
if (Option.isSome(result)) {
|
|
assert.strictEqual(result.value, "error")
|
|
}
|
|
})
|
|
|
|
it("returns None when no Fail reason exists", () => {
|
|
assert.strictEqual(Option.isNone(Cause.findErrorOption(Cause.die("defect"))), true)
|
|
assert.strictEqual(Option.isNone(Cause.findErrorOption(Cause.empty)), true)
|
|
})
|
|
})
|
|
|
|
describe("findDie", () => {
|
|
it("returns success with the first Die reason", () => {
|
|
const result = Cause.findDie(Cause.die("defect"))
|
|
assert.strictEqual(Result.isSuccess(result), true)
|
|
if (Result.isSuccess(result)) {
|
|
assert.strictEqual(result.success.defect, "defect")
|
|
assert.strictEqual(result.success._tag, "Die")
|
|
}
|
|
})
|
|
|
|
it("returns failure when no Die reason exists", () => {
|
|
const result = Cause.findDie(Cause.fail("error"))
|
|
assert.strictEqual(Result.isFailure(result), true)
|
|
})
|
|
})
|
|
|
|
describe("findDefect", () => {
|
|
it("returns success with the defect value", () => {
|
|
const result = Cause.findDefect(Cause.die("defect"))
|
|
assert.strictEqual(Result.isSuccess(result), true)
|
|
if (Result.isSuccess(result)) {
|
|
assert.strictEqual(result.success, "defect")
|
|
}
|
|
})
|
|
|
|
it("returns failure when no Die reason exists", () => {
|
|
const result = Cause.findDefect(Cause.fail("error"))
|
|
assert.strictEqual(Result.isFailure(result), true)
|
|
})
|
|
})
|
|
|
|
describe("findInterrupt", () => {
|
|
it("returns success with the first Interrupt reason", () => {
|
|
const result = Cause.findInterrupt(Cause.interrupt(42))
|
|
assert.strictEqual(Result.isSuccess(result), true)
|
|
if (Result.isSuccess(result)) {
|
|
assert.strictEqual(result.success.fiberId, 42)
|
|
assert.strictEqual(result.success._tag, "Interrupt")
|
|
}
|
|
})
|
|
|
|
it("returns failure when no Interrupt reason exists", () => {
|
|
const result = Cause.findInterrupt(Cause.fail("error"))
|
|
assert.strictEqual(Result.isFailure(result), true)
|
|
})
|
|
})
|
|
|
|
describe("interruptors", () => {
|
|
it("returns a set of fiber IDs", () => {
|
|
const cause = Cause.combine(Cause.interrupt(1), Cause.interrupt(2))
|
|
const ids = Cause.interruptors(cause)
|
|
assert.strictEqual(ids.has(1), true)
|
|
assert.strictEqual(ids.has(2), true)
|
|
assert.strictEqual(ids.size, 2)
|
|
})
|
|
|
|
it("returns empty set for non-interrupt causes", () => {
|
|
assert.strictEqual(Cause.interruptors(Cause.fail("error")).size, 0)
|
|
assert.strictEqual(Cause.interruptors(Cause.empty).size, 0)
|
|
})
|
|
|
|
it("excludes undefined fiber IDs from set", () => {
|
|
const cause = Cause.interrupt()
|
|
const ids = Cause.interruptors(cause)
|
|
assert.strictEqual(ids.has(undefined as any), false)
|
|
})
|
|
})
|
|
|
|
describe("filterInterruptors", () => {
|
|
it("returns success with fiber ID set when interrupts exist", () => {
|
|
const result = Cause.filterInterruptors(Cause.interrupt(1))
|
|
assert.strictEqual(Result.isSuccess(result), true)
|
|
if (Result.isSuccess(result)) {
|
|
assert.strictEqual(result.success.has(1), true)
|
|
}
|
|
})
|
|
|
|
it("returns failure when no interrupts exist", () => {
|
|
const result = Cause.filterInterruptors(Cause.fail("error"))
|
|
assert.strictEqual(Result.isFailure(result), true)
|
|
})
|
|
})
|
|
|
|
describe("map", () => {
|
|
it("transforms error values in Fail reasons (data-first)", () => {
|
|
const cause = Cause.fail("error")
|
|
const mapped = Cause.map(cause, (e) => e.toUpperCase())
|
|
const reason = mapped.reasons[0]
|
|
if (Cause.isFailReason(reason)) {
|
|
assert.strictEqual(reason.error, "ERROR")
|
|
}
|
|
})
|
|
|
|
it("works in data-last (pipeable) form", () => {
|
|
const mapped = pipe(Cause.fail(1), Cause.map((n) => n + 1))
|
|
const reason = mapped.reasons[0]
|
|
if (Cause.isFailReason(reason)) {
|
|
assert.strictEqual(reason.error, 2)
|
|
}
|
|
})
|
|
|
|
it("does not affect Die reasons", () => {
|
|
const cause = Cause.die("defect")
|
|
const mapped = Cause.map(cause, () => "should not appear")
|
|
assert.strictEqual(mapped.reasons.length, 1)
|
|
assert.strictEqual(Cause.isDieReason(mapped.reasons[0]), true)
|
|
})
|
|
|
|
it("does not affect Interrupt reasons", () => {
|
|
const cause = Cause.interrupt(1)
|
|
const mapped = Cause.map(cause, () => "should not appear")
|
|
assert.strictEqual(mapped.reasons.length, 1)
|
|
assert.strictEqual(Cause.isInterruptReason(mapped.reasons[0]), true)
|
|
})
|
|
|
|
it("maps empty cause to empty cause", () => {
|
|
const mapped = Cause.map(Cause.empty, () => "x")
|
|
assert.strictEqual(mapped.reasons.length, 0)
|
|
})
|
|
})
|
|
|
|
describe("combine", () => {
|
|
it("merges two causes (data-first)", () => {
|
|
const combined = Cause.combine(Cause.fail("a"), Cause.fail("b"))
|
|
assert.strictEqual(combined.reasons.length, 2)
|
|
})
|
|
|
|
it("works in data-last (pipeable) form", () => {
|
|
const combined = pipe(Cause.fail("a"), Cause.combine(Cause.fail("b")))
|
|
assert.strictEqual(combined.reasons.length, 2)
|
|
})
|
|
|
|
it("combining with empty returns the other cause", () => {
|
|
const cause = Cause.fail("error")
|
|
const combined1 = Cause.combine(cause, Cause.empty)
|
|
const combined2 = Cause.combine(Cause.empty, cause)
|
|
assert.strictEqual(combined1.reasons.length, 1)
|
|
assert.strictEqual(combined2.reasons.length, 1)
|
|
})
|
|
|
|
it("combines mixed reason types", () => {
|
|
const combined = Cause.combine(
|
|
Cause.fail("error"),
|
|
Cause.combine(Cause.die("defect"), Cause.interrupt(1))
|
|
)
|
|
assert.strictEqual(combined.reasons.length, 3)
|
|
})
|
|
})
|
|
|
|
describe("prettyErrors", () => {
|
|
it("converts Fail with Error to array of Errors", () => {
|
|
const cause = Cause.fail(new Error("boom"))
|
|
const errors = Cause.prettyErrors(cause)
|
|
assert.strictEqual(errors.length, 1)
|
|
assert.ok(errors[0] instanceof Error)
|
|
assert.ok(errors[0].message.includes("boom"))
|
|
})
|
|
|
|
it("converts Fail with string to Error", () => {
|
|
const cause = Cause.fail("string error")
|
|
const errors = Cause.prettyErrors(cause)
|
|
assert.strictEqual(errors.length, 1)
|
|
assert.ok(errors[0] instanceof Error)
|
|
})
|
|
|
|
it("converts Die to Error", () => {
|
|
const cause = Cause.die("defect")
|
|
const errors = Cause.prettyErrors(cause)
|
|
assert.strictEqual(errors.length, 1)
|
|
assert.ok(errors[0] instanceof Error)
|
|
})
|
|
|
|
it("returns InterruptError for interrupt-only cause", () => {
|
|
const cause = Cause.interrupt(1)
|
|
const errors = Cause.prettyErrors(cause)
|
|
assert.strictEqual(errors.length, 1)
|
|
assert.ok(errors[0] instanceof Error)
|
|
})
|
|
|
|
it("handles empty cause", () => {
|
|
const errors = Cause.prettyErrors(Cause.empty)
|
|
assert.ok(Array.isArray(errors))
|
|
})
|
|
})
|
|
|
|
describe("pretty", () => {
|
|
it("renders a Fail cause as a string", () => {
|
|
const cause = Cause.fail("something went wrong")
|
|
const rendered = Cause.pretty(cause)
|
|
assert.strictEqual(typeof rendered, "string")
|
|
assert.ok(rendered.includes("something went wrong"))
|
|
})
|
|
|
|
it("renders a Die cause as a string", () => {
|
|
const cause = Cause.die(new Error("unexpected"))
|
|
const rendered = Cause.pretty(cause)
|
|
assert.strictEqual(typeof rendered, "string")
|
|
assert.ok(rendered.includes("unexpected"))
|
|
})
|
|
|
|
it("returns a string for empty cause", () => {
|
|
const rendered = Cause.pretty(Cause.empty)
|
|
assert.strictEqual(typeof rendered, "string")
|
|
})
|
|
})
|
|
|
|
describe("annotate", () => {
|
|
it("attaches annotations to a cause (data-first)", () => {
|
|
const cause = Cause.fail("error")
|
|
const annotated = Cause.annotate(cause, Context.empty())
|
|
assert.strictEqual(Cause.isCause(annotated), true)
|
|
assert.strictEqual(annotated.reasons.length, 1)
|
|
})
|
|
|
|
it("works in data-last (pipeable) form", () => {
|
|
const annotated = pipe(Cause.fail("error"), Cause.annotate(Context.empty()))
|
|
assert.strictEqual(Cause.isCause(annotated), true)
|
|
})
|
|
|
|
it("does not mutate the original cause", () => {
|
|
const original = Cause.fail("error")
|
|
Cause.annotate(original, Context.empty())
|
|
assert.strictEqual(original.reasons.length, 1)
|
|
})
|
|
})
|
|
|
|
describe("reasonAnnotations", () => {
|
|
it("returns annotations from a reason", () => {
|
|
const reason = Cause.makeFailReason("error")
|
|
const anns = Cause.reasonAnnotations(reason)
|
|
assert.ok(anns !== undefined)
|
|
})
|
|
})
|
|
|
|
describe("annotations", () => {
|
|
it("returns merged annotations from a cause", () => {
|
|
const cause = Cause.fail("error")
|
|
const anns = Cause.annotations(cause)
|
|
assert.ok(anns !== undefined)
|
|
})
|
|
})
|
|
|
|
describe("StackTrace", () => {
|
|
it("is a Context.Service", () => {
|
|
assert.ok(Cause.StackTrace !== undefined)
|
|
})
|
|
})
|
|
|
|
describe("InterruptorStackTrace", () => {
|
|
it("is a Context.Service", () => {
|
|
assert.ok(Cause.InterruptorStackTrace !== undefined)
|
|
})
|
|
})
|
|
|
|
describe("NoSuchElementError", () => {
|
|
it("creates an error with _tag and message", () => {
|
|
const error = new Cause.NoSuchElementError("not found")
|
|
assert.strictEqual(error._tag, "NoSuchElementError")
|
|
assert.strictEqual(error.message, "not found")
|
|
})
|
|
|
|
it("creates an error without message", () => {
|
|
const error = new Cause.NoSuchElementError()
|
|
assert.strictEqual(error._tag, "NoSuchElementError")
|
|
})
|
|
|
|
it("is an instance of Error", () => {
|
|
const error = new Cause.NoSuchElementError()
|
|
assert.ok(error instanceof Error)
|
|
})
|
|
})
|
|
|
|
describe("isNoSuchElementError", () => {
|
|
it("returns true for NoSuchElementError instances", () => {
|
|
assert.strictEqual(Cause.isNoSuchElementError(new Cause.NoSuchElementError()), true)
|
|
})
|
|
|
|
it("returns false for other values", () => {
|
|
assert.strictEqual(Cause.isNoSuchElementError("nope"), false)
|
|
assert.strictEqual(Cause.isNoSuchElementError(new Error()), false)
|
|
assert.strictEqual(Cause.isNoSuchElementError(null), false)
|
|
})
|
|
})
|
|
|
|
describe("NoSuchElementErrorTypeId", () => {
|
|
it("is a string constant", () => {
|
|
assert.strictEqual(Cause.NoSuchElementErrorTypeId, "~effect/Cause/NoSuchElementError")
|
|
})
|
|
})
|
|
|
|
describe("Done", () => {
|
|
it("creates a Done signal without value", () => {
|
|
const d = Cause.Done()
|
|
assert.strictEqual(d._tag, "Done")
|
|
assert.strictEqual(d.value, undefined)
|
|
})
|
|
|
|
it("creates a Done signal with a value", () => {
|
|
const d = Cause.Done(42)
|
|
assert.strictEqual(d._tag, "Done")
|
|
assert.strictEqual(d.value, 42)
|
|
})
|
|
})
|
|
|
|
describe("isDone", () => {
|
|
it("returns true for Done values", () => {
|
|
assert.strictEqual(Cause.isDone(Cause.Done()), true)
|
|
assert.strictEqual(Cause.isDone(Cause.Done(42)), true)
|
|
})
|
|
|
|
it("returns false for other values", () => {
|
|
assert.strictEqual(Cause.isDone("not done"), false)
|
|
assert.strictEqual(Cause.isDone(null), false)
|
|
assert.strictEqual(Cause.isDone(new Cause.NoSuchElementError()), false)
|
|
})
|
|
})
|
|
|
|
describe("DoneTypeId", () => {
|
|
it("is a string constant", () => {
|
|
assert.strictEqual(Cause.DoneTypeId, "~effect/Cause/Done")
|
|
})
|
|
})
|
|
|
|
describe("TimeoutError", () => {
|
|
it("creates an error with _tag and message", () => {
|
|
const error = new Cause.TimeoutError("timed out")
|
|
assert.strictEqual(error._tag, "TimeoutError")
|
|
assert.strictEqual(error.message, "timed out")
|
|
})
|
|
|
|
it("creates an error without message", () => {
|
|
const error = new Cause.TimeoutError()
|
|
assert.strictEqual(error._tag, "TimeoutError")
|
|
})
|
|
|
|
it("is an instance of Error", () => {
|
|
assert.ok(new Cause.TimeoutError() instanceof Error)
|
|
})
|
|
})
|
|
|
|
describe("isTimeoutError", () => {
|
|
it("returns true for TimeoutError instances", () => {
|
|
assert.strictEqual(Cause.isTimeoutError(new Cause.TimeoutError()), true)
|
|
})
|
|
|
|
it("returns false for other values", () => {
|
|
assert.strictEqual(Cause.isTimeoutError("nope"), false)
|
|
assert.strictEqual(Cause.isTimeoutError(new Error()), false)
|
|
})
|
|
})
|
|
|
|
describe("TimeoutErrorTypeId", () => {
|
|
it("is a string constant", () => {
|
|
assert.strictEqual(Cause.TimeoutErrorTypeId, "~effect/Cause/TimeoutError")
|
|
})
|
|
})
|
|
|
|
describe("IllegalArgumentError", () => {
|
|
it("creates an error with _tag and message", () => {
|
|
const error = new Cause.IllegalArgumentError("bad arg")
|
|
assert.strictEqual(error._tag, "IllegalArgumentError")
|
|
assert.strictEqual(error.message, "bad arg")
|
|
})
|
|
|
|
it("creates an error without message", () => {
|
|
const error = new Cause.IllegalArgumentError()
|
|
assert.strictEqual(error._tag, "IllegalArgumentError")
|
|
})
|
|
|
|
it("is an instance of Error", () => {
|
|
assert.ok(new Cause.IllegalArgumentError() instanceof Error)
|
|
})
|
|
})
|
|
|
|
describe("isIllegalArgumentError", () => {
|
|
it("returns true for IllegalArgumentError instances", () => {
|
|
assert.strictEqual(Cause.isIllegalArgumentError(new Cause.IllegalArgumentError()), true)
|
|
})
|
|
|
|
it("returns false for other values", () => {
|
|
assert.strictEqual(Cause.isIllegalArgumentError("nope"), false)
|
|
assert.strictEqual(Cause.isIllegalArgumentError(new Error()), false)
|
|
})
|
|
})
|
|
|
|
describe("IllegalArgumentErrorTypeId", () => {
|
|
it("is a string constant", () => {
|
|
assert.strictEqual(Cause.IllegalArgumentErrorTypeId, "~effect/Cause/IllegalArgumentError")
|
|
})
|
|
})
|
|
|
|
describe("ExceededCapacityError", () => {
|
|
it("creates an error with _tag and message", () => {
|
|
const error = new Cause.ExceededCapacityError("queue full")
|
|
assert.strictEqual(error._tag, "ExceededCapacityError")
|
|
assert.strictEqual(error.message, "queue full")
|
|
})
|
|
|
|
it("creates an error without message", () => {
|
|
const error = new Cause.ExceededCapacityError()
|
|
assert.strictEqual(error._tag, "ExceededCapacityError")
|
|
})
|
|
|
|
it("is an instance of Error", () => {
|
|
assert.ok(new Cause.ExceededCapacityError() instanceof Error)
|
|
})
|
|
})
|
|
|
|
describe("isExceededCapacityError", () => {
|
|
it("returns true for ExceededCapacityError instances", () => {
|
|
assert.strictEqual(Cause.isExceededCapacityError(new Cause.ExceededCapacityError()), true)
|
|
})
|
|
|
|
it("returns false for other values", () => {
|
|
assert.strictEqual(Cause.isExceededCapacityError("nope"), false)
|
|
assert.strictEqual(Cause.isExceededCapacityError(new Error()), false)
|
|
})
|
|
})
|
|
|
|
describe("ExceededCapacityErrorTypeId", () => {
|
|
it("is a string constant", () => {
|
|
assert.strictEqual(Cause.ExceededCapacityErrorTypeId, "~effect/Cause/ExceededCapacityError")
|
|
})
|
|
})
|
|
|
|
describe("UnknownError", () => {
|
|
it("creates an error with cause and message", () => {
|
|
const error = new Cause.UnknownError("original", "wrapper message")
|
|
assert.strictEqual(error._tag, "UnknownError")
|
|
assert.strictEqual(error.message, "wrapper message")
|
|
})
|
|
|
|
it("stores the original cause", () => {
|
|
const original = { raw: true }
|
|
const error = new Cause.UnknownError(original)
|
|
assert.strictEqual(error._tag, "UnknownError")
|
|
})
|
|
|
|
it("is an instance of Error", () => {
|
|
assert.ok(new Cause.UnknownError("x") instanceof Error)
|
|
})
|
|
})
|
|
|
|
describe("isUnknownError", () => {
|
|
it("returns true for UnknownError instances", () => {
|
|
assert.strictEqual(Cause.isUnknownError(new Cause.UnknownError("x")), true)
|
|
})
|
|
|
|
it("returns false for other values", () => {
|
|
assert.strictEqual(Cause.isUnknownError("nope"), false)
|
|
assert.strictEqual(Cause.isUnknownError(new Error()), false)
|
|
})
|
|
})
|
|
|
|
describe("UnknownErrorTypeId", () => {
|
|
it("is a string constant", () => {
|
|
assert.strictEqual(Cause.UnknownErrorTypeId, "~effect/Cause/UnknownError")
|
|
})
|
|
})
|
|
})
|