Skip to content

Commit

Permalink
test: improve test coverage (#2256)
Browse files Browse the repository at this point in the history
  • Loading branch information
sun0day committed Oct 5, 2022
1 parent fd7a2f9 commit 5ce2f6d
Show file tree
Hide file tree
Showing 5 changed files with 419 additions and 24 deletions.
97 changes: 97 additions & 0 deletions packages/core/useElementVisibility/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { nextTick } from 'vue-demi'
import { useElementVisibility } from '.'

describe('useElementVisibility', () => {
let el: HTMLDivElement
const overLeft = document.documentElement.clientWidth + 100
const overTop = document.documentElement.clientHeight + 100
const rect = {
y: 0,
bottom: 0,
height: 0,
left: 0,
right: 0,
top: 0,
width: 0,
} as DOMRect
function scrollTrigger() {
window.dispatchEvent(new Event('scroll'))
}
function mockGetBoundingClientRect(values: DOMRect[]) {
const mocker = values.reduce((f, result) => f.mockReturnValueOnce(result), vi.fn())
// prevent error when other tests trigger scroll
mocker.mockImplementation(() => rect)
return mocker
}

beforeEach(() => {
el = document.createElement('div')
window.innerWidth = document.documentElement.clientWidth
window.innerHeight = document.documentElement.clientHeight
document.body.appendChild(el)
})

it('should work when el is not an element', async () => {
const visible = useElementVisibility(null)
expect(visible.value).toBeFalsy()
scrollTrigger()
await nextTick()
expect(visible.value).toBeFalsy()
})

it('should work when scrollY', async () => {
el.getBoundingClientRect = mockGetBoundingClientRect([
rect,
{ ...rect, top: overTop },
rect,
{ ...rect, top: overTop },
])

const visible = useElementVisibility(el)
expect(visible.value).toBeTruthy()

scrollTrigger()
await nextTick()
expect(visible.value).toBeFalsy()

window.innerHeight = 0
scrollTrigger()
await nextTick()
expect(visible.value).toBeTruthy()

scrollTrigger()
await nextTick()
expect(visible.value).toBeFalsy()
})

it('should work when scrollX', async () => {
el.getBoundingClientRect = mockGetBoundingClientRect([
rect,
{ ...rect, left: overLeft },
rect,
{ ...rect, left: overLeft },
])

const visible = useElementVisibility(el)
expect(visible.value).toBeTruthy()

scrollTrigger()
await nextTick()
expect(visible.value).toBeFalsy()

window.innerWidth = 0
scrollTrigger()
await nextTick()
expect(visible.value).toBeTruthy()

scrollTrigger()
await nextTick()
expect(visible.value).toBeFalsy()
})

it('should work when window is undefined', () => {
// @ts-expect-error set window null
const visible = useElementVisibility(el, { window: null })
expect(visible.value).toBeFalsy()
})
})
153 changes: 130 additions & 23 deletions packages/core/useUrlSearchParams/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { nextTick } from 'vue-demi'
import { isVue3, nextTick } from 'vue-demi'
import { useUrlSearchParams } from '.'

describe('useUrlSearchParams', () => {
Expand All @@ -9,9 +9,13 @@ describe('useUrlSearchParams', () => {
writable: true,
})

const mockReplaceState = vi.fn()

beforeEach(() => {
vi.clearAllMocks()
window.location.search = ''
window.location.hash = ''
window.history.replaceState = mockReplaceState
})

const mockPopstate = (search: string, hash: string) => {
Expand Down Expand Up @@ -47,45 +51,133 @@ describe('useUrlSearchParams', () => {
})

test('return initialValue', async () => {
const params = useUrlSearchParams(mode, {
initialValue: {
foo: 'bar',
},
})
const initialValue = { foo: 'bar' }
const params1 = useUrlSearchParams(mode, { initialValue })
// @ts-expect-error test window=null
const params2 = useUrlSearchParams(mode, { initialValue, window: null })

expect(params.foo).toBe('bar')
expect(params1.foo).toBe('bar')
expect(params2.foo).toBe('bar')
})

test('update params on poststate event', async () => {
const params = useUrlSearchParams(mode)
expect(params.foo).toBeUndefined()
if (mode === 'hash')
mockPopstate('', '#/test/?foo=bar')
else if (mode === 'hash-params')
mockPopstate('', '#foo=bar')
else
mockPopstate('?foo=bar', '')

switch (mode) {
case 'hash':
mockPopstate('', '#/test/?foo=bar')
break
case 'hash-params':
mockPopstate('', '#foo=bar')
break
case 'history':
mockPopstate('?foo=bar', '')
}
await nextTick()
expect(params.foo).toBe('bar')
})

test('update browser location on params change', () => {
const params = useUrlSearchParams(mode)
expect(params.foo).toBeUndefined()
params.foo = 'bar'
switch (mode) {
case 'hash':
mockPopstate('', '#/test/?foo=bar1&foo=bar2')
break
case 'hash-params':
mockPopstate('', '#foo=bar1&foo=bar2')
break
case 'history':
mockPopstate('?foo=bar1&foo=bar2', '')
}
await nextTick()
expect(params.foo).toEqual(['bar1', 'bar2'])

expect(params.foo).toBe('bar')
switch (mode) {
case 'hash':
mockPopstate('', '#/test/?foo=')
break
case 'hash-params':
mockPopstate('', '#foo=')
break
case 'history':
mockPopstate('?foo=', '')
}
await nextTick()
expect(params.foo).toBe('')
})

test('array url search param', () => {
const params = useUrlSearchParams(mode)
test('stop poststate event', async () => {
const params = useUrlSearchParams(mode, { write: false })
expect(params.foo).toBeUndefined()
params.foo = ['bar1', 'bar2']

expect(params.foo).toEqual(['bar1', 'bar2'])
switch (mode) {
case 'hash':
mockPopstate('', '#/test/?foo=bar')
break
case 'hash-params':
mockPopstate('', '#foo=bar')
break
case 'history':
mockPopstate('?foo=bar', '')
}
await nextTick()
expect(params.foo).toBeUndefined()
})

if (isVue3) {
test('update browser location on params change', async () => {
const params = useUrlSearchParams(mode)

params.foo = 'bar'
await nextTick()
switch (mode) {
case 'history':
expect(window.history.replaceState).toBeCalledWith(null, '', '/?foo=bar')
break
case 'hash':
expect(window.history.replaceState).toBeCalledWith(null, '', '/#?foo=bar')
break
case 'hash-params':
expect(window.history.replaceState).toBeCalledWith(null, '', '/#foo=bar')
break
}

if (mode === 'hash')
window.location.hash = '#?foo=bar'

delete params.foo
await nextTick()
switch (mode) {
case 'history':
expect(window.history.replaceState).toBeCalledWith(null, '', '/')
break
case 'hash':
expect(window.history.replaceState).toBeCalledWith(null, '', '/#')
break
case 'hash-params':
expect(window.history.replaceState).toBeCalledWith(null, '', '/')
break
}
})

test('array url search param', async () => {
const params = useUrlSearchParams(mode)
expect(params.foo).toBeUndefined()
params.foo = ['bar1', 'bar2']

await nextTick()
switch (mode) {
case 'history':
expect(window.history.replaceState).toBeCalledWith(null, '', '/?foo=bar1&foo=bar2')
break
case 'hash':
expect(window.history.replaceState).toBeCalledWith(null, '', '/#?foo=bar1&foo=bar2')
break
case 'hash-params':
expect(window.history.replaceState).toBeCalledWith(null, '', '/#foo=bar1&foo=bar2')
break
}
})
}

test('generic url search params', () => {
interface CustomUrlParams extends Record<string, any> {
customFoo: number | undefined
Expand All @@ -98,6 +190,21 @@ describe('useUrlSearchParams', () => {

expect(params.customFoo).toEqual(42)
})

it('should remove null & falsy', async () => {
const params = useUrlSearchParams(mode, {
removeNullishValues: true,
removeFalsyValues: true,
initialValue: {
foo: 'bar',
bar: 'foo',
} as { foo: string | null; bar: string | boolean },
})
params.foo = null
params.bar = false
await nextTick()
expect(params).toEqual({ foo: null, bar: false })
})
})
})

Expand Down

0 comments on commit 5ce2f6d

Please sign in to comment.