Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

binds more Vi utilities, and creates tests #25

Merged
merged 1 commit into from
Aug 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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"
illusionalsagacity marked this conversation as resolved.
Show resolved Hide resolved
@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"
illusionalsagacity marked this conversation as resolved.
Show resolved Hide resolved
@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"
illusionalsagacity marked this conversation as resolved.
Show resolved Hide resolved
}

@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