Repository: nuxt/nuxt
File: test/nuxt/composables.test.ts (TypeScript)

Code before:
})

describe('loading state', () => {
  it('expect loading state to be changed by force starting/stoping', async () => {
    vi.stubGlobal('setTimeout', vi.fn((cb: () => void) => cb()))
    const nuxtApp = useNuxtApp()
    const { isLoading, start, finish } = useLoadingIndicator()
    expect(isLoading.value).toBeFalsy()
    await nuxtApp.callHook('page:loading:start')
    expect(isLoading.value).toBeTruthy()
    start()
    expect(isLoading.value).toBeTruthy()
    finish()
    expect(isLoading.value).toBeFalsy()
  })
})

describe('loading state', () => {
  it('expect error from loading state to be changed by finish({ error: true })', async () => {
    vi.stubGlobal('setTimeout', vi.fn((cb: () => void) => cb()))
    const nuxtApp = useNuxtApp()
    const { error, start, finish } = useLoadingIndicator()
    expect(error.value).toBeFalsy()
    await nuxtApp.callHook('page:loading:start')
    start()
    finish({ error: true })
    expect(error.value).toBeTruthy()
    start()
    expect(error.value).toBeFalsy()
    finish()
  })
})

describe('loading state', () => {
  it('expect state from set opts: { force: true }', async () => {
    vi.stubGlobal('setTimeout', vi.fn((cb: () => void) => cb()))
    const nuxtApp = useNuxtApp()
    const { isLoading, start, finish, set } = useLoadingIndicator()
    await nuxtApp.callHook('page:loading:start')
    start({ force: true })
    expect(isLoading.value).toBeTruthy()
    finish()
    expect(isLoading.value).toBeFalsy()
    set(0, { force: true })
    expect(isLoading.value).toBeTruthy()
    set(100, { force: true })
    expect(isLoading.value).toBeFalsy()
  })
})

describe.skipIf(process.env.TEST_MANIFEST === 'manifest-off')('app manifests', () => {

Review comment (suggestion):
After enabling fake timers, pending callbacks (e.g., from `start()` and `finish()`) won't run automatically; consider adding `vi.advanceTimersToNextTimer()` after those calls to ensure `error.value` is updated as expected.

Code after:
    expect(isLoading.value).toBeFalsy()
    vi.useRealTimers()
  })
})

describe('loading state', () => {
  it('expect loading state to be changed by force starting/stoping', async () => {
    vi.useFakeTimers()
    const nuxtApp = useNuxtApp()
    const { isLoading, start, finish } = useLoadingIndicator()
    expect(isLoading.value).toBeFalsy()
    await nuxtApp.callHook('page:loading:start')
    vi.advanceTimersToNextTimer()
    expect(isLoading.value).toBeTruthy()
    start()
    expect(isLoading.value).toBeTruthy()
    finish()
    vi.advanceTimersToNextTimer()
    expect(isLoading.value).toBeFalsy()
    vi.useRealTimers()
  })
})

describe('loading state', () => {
  it('expect error from loading state to be changed by finish({ error: true })', async () => {
    vi.useFakeTimers()
    const nuxtApp = useNuxtApp()
    const { error, start, finish } = useLoadingIndicator()
    expect(error.value).toBeFalsy()
    await nuxtApp.callHook('page:loading:start')
    start()
    finish({ error: true })
    expect(error.value).toBeTruthy()
    start()
    expect(error.value).toBeFalsy()
    finish()
    vi.useRealTimers()
  })
})

describe('loading state', () => {
  it('expect state from set opts: { force: true }', async () => {
    vi.useFakeTimers()
    const nuxtApp = useNuxtApp()
    const { isLoading, start, finish, set } = useLoadingIndicator()
    await nuxtApp.callHook('page:loading:start')
    start({ force: true })
    expect(isLoading.value).toBeTruthy()
    finish()
    vi.advanceTimersToNextTimer()
    expect(isLoading.value).toBeFalsy()