|
|
|
|
@ -1,4 +1,4 @@
|
|
|
|
|
import { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises'
|
|
|
|
|
import { mkdir, mkdtemp, rm, stat, utimes, writeFile } from 'node:fs/promises'
|
|
|
|
|
import { tmpdir } from 'node:os'
|
|
|
|
|
import path from 'node:path'
|
|
|
|
|
|
|
|
|
|
@ -82,6 +82,105 @@ describe('node/contentLoader', () => {
|
|
|
|
|
expect(data[0].excerpt).toContain('Intro says My Post.')
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test.each([
|
|
|
|
|
['nested include', '<!-- @include: ./partial.md -->'],
|
|
|
|
|
['code snippet', '<<< ./included.txt']
|
|
|
|
|
])(
|
|
|
|
|
'refreshes cached HTML and excerpts after a %s changes',
|
|
|
|
|
async (_, src) => {
|
|
|
|
|
await setup(false)
|
|
|
|
|
const included = path.join(root!, 'included.txt')
|
|
|
|
|
await writeFile(included, 'Before the edit')
|
|
|
|
|
await writeFile(
|
|
|
|
|
path.join(root!, 'partial.md'),
|
|
|
|
|
'<!-- @include: ./included.txt -->'
|
|
|
|
|
)
|
|
|
|
|
await writeFile(path.join(root!, 'post.md'), `${src}\n\n---\n\nBody`)
|
|
|
|
|
const loader = createContentLoader(['post.md', 'other.md'], {
|
|
|
|
|
render: true,
|
|
|
|
|
excerpt: true
|
|
|
|
|
})
|
|
|
|
|
const initial = await loader.load()
|
|
|
|
|
const initialPost = initial.find((page) => page.url === '/post.html')!
|
|
|
|
|
const initialOther = initial.find((page) => page.url === '/other.html')!
|
|
|
|
|
expect(initialPost.html).toContain('Before the edit')
|
|
|
|
|
expect(initialPost.excerpt).toContain('Before the edit')
|
|
|
|
|
|
|
|
|
|
const unchanged = await loader.load()
|
|
|
|
|
expect(unchanged.find((page) => page.url === '/post.html')).toBe(
|
|
|
|
|
initialPost
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// Change only the dependency, keeping the page's source and mtime intact.
|
|
|
|
|
const timestamp = (await stat(included)).mtimeMs + 1000
|
|
|
|
|
await writeFile(included, 'After the edit')
|
|
|
|
|
await utimes(included, timestamp / 1000, timestamp / 1000)
|
|
|
|
|
|
|
|
|
|
const updated = await loader.load()
|
|
|
|
|
const updatedPost = updated.find((page) => page.url === '/post.html')!
|
|
|
|
|
expect(updatedPost.html).toContain('After the edit')
|
|
|
|
|
expect(updatedPost.excerpt).toContain('After the edit')
|
|
|
|
|
expect(updatedPost.html).not.toContain('Before the edit')
|
|
|
|
|
expect(updated.find((page) => page.url === '/other.html')).toBe(
|
|
|
|
|
initialOther
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
test('tracks dependencies rendered only by a custom excerpt', async () => {
|
|
|
|
|
await setup(false)
|
|
|
|
|
const included = path.join(root!, 'included.txt')
|
|
|
|
|
await writeFile(included, 'Before the edit')
|
|
|
|
|
const loader = createContentLoader('index.md', {
|
|
|
|
|
excerpt(file) {
|
|
|
|
|
file.excerpt = '<!-- @include: ./included.txt -->'
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
const initial = await loader.load()
|
|
|
|
|
expect(initial[0].html).toBeUndefined()
|
|
|
|
|
expect(initial[0].excerpt).toContain('Before the edit')
|
|
|
|
|
|
|
|
|
|
const timestamp = (await stat(included)).mtimeMs + 1000
|
|
|
|
|
await writeFile(included, 'After the edit')
|
|
|
|
|
await utimes(included, timestamp / 1000, timestamp / 1000)
|
|
|
|
|
|
|
|
|
|
expect((await loader.load())[0].excerpt).toContain('After the edit')
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test('reports deleted dependencies instead of returning cached HTML', async () => {
|
|
|
|
|
await setup(false)
|
|
|
|
|
await writeFile(
|
|
|
|
|
path.join(root!, 'post.md'),
|
|
|
|
|
'<!-- @include: ./other.md -->'
|
|
|
|
|
)
|
|
|
|
|
const loader = createContentLoader('post.md', { render: true })
|
|
|
|
|
expect((await loader.load())[0].html).toContain('Other')
|
|
|
|
|
|
|
|
|
|
await rm(path.join(root!, 'other.md'))
|
|
|
|
|
|
|
|
|
|
await expect(loader.load()).rejects.toThrow('Include file not found:')
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test('refreshes silent includes when a missing file is created or deleted', async () => {
|
|
|
|
|
await setup(false)
|
|
|
|
|
const config = (global as any).VITEPRESS_CONFIG
|
|
|
|
|
config.markdown = { include: { silent: true } }
|
|
|
|
|
config.logger.warn = vi.fn()
|
|
|
|
|
await writeFile(
|
|
|
|
|
path.join(root!, 'post.md'),
|
|
|
|
|
'<!-- @include: ./missing.md -->'
|
|
|
|
|
)
|
|
|
|
|
const loader = createContentLoader('post.md', { render: true })
|
|
|
|
|
expect((await loader.load())[0].html).not.toContain('Created content')
|
|
|
|
|
|
|
|
|
|
const included = path.join(root!, 'missing.md')
|
|
|
|
|
await writeFile(included, 'Created content')
|
|
|
|
|
expect((await loader.load())[0].html).toContain('Created content')
|
|
|
|
|
|
|
|
|
|
await rm(included)
|
|
|
|
|
expect((await loader.load())[0].html).not.toContain('Created content')
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test.each([false, true])(
|
|
|
|
|
'uses the rewritten locale for rendered content and excerpts (render: %s)',
|
|
|
|
|
async (render) => {
|
|
|
|
|
|