From 42def0c5fefbc8a917fd1b31708493d67d8c78b2 Mon Sep 17 00:00:00 2001 From: bkiac Date: Thu, 16 Nov 2023 18:09:52 +0100 Subject: [PATCH] Add option class, fix tests --- src/none.ts | 88 ------------------------- src/option.ts | 139 +++++++++++++++++++++++++++++++-------- src/result.ts | 4 +- src/some.ts | 95 --------------------------- test/option.test.ts | 142 +++++++++++++++++++++++----------------- test/result.test.ts | 156 +++++++++++++++++++++----------------------- 6 files changed, 268 insertions(+), 356 deletions(-) delete mode 100644 src/none.ts delete mode 100644 src/some.ts diff --git a/src/none.ts b/src/none.ts deleted file mode 100644 index d736a22..0000000 --- a/src/none.ts +++ /dev/null @@ -1,88 +0,0 @@ -import {Panic, UnwrapPanic} from "./panic" -import {inspectSymbol} from "./util" -import type {OptionMethods, Option} from "../option/option" - -export class NoneImpl implements OptionMethods { - readonly some = false - readonly none = true - readonly value = null - - and(_other: Option): None { - return None - } - - andThen(_f: (value: never) => Option): None { - return None - } - - expect(panic: string): never { - throw new Panic(panic) - } - - filter(_f: (value: never) => boolean): None { - return None - } - - inspect(_f: (value: never) => void): None { - return None - } - - map(_f: (value: never) => U): None { - return None - } - - mapOr(defaultValue: A, _f: (value: never) => B): A { - return defaultValue - } - - mapOrElse(defaultValue: () => A, _f: (value: never) => B): A { - return defaultValue() - } - - or(other: Option): Option { - return other - } - - orElse(f: () => Option): Option { - return f() - } - - unwrap(): never { - throw new UnwrapPanic(`called "unwrap()" on None`) - } - - unwrapOr(defaultValue: U): U { - return defaultValue - } - - unwrapOrElse(defaultValue: () => U): U { - return defaultValue() - } - - xor(other: Option): Option { - return other - } - - match(_some: (value: never) => A, none: () => B): B { - return none() - } - - toString(): "None" { - return "None" as const - } - - [inspectSymbol](): "None" { - return this.toString() - } - - toObject(): {some: false; value: null} { - return {some: false, value: null} as const - } - - toJSON(): {meta: "None"; value: null} { - return {meta: "None", value: null} as const - } -} - -export interface None extends NoneImpl {} -export const None: None = new NoneImpl() diff --git a/src/option.ts b/src/option.ts index d6ed1f4..c56eba7 100644 --- a/src/option.ts +++ b/src/option.ts @@ -1,29 +1,114 @@ -import type {inspectSymbol} from "./util" -import type {None} from "./none" -import type {Some} from "./some" - -export interface OptionMethods { - and(other: Option): Option - andThen(f: (value: T) => Option): Option - expect(panic: string): T - filter(f: (value: T) => boolean): Option - inspect(f: (value: T) => void): Option - map(f: (value: T) => U): Option - mapOr(defaultValue: A, f: (value: T) => B): A | B - mapOrElse(defaultValue: () => A, f: (value: T) => B): A | B - or(other: Option): Option - orElse(f: () => Option): Option - unwrap(): T - unwrapOr(defaultValue: U): T | U - unwrapOrElse(defaultValue: () => U): T | U - xor(other: Option): Option - - match(some: (value: T) => A, none: () => B): A | B - - toString(): `Some(${string})` | "None" - [inspectSymbol](): ReturnType["toString"]> - toObject(): {some: true; value: T} | {some: false; value: null} - toJSON(): {meta: "Some"; value: T} | {meta: "None"; value: null} +import {Panic} from "./panic" +import {inspectSymbol} from "./util" + +export class OptionImpl { + readonly some: boolean + readonly none: boolean + readonly value: T | never + + constructor(value: T) { + this.some = true + this.none = false + this.value = value + } + + and(other: Option): Option { + return this.some ? other : None + } + + andThen(f: (value: T) => Option): Option { + return this.some ? f(this.value as T) : None + } + + expect(panic: string): T { + if (this.some) { + return this.value as T + } + throw new Panic(panic) + } + + filter(f: (value: T) => boolean): Option { + return (this.some && f(this.value as T) ? this : None) as Option + } + + inspect(f: (value: T) => void): this { + if (this.some) { + f(this.value as T) + } + return this + } + + map(f: (value: T) => U): Option { + return (this.some ? new OptionImpl(f(this.value as T)) : None) as Option + } + + mapOr(defaultValue: A, f: (value: T) => B): A | B { + return this.some ? f(this.value as T) : defaultValue + } + + mapOrElse(defaultValue: () => A, f: (value: T) => B): A | B { + return this.some ? f(this.value as T) : defaultValue() + } + + or(other: Option): Option { + return (this.some ? this : other) as Option + } + + orElse(f: () => Option): Option { + return (this.some ? this : f()) as Option + } + + unwrap(): T { + return this.value as T + } + + unwrapOr(defaultValue: U): T | U { + return this.some ? (this.value as T) : defaultValue + } + + unwrapOrElse(defaultValue: () => U): T | U { + return this.some ? (this.value as T) : defaultValue() + } + + xor(other: Option): Option { + return (other.some ? None : this) as Option + } + + match(some: (value: T) => A, none: () => B): A | B { + return this.some ? some(this.value as T) : none() + } + + toString(): `Some(${string})` | "None" { + return this.some ? `Some(${this.value})` : "None" + } + + [inspectSymbol](): ReturnType["toString"]> { + return this.toString() + } + + toObject(): {some: true; value: T} | {some: false; value: null} { + return this.some ? {some: true, value: this.value as T} : {some: false, value: null} + } + + toJSON(): {meta: "Some"; value: T} | {meta: "None"; value: null} { + return this.some ? {meta: "Some", value: this.value as T} : {meta: "None", value: null} + } +} + +export interface Some extends OptionImpl { + readonly some: true + readonly none: false + readonly value: T +} +export function Some(value: T): Some { + return new OptionImpl(value) as Some +} + +export interface None extends OptionImpl { + readonly some: false + readonly none: true + readonly value: never } +export const None = new OptionImpl(null) as None -export type Option = (Some | None) & OptionMethods +export type Option = (Some | None) & OptionImpl diff --git a/src/result.ts b/src/result.ts index c7ee5ad..845965b 100644 --- a/src/result.ts +++ b/src/result.ts @@ -136,8 +136,6 @@ export class ResultImpl { } } -export type Result = Ok | Err - export interface Ok extends ResultImpl { readonly ok: true readonly err: false @@ -161,3 +159,5 @@ export function Err(value: E): Err export function Err(value?: E): Err { return new ResultImpl(false, (value ?? null) as E) as Err } + +export type Result = (Ok | Err) & ResultImpl diff --git a/src/some.ts b/src/some.ts deleted file mode 100644 index ffddddd..0000000 --- a/src/some.ts +++ /dev/null @@ -1,95 +0,0 @@ -import {inspectSymbol} from "./util" -import type {OptionMethods, Option} from "./option" -import {None} from "./none" - -export class SomeImpl implements OptionMethods { - readonly some = true - readonly none = false - readonly value: T - - constructor(value: T) { - this.value = value - } - - and(other: Option): Option { - return other - } - - andThen(f: (value: T) => Option): Option { - return f(this.value) - } - - expect(_panic: string): T { - return this.value - } - - filter(f: (value: T) => boolean): Option { - return f(this.value) ? this : None - } - - inspect(f: (value: T) => void): this { - f(this.value) - return this - } - - map(f: (value: T) => U): Some { - return new SomeImpl(f(this.value)) - } - - mapOr(_defaultValue: A, f: (value: T) => B): B { - return f(this.value) - } - - mapOrElse(_defaultValue: () => A, f: (value: T) => B): B { - return f(this.value) - } - - or(_other: Option): this { - return this - } - - orElse(_f: () => Option): this { - return this - } - - unwrap(): T { - return this.value - } - - unwrapOr(_defaultValue: U): T { - return this.value - } - - unwrapOrElse(_defaultValue: () => U): T { - return this.value - } - - xor(other: Option): Option { - return other.some ? None : this - } - - match(some: (value: T) => A, _none: () => B): A { - return some(this.value) - } - - toString(): `Some(${string})` { - return `Some(${this.value})` as const - } - - [inspectSymbol](): ReturnType["toString"]> { - return this.toString() - } - - toObject(): {some: true; value: T} { - return {some: true, value: this.value} as const - } - - toJSON(): {meta: "Some"; value: T} { - return {meta: "Some", value: this.value} as const - } -} - -export interface Some extends SomeImpl {} -export function Some(value: T): Some { - return new SomeImpl(value) -} diff --git a/test/option.test.ts b/test/option.test.ts index 2c22420..d60bd6b 100644 --- a/test/option.test.ts +++ b/test/option.test.ts @@ -1,65 +1,85 @@ import {describe, expect, it, vi} from "vitest" -import {Panic, UnwrapPanic, None, Some} from "../src/internal" +import {Panic, UnwrapPanic, None, Some, type Option} from "../src/internal" -it("returns a Some option", () => { - const option = Some(42) - expect(option.some).toEqual(true) - expect(option.none).toEqual(false) - expect(option.value).toEqual(42) -}) +function TestSome(value: T): Option { + return Some(value) +} + +function TestNone(): Option { + return None +} + +describe.concurrent("basic", () => { + it("returns a Some option", () => { + const option = Some(42) + expect(option.some).toEqual(true) + expect(option.none).toEqual(false) + expect(option.value).toEqual(42) + }) + + it("returns a None option", () => { + const option = None + expect(option.some).toEqual(false) + expect(option.none).toEqual(true) + expect(option.value).toEqual(null) + }) -it("returns a None option", () => { - const option = None - expect(option.some).toEqual(false) - expect(option.none).toEqual(true) + it("works with discriminated union", () => { + const option = Some(42) + if (option.some) { + expect(option.value).toEqual(42) + } else { + expect(option.value).toEqual(null) + } + }) }) describe.concurrent("and", () => { it("returns the other option when Some and None", () => { - const a = Some(2) - const b = None + const a = TestSome(2) + const b = TestNone() expect(a.and(b)).toEqual(b) }) it("returns the other option when Some and Some", () => { - const a = Some(2) - const b = Some("str") + const a = TestSome(2) + const b = TestSome("str") expect(a.and(b)).toEqual(b) }) it("returns None when None and Some", () => { - const a = None - const b = Some("foo") + const a = TestNone() + const b = TestSome("foo") expect(a.and(b)).toEqual(a) }) it("returns None when None and None", () => { - const a = None - const b = None + const a = TestNone() + const b = TestNone() expect(a.and(b)).toEqual(a) }) }) describe.concurrent("andThen", () => { it("returns the mapped value for a Some option", () => { - const a = Some(0) - expect(a.andThen((value) => Some(value + 1))).toEqual(Some(1)) + const a = TestSome(0) + expect(a.andThen((value) => TestSome(value + 1))).toEqual(Some(1)) }) it("returns None for a None option", () => { - const a = None + const a = TestNone() expect(a.andThen((value) => Some(value + 1))).toEqual(a) }) }) describe.concurrent("expect", () => { it("returns the value when called on a Some option", () => { - const option = Some(42) + const option = TestSome(42) expect(option.expect("error")).toEqual(42) }) it("throws when called on a None option", () => { - const option = None + const option = TestNone() expect(() => option.expect("error")).toThrow(Panic) expect(() => option.expect("error")).toThrow("error") }) @@ -72,26 +92,26 @@ describe.concurrent("filter", () => { }) it("returns None when the predicate returns false", () => { - const option = Some(42) + const option = TestSome(42) expect(option.filter((value) => value !== 42)).toEqual(None) }) it("returns None when called on a None option", () => { - const option = None - expect(option.filter((value) => value === 42)).toEqual(option) + const option = TestNone() + expect(option.filter((value) => value === "hello")).toEqual(option) }) }) describe.concurrent("inspect", () => { it("calls the function with the value when called on a Some option", () => { - const option = Some(42) + const option = TestSome(42) const callback = vi.fn() expect(option.inspect(callback)).toEqual(option) expect(callback).toHaveBeenCalledWith(42) }) it("does not call the function when called on a None option", () => { - const option = None + const option = TestNone() const callback = vi.fn() expect(option.inspect(callback)).toEqual(option) expect(callback).not.toHaveBeenCalled() @@ -100,31 +120,31 @@ describe.concurrent("inspect", () => { describe.concurrent("map", () => { it("returns the mapped value for a Some option", () => { - const option = Some(42) + const option = TestSome(42) expect(option.map((value) => value + 1)).toEqual(Some(43)) }) it("returns None for a None option", () => { - const option = None + const option = TestNone() expect(option.map((value) => value + 1)).toEqual(option) }) }) describe.concurrent("mapOr", () => { it("returns the mapped value for a Some option", () => { - const option = Some(42) + const option = TestSome(42) expect(option.mapOr("default", (value) => value + 1)).toEqual(43) }) it("returns the default value for a None option", () => { - const option = None + const option = TestNone() expect(option.mapOr("default", (value) => value + 1)).toEqual("default") }) }) describe.concurrent("mapOrElse", () => { it("returns the mapped value for a Some option", () => { - const option = Some(42) + const option = TestSome(42) expect( option.mapOrElse( () => "default", @@ -134,7 +154,7 @@ describe.concurrent("mapOrElse", () => { }) it("returns the default value for a None option", () => { - const option = None + const option = TestNone() expect( option.mapOrElse( () => "default", @@ -146,107 +166,107 @@ describe.concurrent("mapOrElse", () => { describe.concurrent("or", () => { it("returns the original option when Some and None", () => { - const a = Some(2) - const b = None + const a = TestSome(2) + const b = TestNone() expect(a.or(b)).toEqual(a) }) it("returns the original option when Some and Some", () => { - const a = Some(2) - const b = Some("str") + const a = TestSome(2) + const b = TestSome("str") expect(a.or(b)).toEqual(a) }) it("returns the other option when None and Some", () => { - const a = None - const b = Some("foo") + const a = TestNone() + const b = TestSome("foo") expect(a.or(b)).toEqual(b) }) it("returns None when None and None", () => { - const a = None - const b = None + const a = TestNone() + const b = TestNone() expect(a.or(b)).toEqual(a) }) }) describe.concurrent("orElse", () => { it("returns the original option for a Some option", () => { - const a = Some(0) + const a = TestSome(0) expect(a.orElse(() => Some(1))).toEqual(a) }) it("returns the result of the function for a None option", () => { - const a = None + const a = TestNone() expect(a.orElse(() => Some(1))).toEqual(Some(1)) }) }) describe.concurrent("unwrap", () => { it("returns the value when called on a Some option", () => { - const option = Some(42) + const option = TestSome(42) expect(option.unwrap()).toEqual(42) }) it("throws when called on a None option", () => { - const option = None + const option = TestNone() expect(() => option.unwrap()).toThrow(UnwrapPanic) }) }) describe.concurrent("unwrapOr", () => { it("returns the value when called on a Some option", () => { - const option = Some(42) + const option = TestSome(42) expect(option.unwrapOr("default")).toEqual(42) }) it("returns the default value when called on a None option", () => { - const option = None + const option = TestNone() expect(option.unwrapOr("default")).toEqual("default") }) }) describe.concurrent("unwrapOrElse", () => { it("returns the value when called on a Some option", () => { - const option = Some(42) + const option = TestSome(42) expect(option.unwrapOrElse(() => "default")).toEqual(42) }) it("returns the default value when called on a None option", () => { - const option = None + const option = TestNone() expect(option.unwrapOrElse(() => "default")).toEqual("default") }) }) describe.concurrent("xor", () => { it("returns Some when Some and None", () => { - const a = Some(2) - const b = None + const a = TestSome(2) + const b = TestNone() expect(a.xor(b)).toEqual(a) }) it("returns Some when None and Some", () => { - const a = None - const b = Some("foo") + const a = TestNone() + const b = TestSome("foo") expect(a.xor(b)).toEqual(b) }) it("returns None when None and None", () => { - const a = None - const b = None + const a = TestNone() + const b = TestNone() expect(a.xor(b)).toEqual(a) }) it("returns None when Some and Some", () => { - const a = Some(2) - const b = Some("str") + const a = TestSome(2) + const b = TestSome("str") expect(a.xor(b)).toEqual(None) }) }) describe.concurrent("match", () => { it("returns the result of the some callback when called on a Some option", () => { - const option = Some(42) + const option = TestSome(42) expect( option.match( (value) => value + 1, @@ -256,7 +276,7 @@ describe.concurrent("match", () => { }) it("returns the result of the none callback when called on a None option", () => { - const option = None + const option = TestNone() expect( option.match( (value) => value + 1, diff --git a/test/result.test.ts b/test/result.test.ts index 5f3f09f..7d9bd97 100644 --- a/test/result.test.ts +++ b/test/result.test.ts @@ -1,6 +1,14 @@ -import {describe, it, expect, expectTypeOf} from "vitest" +import {describe, it, expect, expectTypeOf, vi, test} from "vitest" import {Panic, UnwrapPanic, Ok, Err, type Result} from "../src/internal" +function TestOk(value: T): Result { + return Ok(value) +} + +function TestErr(value: E): Result { + return Err(value) +} + describe.concurrent("basic", () => { it("returns an Ok result", () => { const result = Ok(42) @@ -15,7 +23,7 @@ describe.concurrent("basic", () => { }) it("works as discriminated union", () => { - const r = Ok(42) as Result + const r = TestOk(42) expectTypeOf(r.value).toEqualTypeOf() if (r.ok) { expectTypeOf(r.value).toEqualTypeOf() @@ -27,52 +35,51 @@ describe.concurrent("basic", () => { describe.concurrent("and", () => { it("returns the error when Ok and Err", () => { - const a = Ok(2) - const b = Err("late error") + const a = TestOk(2) + const b = TestErr("late error") expect(a.and(b)).toEqual(b) }) it("returns the late value when Ok and Ok", () => { - const a = Ok(2) - const b = Ok("str") + const a = TestOk(0) + const b = TestOk(1) expect(a.and(b)).toEqual(b) }) it("returns the error when Err and Ok", () => { - const a = Err("early error") - const b = Ok("foo") + const a = TestErr("early error") + const b = TestOk(0) expect(a.and(b)).toEqual(a) }) it("returns the early error when Err and Err", () => { - const a = Err("early error") - const b = Err("late error") + const a = TestErr("early error") + const b = TestErr("late error") expect(a.and(b)).toEqual(a) }) }) describe.concurrent("andThen", () => { it("returns the mapped value for an Ok result", () => { - const a = Ok(0) + const a = TestOk(0) expect(a.andThen((value) => Ok(value + 1))).toEqual(Ok(1)) }) it("returns the result for an Err result", () => { - const a = Err("early error") + const a = TestErr("early error") expect(a.andThen((value) => Ok(value + 1))).toEqual(a) }) }) describe.concurrent("expect", () => { it("returns the value when called on an Ok result", () => { - const result = Ok(42) + const result = TestOk(42) const value = result.expect("Panic message") expect(value).toEqual(42) }) it("throws a Panic with the provided message when called on an Err result", () => { - const error = new Error("Original error") - const result = Err(error) + const result = TestErr("error") const panicMsg = "Panic message" expect(() => result.expect(panicMsg)).toThrow(Panic) expect(() => result.expect(panicMsg)).toThrow(panicMsg) @@ -81,13 +88,12 @@ describe.concurrent("expect", () => { describe.concurrent("expectErr", () => { it("returns the value when called on an Err result", () => { - const error = new Error("Original error") - const err = Err(error) - expect(err.expectErr("panic message")).toEqual(error) + const err = TestErr("error") + expect(err.expectErr("panic message")).toEqual("error") }) it("throws a Panic with the provided message when called on an Ok result", () => { - const ok = Ok() + const ok = TestOk(0) const panicMsg = "Panic message" expect(() => ok.expectErr(panicMsg)).toThrow(Panic) expect(() => ok.expectErr(panicMsg)).toThrow(panicMsg) @@ -96,58 +102,49 @@ describe.concurrent("expectErr", () => { describe.concurrent("inspect", () => { it("returns this and calls inspect on Ok result", () => { - let counter = 0 - const result = Ok(42) - const result2 = result.inspect((value) => { - counter += value - }) - expect(counter).toEqual(42) + const f = vi.fn() + const result = TestOk(42) + const result2 = result.inspect(f) + expect(f).toHaveBeenCalled() expect(result2).toEqual(result) }) it("returns this and does not call inspect on Err result", () => { - let counter = 0 - const result = Err("") - const result2 = result.inspect(() => { - counter += 1 - }) - expect(counter).toEqual(0) + const f = vi.fn() + const result = TestErr("") + const result2 = result.inspect(f) + expect(f).not.toHaveBeenCalled() expect(result2).toEqual(result) }) }) describe.concurrent("inspectErr", () => { it("returns this and does not call inspectErr on Ok result", () => { - let counter = 0 - const result = Ok(42) - const result2 = result.inspectErr(() => { - counter += 1 - }) - expect(counter).toEqual(0) + const f = vi.fn() + const result = TestOk(42) + const result2 = result.inspectErr(f) + expect(f).not.toHaveBeenCalled() expect(result2).toEqual(result) }) it("returns this and calls inspectErr on Err result", () => { - let counter = 0 - const result = Err("") - const result2 = result.inspectErr(() => { - counter += 1 - }) - expect(counter).toEqual(1) + const f = vi.fn() + const result = TestErr("") + const result2 = result.inspectErr(f) + expect(f).toHaveBeenCalled() expect(result2).toEqual(result) }) }) describe.concurrent("map", () => { it("returns the mapped value for an Ok result", () => { - const result = Ok(42) + const result = TestOk(42) const result2 = result.map((value) => value * 2) expect(result2).toEqual(Ok(84)) }) it("returns the original Err for an Err result", () => { - const error = new Error("Test error") - const result = Err(error) + const result = TestErr("error") const result2 = result.map((value) => value * 2) expect(result2).toEqual(result) }) @@ -155,29 +152,27 @@ describe.concurrent("map", () => { describe.concurrent("mapErr", () => { it("returns the mapped error for an Err result", () => { - const error = new Error("Test error") - const result = Err(error) - const result2 = result.mapErr(() => new Error("Error")) - expect(result2).toEqual(Err(new Error("Error"))) + const result = TestErr("error") + const result2 = result.mapErr(() => "new error") + expect(result2.unwrapErr()).toEqual("new error") }) it("returns the original Ok for an Err result", () => { - const result = Ok() - const result2 = result.mapErr(() => new Error("Error")) + const result = TestOk(0) + const result2 = result.mapErr(() => "new error") expect(result2).toEqual(result) }) }) describe.concurrent("mapOr", () => { it("returns the mapped value for an Ok result", () => { - const result = Ok(42) + const result = TestOk(42) const value = result.mapOr(0, (value) => value * 2) expect(value).toEqual(84) }) it("returns the default value for an Err result", () => { - const error = new Error("Test error") - const result = Err(error) + const result = TestErr("error") const value = result.mapOr(0, (value) => value * 2) expect(value).toEqual(0) }) @@ -185,7 +180,7 @@ describe.concurrent("mapOr", () => { describe.concurrent("mapOrElse", () => { it("returns the mapped value for an Ok result", () => { - const result = Ok(42) + const result = TestOk(42) const value = result.mapOrElse( () => 0, (value) => value * 2, @@ -194,7 +189,7 @@ describe.concurrent("mapOrElse", () => { }) it("returns the default value from a function for an Err result", () => { - const result = Err(new Error("Test error")) + const result = TestErr("error") const value = result.mapOrElse( () => 0, (value) => value * 2, @@ -205,90 +200,86 @@ describe.concurrent("mapOrElse", () => { describe.concurrent("or", () => { it("returns the value when Ok or Err", () => { - const a = Ok(2) - const b = Err("late error") + const a = TestOk(2) + const b = TestErr("late error") expect(a.or(b)).toEqual(a) }) it("returns the early value when Ok or Ok", () => { - const a = Ok(2) - const b = Ok("str") + const a = TestOk(0) + const b = TestOk(1) expect(a.or(b)).toEqual(a) }) it("returns the late value when Err or Ok", () => { - const a = Err("early error") - const b = Ok("foo") + const a = TestErr("early error") + const b = TestOk(0) expect(a.or(b)).toEqual(b) }) it("returns the late error when Err and Err", () => { - const a = Err("early error") - const b = Err("late error") + const a = TestErr("early error") + const b = TestErr("late error") expect(a.or(b)).toEqual(b) }) }) describe.concurrent("orElse", () => { it("returns the result for an Ok result", () => { - const a = Ok(0) + const a = TestOk(0) expect(a.orElse(() => Ok(1))).toEqual(a) }) it("returns the mapped value for an Err result", () => { - const a = Err("early error") + const a = TestErr("early error") expect(a.orElse(() => Ok(1))).toEqual(Ok(1)) }) }) describe.concurrent("unwrap", () => { it("returns the value for an Ok result", () => { - const result = Ok(42) + const result = TestOk(42) expect(result.unwrap()).toEqual(42) }) it("throws a Panic for an Err result", () => { - const error = new Error("Test error") - const result = Err(error) + const result = TestErr("error") expect(() => result.unwrap()).toThrow(UnwrapPanic) }) }) describe.concurrent("unwrapErr", () => { it("returns the error for an Err result", () => { - const error = new Error("Test error") - const result = Err(error) - expect(result.unwrapErr()).toEqual(error) + const result = TestErr("error") + expect(result.unwrapErr()).toEqual("error") }) it("throws for an Ok result", () => { - const result = Ok(42) + const result = TestOk(42) expect(() => result.unwrapErr()).toThrow(UnwrapPanic) }) }) describe.concurrent("unwrapOr", () => { it("returns the value for an Ok result", () => { - const result = Ok(42) + const result = TestOk(42) expect(result.unwrapOr(0)).toEqual(42) }) it("returns the default value for an Err result", () => { - const error = new Error("Test error") - const result = Err(error) + const result = TestErr("error") expect(result.unwrapOr(42)).toEqual(42) }) }) describe.concurrent("unwrapOrElse", () => { it("returns the value for an Ok result", () => { - const result = Ok(42) + const result = TestOk(42) expect(result.unwrapOrElse(() => 0)).toEqual(42) }) it("returns the default value from a function for an Err result", () => { - const error = new Error("Test error") - const result = Err(error) + const result = TestErr("error") const unwrapped = result.unwrapOrElse(() => 42) expect(unwrapped).toEqual(42) }) @@ -296,7 +287,7 @@ describe.concurrent("unwrapOrElse", () => { describe.concurrent("match", () => { it("calls the ok function for an Ok result", () => { - const result = Ok(42) + const result = TestOk(42) const output = result.match( (value) => value * 2, () => 0, @@ -305,8 +296,7 @@ describe.concurrent("match", () => { }) it("calls the err function for an Err result", () => { - const error = new Error("Test error") - const result = Err(error) + const result = TestErr("error") const output = result.match( (value) => value * 2, () => 0,