Skip to content
This repository was archived by the owner on Dec 11, 2025. It is now read-only.
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
47 changes: 47 additions & 0 deletions packages/unuse/src/useIntervalFn/index.solid.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import type { Accessor } from 'solid-js';
import { beforeEach, expect, it, vi } from 'vitest';
import { useIntervalFn } from '.';
import { describeSolid } from '../_testUtils/solid';

describeSolid('useIntervalFn', () => {
let callback = vi.fn();
vi.useFakeTimers();

beforeEach(() => {
callback = vi.fn();
});

it('pause in callback', async () => {
const pausable = useIntervalFn(
() => {
callback();
pausable.pause();
},
50,
{ immediateCallback: true, immediate: false }
);

pausable.resume();
expect(pausable.isActive).toSatisfy((value) => typeof value === 'function');
expect((pausable.isActive as Accessor<boolean>)()).toBeFalsy();
expect(callback).toHaveBeenCalledTimes(1);

await vi.advanceTimersByTimeAsync(60);
expect(callback).toHaveBeenCalledTimes(1);

pausable.resume();
expect((pausable.isActive as Accessor<boolean>)()).toBeFalsy();
expect(callback).toHaveBeenCalledTimes(2);

await vi.advanceTimersByTimeAsync(60);
expect(callback).toHaveBeenCalledTimes(2);
});

it('cant work when interval is negative', async () => {
const { isActive } = useIntervalFn(callback, -1);

expect((isActive as Accessor<boolean>)()).toBeFalsy();
await vi.advanceTimersByTimeAsync(60);
expect(callback).toHaveBeenCalledTimes(0);
});
});
87 changes: 86 additions & 1 deletion packages/unuse/src/useIntervalFn/index.spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,93 @@
import { describe, expect, it } from 'vitest';
// @vitest-environment happy-dom

import type { UnComputed } from 'unuse-reactivity';
import { isUnComputed, unSignal } from 'unuse-reactivity';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import type { Pausable } from '.';
import { useIntervalFn } from '.';

