Skip to content

Commit

Permalink
feat: binds more Vi utilities, and creates tests
Browse files Browse the repository at this point in the history
  • Loading branch information
illusionalsagacity committed Jun 11, 2024
1 parent 347237e commit 88361a9
Show file tree
Hide file tree
Showing 3 changed files with 332 additions and 31 deletions.
124 changes: 115 additions & 9 deletions src/Vitest.res
Original file line number Diff line number Diff line change
Expand Up @@ -968,6 +968,11 @@ external afterEachPromise: (@uncurry (unit => promise<'a>), Js.Undefined.t<int>)
let afterEachPromise = (~timeout=?, callback) =>
afterEachPromise(callback, timeout->Js.Undefined.fromOption)

@module("vitest")
external afterAll: (@uncurry (unit => 'a), Js.Undefined.t<int>) => unit = "afterAll"

let afterAll = (~timeout=?, callback) => afterAll(callback, timeout->Js.Undefined.fromOption)

@module("vitest")
external afterAllPromise: (@uncurry (unit => promise<'a>), Js.Undefined.t<int>) => unit = "afterAll"

Expand Down Expand Up @@ -1109,7 +1114,9 @@ module Matchers = (

@inline
let toMatch = (expected, list) => {
expected->dangerously_reinforce_assertion(Belt.List.toArray)->Array.toMatch(list->Belt.List.toArray)
expected
->dangerously_reinforce_assertion(Belt.List.toArray)
->Array.toMatch(list->Belt.List.toArray)
}
}

Expand Down Expand Up @@ -1160,6 +1167,13 @@ module Assert = {

%%private(@module("vitest") @val external assert_obj: t = "assert")

@module("vitest")
external assert_: (bool, Js.undefined<string>) => unit = "assert"
let assert_ = (~message=?, value) => assert_(value, message->Js.Undefined.fromOption)

@module("vitest") @scope("expect")
external unreachable: (~message: string=?, unit) => unit = "unreachable"

@send external equal: (t, 'a, 'a, Js.undefined<string>) => unit = "equal"

@inline
Expand All @@ -1180,29 +1194,121 @@ module Vi = {
@send external advanceTimersByTime: (t, int) => t = "advanceTimersByTime"
@inline let advanceTimersByTime = ms => vi_obj->advanceTimersByTime(ms)

@send external advanceTimersByTimeAsync: (t, int) => promise<t> = "advanceTimersByTimeAsync"
let advanceTimersByTimeAsync = time => vi_obj->advanceTimersByTimeAsync(time)

@send external advanceTimersToNextTimer: t => t = "advanceTimersToNextTimer"
@inline let advanceTimersToNextTimer = () => vi_obj->advanceTimersToNextTimer

@send external advanceTimersToNextTimerAsync: t => promise<t> = "advanceTimersToNextTimerAsync"
let advanceTimersToNextTimerAsync = () => vi_obj->advanceTimersToNextTimerAsync

@send external getTimerCount: t => int = "getTimerCount"
let getTimerCount = () => vi_obj->getTimerCount

@send external clearAllTimers: t => t = "clearAllTimers"
let clearAllTimers = () => vi_obj->clearAllTimers

@send external runAllTicks: t => t = "runAllTicks"
let runAllTicks = () => vi_obj->runAllTicks

@send external runAllTimers: t => t = "runAllTimers"
@inline let runAllTimers = () => vi_obj->runAllTimers

@send external runAllTimersAsync: t => promise<t> = "runAllTimersAsync"
let runAllTimersAsync = () => vi_obj->runAllTimersAsync

@send external runOnlyPendingTimers: t => t = "runOnlyPendingTimers"
@inline let runOnlyPendingTimers = () => vi_obj->runOnlyPendingTimers

@send external useFakeTimers: t => t = "useFakeTimers"
@inline let useFakeTimers = () => vi_obj->useFakeTimers
@send external runOnlyPendingTimersAsync: t => promise<t> = "runOnlyPendingTimersAsync"
let runOnlyPendingTimersAsync = () => vi_obj->runOnlyPendingTimersAsync

@send
external setSystemTime: (t, @unwrap [#Date(Js.Date.t) | #String(string) | #Int(int)]) => t =
"setSystemTime"
let setSystemTime = time => vi_obj->setSystemTime(time)

/**
https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/sinonjs__fake-timers/index.d.ts
*/
type fakeTimersConfig = {
now?: Js.Date.t, // or int
toFake?: array<string>,
loopLimit?: int,
shouldAdvanceTime?: bool,
advanceTimeDelta?: int,
shouldClearNativeTimers?: bool,
}

@send external useFakeTimers: (t, ~config: fakeTimersConfig=?, unit) => t = "useFakeTimers"
@inline let useFakeTimers = (~config=?, ()) => vi_obj->useFakeTimers(~config?, ())

@send external useRealTimers: t => t = "useRealTimers"
@inline let useRealTimers = () => vi_obj->useRealTimers

@send external mockCurrentDate: (t, Js.Date.t) => t = "mockCurrentDate"
@inline let mockCurrentDate = date => vi_obj->mockCurrentDate(date)
@send external isFakeTimers: t => bool = "isFakeTimers"
let isFakeTimers = () => vi_obj->isFakeTimers

@send @return(nullable)
external getMockedSystemTime: t => option<Js.Date.t> = "getMockedSystemTime"
let getMockedSystemTime = () => vi_obj->getMockedSystemTime

@send external getRealSystemTime: t => float = "getRealSystemTime"
let getRealSystemTime = () => vi_obj->getRealSystemTime

@send external restoreCurrentDate: (t, Js.Date.t) => t = "restoreCurrentDate"
@inline let restoreCurrentDate = date => vi_obj->restoreCurrentDate(date)
type waitForOptions = {
timeout?: int,
interval?: int,
}

@send external waitFor: (t, @uncurry unit => 'a, waitForOptions) => promise<'a> = "waitFor"

/**
@since(vitest >= 0.34.5)
*/
let waitFor = (callback, ~timeout=?, ~interval=?, ()) => {
waitFor(vi_obj, callback, {?timeout, ?interval})
}

@send
external waitForAsync: (t, @uncurry unit => promise<'a>, waitForOptions) => promise<'a> = "waitFor"

/**
@since(vitest >= 0.34.5)
*/
let waitForAsync = (callback, ~timeout=?, ~interval=?, ()) => {
waitForAsync(vi_obj, callback, {?timeout, ?interval})
}

type waitUntilOptions = {
timeout?: int,
interval?: int,
}

@send
external waitUntil: (t, @uncurry unit => 'a, waitUntilOptions) => promise<'a> = "waitUntil"

/**
@since(vitest >= 0.34.5)
*/
let waitUntil = (callback, ~timeout=?, ~interval=?, ()) => {
waitUntil(vi_obj, callback, {?timeout, ?interval})
}

@send
external waitUntilAsync: (t, @uncurry unit => promise<'a>, waitUntilOptions) => promise<'a> =
"waitUntil"

/**
@since(vitest >= 0.34.5)
*/
let waitUntilAsync = (callback, ~timeout=?, ~interval=?, ()) => {
waitUntilAsync(vi_obj, callback, {?timeout, ?interval})
}

@send external getMockedDate: t => Js.null<Js.Date.t> = "getMockedDate"
@inline let getMockedDate = () => vi_obj->getMockedDate->Js.Null.toOption
// binding this using vi_obj causes a runtime error. this is because vitest sees this inside this file, then tries to evaluate the hoisted function, but the hoisted function is not provided yet, it's just a parameter to the function
@send external hoisted: (t, @uncurry unit => 'a) => 'a = "hoisted"
}

@scope("import.meta") @val
Expand Down
68 changes: 46 additions & 22 deletions tests/assertions.test.res
Original file line number Diff line number Diff line change
@@ -1,5 +1,29 @@
open Vitest

describe("Assert", () => {
test("assert_", _t => {
Assert.assert_(true)
Assert.assert_(1 == 1)
Assert.assert_("one" == "one")
Assert.assert_(1 == 1)
})

test("unreachable", _t => {
try {
let _ = Js.Exn.raiseError("error")
Assert.unreachable()
} catch {
| _ => Assert.assert_(~message="threw error", true)
}

try {
expect(true)->Expect.toBe(true)
} catch {
| _ => Assert.unreachable()
}
})
})

describe("Expect", () => {
test("toBe", _t => {
expect(1)->Expect.toBe(1)
Expand Down Expand Up @@ -248,41 +272,41 @@ describe("Expect", () => {
})

describe("Array", () => {
test(
"toContain",
_t => {
expect([1, 2, 3])->Expect.Array.toContain(2)
expect(["hello", "world"])->Expect.Array.toContain("world")
expect([true, false])->Expect.Array.toContain(false)
expect([1, 2, 3])->Expect.not->Expect.Array.toContain(4)
test(
"toContain",
_t => {
expect([1, 2, 3])->Expect.Array.toContain(2)
expect(["hello", "world"])->Expect.Array.toContain("world")
expect([true, false])->Expect.Array.toContain(false)
expect([1, 2, 3])->Expect.not->Expect.Array.toContain(4)
},
)

test(
"toContainEqual",
_t => {
expect([1, 2, 3])->Expect.Array.toContainEqual(2)
expect(["hello", "world"])->Expect.Array.toContainEqual("world")
expect([true, false])->Expect.Array.toContainEqual(false)
expect([1, 2, 3])->Expect.Array.toContainEqual(2)
expect(["hello", "world"])->Expect.Array.toContainEqual("world")
expect([true, false])->Expect.Array.toContainEqual(false)
expect([1, 2, 3])->Expect.not->Expect.Array.toContainEqual(4)
},
)

test(
"toHaveLength",
_t => {
expect([1, 2, 3])->Expect.Array.toHaveLength(3)
expect([])->Expect.Array.toHaveLength(0)
expect([1, 2, 3])->Expect.not->Expect.Array.toHaveLength(5)
},
)
_t => {
expect([1, 2, 3])->Expect.Array.toHaveLength(3)
expect([])->Expect.Array.toHaveLength(0)
expect([1, 2, 3])->Expect.not->Expect.Array.toHaveLength(5)
},
)

test(
"toMatch",
_t => {
expect([1, 2, 3])->Expect.Array.toMatch([1, 2, 3])
expect(["hello", "world"])->Expect.Array.toMatch(["hello", "world"])
expect([true, false])->Expect.Array.toMatch([true, false])
test(
"toMatch",
_t => {
expect([1, 2, 3])->Expect.Array.toMatch([1, 2, 3])
expect(["hello", "world"])->Expect.Array.toMatch(["hello", "world"])
expect([true, false])->Expect.Array.toMatch([true, false])
expect([1, 2, 3])->Expect.not->Expect.Array.toMatch([1, 2])
},
)
Expand Down
Loading

0 comments on commit 88361a9

Please sign in to comment.