Skip to content

Commit

Permalink
More robust error testing
Browse files Browse the repository at this point in the history
  • Loading branch information
samhh committed Apr 6, 2024
1 parent 51453a8 commit 20862b9
Show file tree
Hide file tree
Showing 8 changed files with 24 additions and 74 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ This project adheres to semantic versioning.
## 0.19.0 (_Unreleased_)

- Add `clone` to `URLPath`.
- Wrap the provided error cause in `unsafeExpect` in `Option` in an `Error` object.
- Fix `URLPath` incorrectly parsing alternative origins.
- Fix typings in presence of `isolatedModules`.
- Bump minimum supported Node LTS to v20.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
"fast-check": "^3.1.2",
"fp-ts": "^2.16.0",
"fp-ts-laws": "^0.3.0",
"jest": "^29.4.1",
"jest": "^29.7.0",
"jsdom": "^22.1.0",
"monocle-ts": "^2.3.0",
"newtype-ts": "^0.3.0",
Expand Down
2 changes: 1 addition & 1 deletion pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions src/Option.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import { decrement, increment } from "./Number"
*
* assert.throws(
* () => unsafeExpect('foo')(O.none),
* Error('Unwrapped `None`', { cause: 'foo' }),
* Error('Unwrapped `None`', { cause: Error('foo') }),
* )
*
* @category 3 Functions
Expand All @@ -37,7 +37,7 @@ import { decrement, increment } from "./Number"
export const unsafeExpect =
(msg: string) =>
<A>(x: Option<A>): A => {
if (O.isNone(x)) throw Error("Unwrapped `None`", { cause: msg })
if (O.isNone(x)) throw Error("Unwrapped `None`", { cause: new Error(msg) })

return x.value
}
Expand Down
22 changes: 7 additions & 15 deletions test/Enum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,9 @@ import * as Str from "fp-ts/string"
import { Enum as EnumBool } from "../src/Boolean"
import { curry2 } from "../src/Function"
import * as L from "../src/Lazy"
import type { Lazy } from "../src/Lazy"
import { EnumInt } from "../src/Number"
import { EQ } from "../src/Ordering"

const msgAndCause = (f: Lazy<unknown>): [string, unknown] => {
try {
f()
throw "didn't throw"
} catch (e) {
if (!(e instanceof Error)) throw "threw unexpected type"
return [e.message, e.cause]
}
}

const BoundedNull: Bounded<null> = {
equals: constant(true),
compare: constant(EQ),
Expand Down Expand Up @@ -375,10 +364,13 @@ describe("Enum", () => {

it("throws with expected message in fromEnum if member not present", () => {
const E = f(Str.Ord)(["foo"])
const [m, c] = msgAndCause(() => E.fromEnum("bar"))

expect(m).toBe("Unwrapped `None`")
expect(c).toMatch(/getUnsafeConstantEnum/)
expect(() => E.fromEnum("bar")).toThrow(
new Error("Unwrapped `None`", {
cause: new Error(
"Failed to lookup fromEnum input via getUnsafeConstantEnum",
),
}),
)
})
})
})
23 changes: 4 additions & 19 deletions test/IOOption.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,6 @@
import { describe, expect, it } from "@jest/globals"
import * as IOO from "fp-ts/IOOption"
import { pass, unsafeExpect, unsafeUnwrap } from "../src/IOOption"
import type { Lazy } from "../src/Lazy"

const msgAndCause = (f: Lazy<unknown>): [string, unknown] => {
try {
f()
throw "didn't throw"
} catch (e) {
if (!(e instanceof Error)) throw "threw unexpected type"
return [e.message, e.cause]
}
}

describe("IOOption", () => {
describe("unsafeUnwrap", () => {
Expand All @@ -22,10 +11,7 @@ describe("IOOption", () => {
})

it("throws None", () => {
const [m, c] = msgAndCause(() => f(IOO.none))

expect(m).toBe("Unwrapped `None`")
expect(c).toBe(undefined)
expect(() => f(IOO.none)).toThrow(new Error("Unwrapped `None`"))
})
})

Expand All @@ -37,10 +23,9 @@ describe("IOOption", () => {
})

it("throws None with provided message", () => {
const [m, c] = msgAndCause(() => f(IOO.none))

expect(m).toBe("Unwrapped `None`")
expect(c).toBe("foo")
expect(() => f(IOO.none)).toThrow(
new Error("Unwrapped `None`", { cause: new Error("foo") }),
)
})
})

Expand Down
22 changes: 4 additions & 18 deletions test/Option.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,6 @@ import {
unsafeUnwrap,
} from "../src/Option"

const msgAndCause = (f: Lazy<unknown>): [string, unknown] => {
try {
f()
throw "didn't throw"
} catch (e) {
if (!(e instanceof Error)) throw "threw unexpected type"
return [e.message, e.cause]
}
}

const arbOption = <A>(x: fc.Arbitrary<A>): fc.Arbitrary<Option<A>> =>
fc.oneof(x.map(O.some), fc.constant(O.none))

Expand All @@ -45,10 +35,7 @@ describe("Option", () => {
})

it("throws None", () => {
const [m, c] = msgAndCause(() => f(O.none))

expect(m).toBe("Unwrapped `None`")
expect(c).toBe(undefined)
expect(() => f(O.none)).toThrow(new Error("Unwrapped `None`"))
})
})

Expand All @@ -60,10 +47,9 @@ describe("Option", () => {
})

it("throws None with provided message", () => {
const [m, c] = msgAndCause(() => f(O.none))

expect(m).toBe("Unwrapped `None`")
expect(c).toBe("foo")
expect(() => f(O.none)).toThrow(
new Error("Unwrapped `None`", { cause: new Error("foo") }),
)
})
})

Expand Down
22 changes: 4 additions & 18 deletions test/TaskOption.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,6 @@ import { describe, expect, it } from "@jest/globals"
import * as TO from "fp-ts/TaskOption"
import { pass, unsafeExpect, unsafeUnwrap } from "../src/TaskOption"

const msgAndCause = async (f: Promise<unknown>): Promise<[string, unknown]> => {
try {
await f
throw "didn't throw"
} catch (e) {
if (!(e instanceof Error)) throw "threw unexpected type"
return [e.message, e.cause]
}
}

describe("TaskOption", () => {
describe("unsafeUnwrap", () => {
const f = unsafeUnwrap
Expand All @@ -21,10 +11,7 @@ describe("TaskOption", () => {
})

it("throws None", async () => {
const [m, c] = await msgAndCause(f(TO.none))

expect(m).toBe("Unwrapped `None`")
expect(c).toBe(undefined)
expect(f(TO.none)).rejects.toThrow(new Error("Unwrapped `None`"))
})
})

Expand All @@ -36,10 +23,9 @@ describe("TaskOption", () => {
})

it("throws None with provided message", async () => {
const [m, c] = await msgAndCause(f(TO.none))

expect(m).toBe("Unwrapped `None`")
expect(c).toBe("foo")
expect(f(TO.none)).rejects.toThrow(
new Error("Unwrapped `None`", { cause: new Error("foo") }),
)
})
})

Expand Down

0 comments on commit 20862b9

Please sign in to comment.