describe('useIntervalFn', () => {
it('should be defined', () => {
expect(useIntervalFn).toBeTypeOf('function');
});

let callback = vi.fn();
vi.useFakeTimers();

beforeEach(() => {
callback = vi.fn();
});

async function exec({ isActive, pause, resume }: Pausable) {
expect(isActive).toSatisfy(isUnComputed);
expect((isActive as unknown as UnComputed<boolean>).get()).toBeTruthy();
expect(callback).toHaveBeenCalledTimes(0);

await vi.advanceTimersByTimeAsync(60);
expect(callback).toHaveBeenCalledTimes(1);

pause();
expect((isActive as unknown as UnComputed<boolean>).get()).toBeFalsy();

await vi.advanceTimersByTimeAsync(60);
expect(callback).toHaveBeenCalledTimes(1);

resume();
expect((isActive as unknown as UnComputed<boolean>).get()).toBeTruthy();

await vi.advanceTimersByTimeAsync(60);
expect(callback).toHaveBeenCalledTimes(2);
}

it('basic pause/resume', async () => {
await exec(useIntervalFn(callback, 50));

callback = vi.fn();

const interval = unSignal(50);
await exec(useIntervalFn(callback, interval));

callback.mockClear();
interval.set(20);
await vi.advanceTimersByTimeAsync(30);
expect(callback).toHaveBeenCalledTimes(1);
});

it('pause in callback', async () => {
const pausable = useIntervalFn(
() => {
callback();
pausable.pause();
},
50,
{ immediateCallback: true, immediate: false }
);

pausable.resume();
expect(pausable.isActive).toSatisfy(isUnComputed);
expect(
(pausable.isActive as unknown as UnComputed<boolean>).get()
).toBeFalsy();
expect(callback).toHaveBeenCalledTimes(1);

await vi.advanceTimersByTimeAsync(60);
expect(callback).toHaveBeenCalledTimes(1);

pausable.resume();
expect(
(pausable.isActive as unknown as UnComputed<boolean>).get()
).toBeFalsy();
expect(callback).toHaveBeenCalledTimes(2);

await vi.advanceTimersByTimeAsync(60);
expect(callback).toHaveBeenCalledTimes(2);
});

it('cant work when interval is negative', async () => {
const { isActive } = useIntervalFn(callback, -1);

expect((isActive as unknown as UnComputed<boolean>).get()).toBeFalsy();
await vi.advanceTimersByTimeAsync(60);
expect(callback).toHaveBeenCalledTimes(0);
});
});
87 changes: 86 additions & 1 deletion packages/unuse/src/useIntervalFn/index.vue.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import { beforeEach, expect, it, vi } from 'vitest';
import type { Ref } from 'vue';
import { isRef, shallowRef } from 'vue';
import { effectScope, isRef, nextTick, shallowRef } from 'vue';
import type { Pausable } from '.';
import { useIntervalFn } from '.';
import { describeVue } from '../_testUtils/vue';
Expand Down Expand Up @@ -36,6 +36,28 @@ describeVue('useIntervalFn', () => {
expect(callback).toHaveBeenCalledTimes(2);
}

async function execImmediateCallback({ isActive, pause, resume }: Pausable) {
expect(isActive).toSatisfy(isRef);
expect((isActive as unknown as Ref<boolean>).value).toBeTruthy();
expect(callback).toHaveBeenCalledTimes(1);

await vi.advanceTimersByTimeAsync(60);
expect(callback).toHaveBeenCalledTimes(2);

pause();
expect((isActive as unknown as Ref<boolean>).value).toBeFalsy();

await vi.advanceTimersByTimeAsync(60);
expect(callback).toHaveBeenCalledTimes(2);

resume();
expect((isActive as unknown as Ref<boolean>).value).toBeTruthy();
expect(callback).toHaveBeenCalledTimes(3);

await vi.advanceTimersByTimeAsync(60);
expect(callback).toHaveBeenCalledTimes(4);
}

it('basic pause/resume', async () => {
await exec(useIntervalFn(callback, 50));

Expand All @@ -49,4 +71,67 @@ describeVue('useIntervalFn', () => {
await vi.advanceTimersByTimeAsync(30);
expect(callback).toHaveBeenCalledTimes(1);
});

it('pause/resume with immediateCallback', async () => {
await execImmediateCallback(
useIntervalFn(callback, 50, { immediateCallback: true })
);

callback = vi.fn();

const interval = shallowRef(50);
await execImmediateCallback(
useIntervalFn(callback, interval, { immediateCallback: true })
);

callback.mockClear();
interval.value = 20;
await nextTick();
expect(callback).toHaveBeenCalledTimes(1);
});

it('pause/resume in scope', async () => {
const scope = effectScope();
await scope.run(async () => {
await exec(useIntervalFn(callback, 50));
});
callback.mockClear();
scope.stop();
await vi.advanceTimersByTimeAsync(60);
expect(callback).toHaveBeenCalledTimes(0);
});

it('pause in callback', async () => {
const pausable = useIntervalFn(
() => {
callback();
pausable.pause();
},
50,
{ immediateCallback: true, immediate: false }
);

pausable.resume();
expect(pausable.isActive).toSatisfy(isRef);
expect((pausable.isActive as unknown as Ref<boolean>).value).toBeFalsy();
expect(callback).toHaveBeenCalledTimes(1);

await vi.advanceTimersByTimeAsync(60);
expect(callback).toHaveBeenCalledTimes(1);

pausable.resume();
expect((pausable.isActive as unknown as Ref<boolean>).value).toBeFalsy();
expect(callback).toHaveBeenCalledTimes(2);

await vi.advanceTimersByTimeAsync(60);
expect(callback).toHaveBeenCalledTimes(2);
});

it('cant work when interval is negative', async () => {
const { isActive } = useIntervalFn(callback, -1);

expect((isActive as unknown as Ref<boolean>).value).toBeFalsy();
await vi.advanceTimersByTimeAsync(60);
expect(callback).toHaveBeenCalledTimes(0);
});
});
Loading