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

chore: migrate to vitest #948

Open
wants to merge 34 commits into
base: v3
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
cdb34e3
chore: migrate async package from uvu to vitest
caio2983 Oct 26, 2024
2556fa9
chore: migrate core package from uvu to vitest
caio2983 Oct 26, 2024
c176cad
chore: migrate core-v1 package from uvu to vitest
caio2983 Oct 26, 2024
2342cd7
chore: migrate core-v2 package from uvu to vitest
caio2983 Oct 26, 2024
18bddb2
chore: migrate effects package from uvu to vitest
caio2983 Oct 26, 2024
fc7e8dd
chore: migrate framework package from uvu to vitest
caio2983 Oct 26, 2024
875c494
chore: migrate hooks package from uvu to vitest
caio2983 Oct 26, 2024
b7498a7
chore: migrate jsx package from uvu to vitest
caio2983 Oct 27, 2024
96d54f7
chore: migrate lens package from uvu to vitest
caio2983 Oct 27, 2024
a58ca8a
chore: migrate logger package from uvu to vitest
caio2983 Oct 27, 2024
420d6f3
chore: migrate npm-cookie-baker package from uvu to vitest
caio2983 Oct 27, 2024
e779c67
chore: migrate npm-lit package from uvu to vitest
caio2983 Oct 27, 2024
4038179
chore: migrate npm-react package from uvu to vitest
caio2983 Oct 27, 2024
5518edb
chore: migrate npm-solid-js package from uvu to vitest
caio2983 Oct 27, 2024
93b9c21
chore: migrate npm-svelte package from uvu to vitest
caio2983 Oct 27, 2024
951f726
chore: migrate npm-vue package from uvu to vitest
caio2983 Oct 27, 2024
9a8f674
chore: migrate npm-zod package from uvu to vitest
caio2983 Oct 27, 2024
de29681
chore: migrate persist package from uvu to vitest
caio2983 Oct 27, 2024
3209ab9
chore: migrate persist-web-storage package from uvu to vitest
caio2983 Oct 27, 2024
85c35b0
chore: migrate primitive package from uvu to vitest
caio2983 Oct 27, 2024
9feed0d
chore: migrate testing package from uvu to vitest
caio2983 Oct 27, 2024
a9614c9
chore: migrate timer package from uvu to vitest
caio2983 Oct 27, 2024
f090394
chore: migrate undo package from uvu to vitest
caio2983 Oct 27, 2024
39b0f69
chore: migrate url package from uvu to vitest
caio2983 Oct 27, 2024
05e93a9
chore: migrate utils package from uvu to vitest
caio2983 Oct 27, 2024
4fdd4d5
chore: migrate web package from uvu to vitest
caio2983 Oct 27, 2024
6c9c88e
chore: migrate devtools package from uvu to vitest
caio2983 Oct 27, 2024
b6175b5
chore: migrate form package from uvu to vitest
caio2983 Oct 27, 2024
ecad5c4
chore: migrate form-web package from uvu to vitest
caio2983 Oct 27, 2024
7f5ae68
fix(async): retrieve removed comments
caio2983 Oct 28, 2024
c268243
refactor(async): remove describe usage
caio2983 Oct 28, 2024
01dfa9c
refactor(async): change tests runner script
caio2983 Oct 28, 2024
201b184
chore: change test scripts and remove non-english comments
caio2983 Nov 1, 2024
6e3b4cb
chore: migrate web-fetch package from uvu to vitest
caio2983 Nov 1, 2024
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
451 changes: 418 additions & 33 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@
"turbo": "^1.13.0",
"typescript": "^5.4.3",
"use-sync-external-store": "^1.2.0",
"uvu": "^0.5.6",
"vite": "^5.2.6",
"vitest": "^2.1.3",
"zx": "^7.2.3"
},
"peerDependencies": {
Expand Down
4 changes: 2 additions & 2 deletions packages/async/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
"scripts": {
"prepublishOnly": "npm run build && npm run test",
"build": "microbundle -f esm,cjs",
"test": "ts-node src/index.test.ts",
"test:watch": "tsx watch src/index.test.ts"
"test": "vitest",
"test:watch": "vitest --watch"
},
"dependencies": {
"@reatom/core": "^3.5.0",
Expand Down
76 changes: 24 additions & 52 deletions packages/async/src/index.story.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { test } from 'uvu'
import * as assert from 'uvu/assert'
import { describe, it, expect } from 'vitest'
import { createTestCtx } from '@reatom/testing'
import { atom } from '@reatom/core'
import { onConnect } from '@reatom/hooks'
Expand All @@ -13,9 +12,9 @@ describe('optimistic update', () => {
We want to update the list immediately, but we want to rollback the update
if the server returns an error.

Also, we use `onConnect` to fetch the list from the server every 5 seconds
and we don't want to call subscriptions extra times so we use `isDeepEqual`
in `withDataAtom` to prevent new reference stream if nothing really changed.
Also, we use onConnect to fetch the list from the server every 5 seconds
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the quotes removed?

and we don't want to call subscriptions extra times so we use isDeepEqual
in withDataAtom to prevent new reference stream if nothing really changed.
*/

//#region BACKEND IMITATION
Expand All @@ -30,25 +29,16 @@ describe('optimistic update', () => {
}
//#endregion

// this is short for test purposes, use ~5000 in real code
const INTERVAL = 5

const getData = reatomAsync.from(api.getData).pipe(
// add `dataAtom` and map the effect payload into it
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the comments removed?

// try to prevent new reference stream if nothing really changed
withDataAtom([], (ctx, payload, state) =>
isDeepEqual(payload, state) ? state : payload,
),
)
const getData = reatomAsync
.from(api.getData)
.pipe(withDataAtom([], (ctx, payload, state) => (isDeepEqual(payload, state) ? state : payload)))
const putData = reatomAsync.from(api.putData)
putData.onCall((ctx, promise, params) => {
const [id, value] = params
const oldList = ctx.get(getData.dataAtom)
// optimistic update
const newList = getData.dataAtom(ctx, (state) =>
state.map((item) => (item.id === id ? { ...item, value } : item)),
)
// rollback on error
const newList = getData.dataAtom(ctx, (state) => state.map((item) => (item.id === id ? { ...item, value } : item)))
promise.catch((error) => {
if (ctx.get(getData.dataAtom) === newList) {
getData.dataAtom(ctx, oldList)
Expand All @@ -67,36 +57,29 @@ describe('optimistic update', () => {
}
})

test('optimistic update', async () => {
it('optimistic update', async () => {
const ctx = createTestCtx()
const effectTrack = ctx.subscribeTrack(getData.onFulfill)
const dataTrack = ctx.subscribeTrack(getData.dataAtom)

// every subscription calls passed callback immediately
assert.is(effectTrack.calls.length, 1)
assert.is(dataTrack.calls.length, 1)
assert.equal(dataTrack.lastInput(), [])
expect(effectTrack.calls.length).toBe(1)
expect(dataTrack.calls.length).toBe(1)
expect(dataTrack.lastInput()).toEqual([])

// `onConnect` calls `fetchData`, wait it and check changes
await sleep()
assert.is(dataTrack.calls.length, 2)
assert.equal(dataTrack.lastInput(), [{ id: 1, value: 1 }])
expect(dataTrack.calls.length).toBe(2)
expect(dataTrack.lastInput()).toEqual([{ id: 1, value: 1 }])

// call `updateData` and check changes
putData(ctx, 1, 2)
assert.is(dataTrack.calls.length, 3)
assert.equal(dataTrack.lastInput(), [{ id: 1, value: 2 }])
expect(dataTrack.calls.length).toBe(3)
expect(dataTrack.lastInput()).toEqual([{ id: 1, value: 2 }])

// wait for `fetchData` and check changes
assert.is(effectTrack.calls.length, 2)
expect(effectTrack.calls.length).toBe(2)
await sleep(INTERVAL)
// the effect is called again, but dataAtom is not updated
assert.is(effectTrack.calls.length, 3)
assert.is(dataTrack.calls.length, 3)
expect(effectTrack.calls.length).toBe(3)
expect(dataTrack.calls.length).toBe(3)

// cleanup test
dataTrack.unsubscribe()
;`👍` //?
})
})

Expand All @@ -106,7 +89,7 @@ describe('concurrent pooling', () => {
every 5 seconds. We want to abort the previous pooling if the new one
was started. The problem with the most tooling for async management is that no causes tracking
and we can't abort some step of the previous pooling if the new one was started.
Reatom handle it perfectly, because `ctx` is immutable and could be traced when needed.
Reatom handle it perfectly, because ctx is immutable and could be traced when needed.
*/

//#region BACKEND IMITATION
Expand All @@ -119,7 +102,6 @@ describe('concurrent pooling', () => {
await sleep(5)
const progress = (tasks.get(taskId) ?? -10) + 10
tasks.set(taskId, progress)

return progress
},
}
Expand All @@ -141,7 +123,7 @@ describe('concurrent pooling', () => {
}
}).pipe(withAbort({ strategy: 'last-in-win' }))

test('concurrent pooling', async () => {
it('concurrent pooling', async () => {
const ctx = createTestCtx()
const track = ctx.subscribeTrack(progressAtom)

Expand All @@ -151,20 +133,10 @@ describe('concurrent pooling', () => {

await Promise.allSettled([promise1, promise2])

assert.is(ctx.get(progressAtom), 100)
expect(ctx.get(progressAtom)).toBe(100)

const expectedProgress = [
0, 10, /* start again */ 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100,
]
const expectedProgress = [0, 10, /* start again */ 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100]

// assert.equal(track.inputs(), expectedProgress)
;`👍` //?
// expect(track.inputs()).toEqual(expectedProgress)
})
})

test.run()

// uvu have no own describe
function describe(name: string, fn: () => any) {
fn()
}
75 changes: 36 additions & 39 deletions packages/async/src/mapToAsync.test.ts
Original file line number Diff line number Diff line change
@@ -1,55 +1,52 @@
import { suite } from 'uvu'
import * as assert from 'uvu/assert'
import { describe, it, expect } from 'vitest'
import { take, takeNested } from '@reatom/effects'
import { createTestCtx } from '@reatom/testing'
import { atom } from '@reatom/core'
import { mapToAsync, withDataAtom } from './index'

export const test = suite('mapToAsync')
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no need to use describe, please change the tests runner script to this:

    "test": "vitest run src/*.test.ts",
    "test:watch": "vitest src/*.test.ts"

describe('mapToAsync', () => {
it(`mapToAsync interface`, () => {
const argumentAtom = atom(0, 'argumentAtom')
const asyncAction = argumentAtom.pipe(mapToAsync(async (ctx, arg) => arg))

test(`mapToAsync interface`, () => {
const argumentAtom = atom(0, 'argumentAtom')
const asyncAction = argumentAtom.pipe(mapToAsync(async (ctx, arg) => arg))
expect(typeof asyncAction).toBe('function')
expect(asyncAction.__reatom.name).toBe('argumentAtom.mapToAsync')
expect(typeof asyncAction.unstable_unhook).toBe('function')
;`👍` //?
})

assert.type(asyncAction, 'function')
assert.is(asyncAction.__reatom.name, 'argumentAtom.mapToAsync')
assert.type(asyncAction.unstable_unhook, 'function')
;`👍` //?
})

test(`is called whenever argument is changed`, async () => {
const argumentAtom = atom('initial', 'argumentAtom')
const asyncAction = argumentAtom.pipe(
mapToAsync(async (ctx, arg) => arg),
withDataAtom('default'),
)
const ctx = createTestCtx()
it(`is called whenever argument is changed`, async () => {
const argumentAtom = atom('initial', 'argumentAtom')
const asyncAction = argumentAtom.pipe(
mapToAsync(async (ctx, arg) => arg),
withDataAtom('default'),
)
const ctx = createTestCtx()

assert.is(ctx.get(asyncAction.dataAtom), 'default')
expect(ctx.get(asyncAction.dataAtom)).toBe('default')

const hijackedCall = take(ctx, asyncAction)
const hijackedCall = take(ctx, asyncAction)

argumentAtom(ctx, 'updated')
argumentAtom(ctx, 'updated')

assert.is(await hijackedCall, 'updated')
assert.is(ctx.get(asyncAction.dataAtom), 'updated')
;`👍` //?
})
expect(await hijackedCall).toBe('updated')
expect(ctx.get(asyncAction.dataAtom)).toBe('updated')
;`👍` //?
})

test(`can be unhooked`, async () => {
const argumentAtom = atom('initial', 'argumentAtom')
const asyncAction = argumentAtom.pipe(
mapToAsync(async (ctx, n) => n),
withDataAtom('default'),
)
it(`can be unhooked`, async () => {
const argumentAtom = atom('initial', 'argumentAtom')
const asyncAction = argumentAtom.pipe(
mapToAsync(async (ctx, n) => n),
withDataAtom('default'),
)

asyncAction.unstable_unhook()
asyncAction.unstable_unhook()

const ctx = createTestCtx()
const ctx = createTestCtx()

await takeNested(ctx, argumentAtom, 'updated')
assert.is(ctx.get(asyncAction.dataAtom), 'default')
;`👍` //?
await takeNested(ctx, argumentAtom, 'updated')
expect(ctx.get(asyncAction.dataAtom)).toBe('default')
;`👍` //?
})
})

test.run()
Loading