Repository: nuxt/nuxt
File: packages/nuxt/test/page-metadata.test.ts (TypeScript)

Code before:
  // TODO: https://github.com/nuxt/nuxt/pull/30066
  it.todo('should handle experimental decorators', async () => {
    const fileContents = `
<script setup lang="ts">
function something (_method: () => unknown) {
  return () => 'decorated'
}
class SomeClass {
  @something
  public someMethod () {
    return 'initial'
  }
}
definePageMeta({ name: 'bar' })
</script>
    `
    const meta = await getRouteMeta(fileContents, `/app/pages/index.vue`)
    expect(meta).toStrictEqual({
      name: 'bar',
    })
  })

  it('should use and invalidate cache', async () => {
    const fileContents = `<script setup>definePageMeta({ foo: 'bar' })</script>`
    // use klona to deep clone the object
    const meta = await getRouteMeta(fileContents, filePath)
    expect(meta === await getRouteMeta(fileContents, filePath)).toBeFalsy()
    expect(meta === await getRouteMeta(fileContents, '/app/pages/other.vue')).toBeFalsy()
    expect(meta === await getRouteMeta('<template><div>Hi</div></template>' + fileContents, filePath)).toBeFalsy()
  })

  it('should extract serialisable metadata', async () => {
    const meta = await getRouteMeta(`
    <script setup>
    definePageMeta({
      path: '/some-custom-path',
      validate: () => true,
      middleware: [
        function () {},
      ],
      otherValue: {
        foo: 'bar',
      },
      // 'name', 'props' and 'alias' are part of 'defaultExtractionKeys'; they're extracted from the component, so we should test the AST walking for different value types
      name: 'some-custom-name',
      props: {
        foo: 'bar',
      },
      alias: ['/alias'],
    })
    </script>

Review comment (performance):
To make this test work, I think we probably have to mock `klona` so it doesn't modify the object.

Otherwise it doesn't in fact test whether the cache is used or not.

Code after:
    })
  })

  // TODO: https://github.com/nuxt/nuxt/pull/30066
  it.todo('should handle experimental decorators', async () => {
    const fileContents = `
<script setup lang="ts">
function something (_method: () => unknown) {
  return () => 'decorated'
}
class SomeClass {
  @something
  public someMethod () {
    return 'initial'
  }
}
definePageMeta({ name: 'bar' })
</script>
    `
    const meta = await getRouteMeta(fileContents, `/app/pages/index.vue`)
    expect(meta).toStrictEqual({
      name: 'bar',
    })
  })

  it('should use and invalidate cache', async () => {
    const _klona = klona as unknown as MockedFunction<typeof klona>
    _klona.mockImplementation(obj => obj)
    const fileContents = `<script setup>definePageMeta({ foo: 'bar' })</script>`
    const meta = await getRouteMeta(fileContents, filePath)
    expect(meta === await getRouteMeta(fileContents, filePath)).toBeTruthy()
    expect(meta === await getRouteMeta(fileContents, '/app/pages/other.vue')).toBeFalsy()
    expect(meta === await getRouteMeta('<template><div>Hi</div></template>' + fileContents, filePath)).toBeFalsy()
    _klona.mockReset()
  })

  it('should not share state between page metadata', async () => {
    const fileContents = `<script setup>definePageMeta({ foo: 'bar' })</script>`
    const meta = await getRouteMeta(fileContents, filePath)
    expect(meta === await getRouteMeta(fileContents, filePath)).toBeFalsy()
  })

  it('should extract serialisable metadata', async () => {
    const meta = await getRouteMeta(`
    <script setup>
    definePageMeta({
      path: '/some-custom-path',
      validate: () => true,
      middleware: [
        function () {},
      ],