Skip to content

Commit

Permalink
test: adds basic test for metalsmith watcher
Browse files Browse the repository at this point in the history
  • Loading branch information
webketje authored and Kevin Van Lierde committed Jun 28, 2023
1 parent 5a516b2 commit 629516e
Show file tree
Hide file tree
Showing 7 changed files with 194 additions and 0 deletions.
Empty file.
Empty file.
Empty file.
Empty file added test/fixtures/watch/src/change
Empty file.
Empty file.
Empty file added test/fixtures/watch/src/remove
Empty file.
194 changes: 194 additions & 0 deletions test/watcher.js
@@ -0,0 +1,194 @@
/* eslint-env node, mocha */

const { writeFile, rename } = require('fs/promises')
const assert = require('assert')
const path = require('path')
const { rm } = require('../lib/helpers')
const Metalsmith = require('..')
const fixture = path.resolve.bind(path, __dirname, 'fixtures')
const { platform } = require('os')

const initialFiles = ['change', 'dir/file', 'remove'].map(path.normalize)

const defaultWatchOpts = {
alwaysStat: false,
awaitWriteFinish: false,
cwd: fixture('watch'),
ignoreInitial: true,
ignored: [],
paths: fixture('watch/src')
}

describe('watcher', function () {
let initialBuild = true

this.timeout(5000)
this.beforeEach(() => {
initialBuild = true
})
this.afterEach(async () => {
return Metalsmith(fixture('watch')).source('contents').destination('src').clean(true).build()
})

it('should set proper default options according to metalsmith config', function () {
const ms = Metalsmith(fixture('watch'))
ms.watch(true)

assert.deepStrictEqual(ms.watch(), defaultWatchOpts)
})

it("should take into account metalsmith.ignore'd paths", function () {
const ms = Metalsmith(fixture('watch'))
ms.ignore('ignored')
ms.watch(true)

assert.deepStrictEqual(ms.watch(), { ...defaultWatchOpts, ignored: ['ignored'] })
})

it('should detect added files', async function () {
const addFile = async () => await writeFile(path.join(fixture('watch/src'), 'added'), '')
const ms = Metalsmith(fixture('watch'))

return new Promise((resolve, reject) => {
ms.watch(true).build((err, files) => {
if (err) reject(err)
else {
if (initialBuild) {
initialBuild = false
addFile()
// this will only trigger if the if clause succeeds in triggering the chokidar watcher
} else {
ms.watch(false)
try {
assert.deepStrictEqual(Object.keys(files), [...initialFiles, 'added'])
resolve()
} catch (err) {
reject(err)
}
}
}
})
})
})

it('should detect removed files', async function () {
const remove = async () => await rm(path.join(fixture('watch/src'), 'remove'))
const ms = Metalsmith(fixture('watch'))

return new Promise((resolve, reject) => {
ms.watch(true).build((err, files) => {
if (err) reject(err)
else {
if (initialBuild) {
initialBuild = false
remove()
// this will only trigger if the if clause succeeds in triggering the chokidar watcher
} else {
ms.watch(false)
try {
assert.deepStrictEqual(Object.keys(files), initialFiles.slice(0, 2))
resolve()
} catch (err) {
reject(err)
}
}
}
})
})
})

it('should detect changed files', async function () {
const change = async () => await writeFile(path.join(fixture('watch/src'), 'change'), 'body')
const ms = Metalsmith(fixture('watch'))

return new Promise((resolve, reject) => {
ms.watch(true).build((err, files) => {
if (err) reject(err)
else {
if (initialBuild) {
initialBuild = false
change()
// this will only trigger if the if clause succeeds in triggering the chokidar watcher
} else {
ms.watch(false)
try {
assert.strictEqual(files['change'].contents.toString(), 'body')
resolve()
} catch (err) {
reject(err)
}
}
}
})
})
})

it('should detect moved files', async function () {
const change = async () =>
await rename(path.join(fixture('watch/src'), 'change'), path.join(fixture('watch/src'), 'renamed'))
const ms = Metalsmith(fixture('watch'))
initialBuild = 0

return new Promise((resolve, reject) => {
ms.watch(true).build((err, files) => {
if (err) reject(err)
else {
initialBuild += 1
if (initialBuild === 1) {
change()
// this will only trigger if the if clause succeeds in triggering the chokidar watcher
} else {
if (initialBuild === 3) {
ms.watch(false)
try {
assert.deepStrictEqual(Object.keys(files), initialFiles.slice(1).concat(['renamed']))
resolve()
} catch (err) {
reject(err)
}
}
}
}
})
})
})

it('should graciously batch file ops', async function () {
const batch = async () => {
rename(path.join(fixture('watch/src'), 'change'), path.join(fixture('watch/src'), 'renamed'))
writeFile(path.join(fixture('watch/src'), 'added'), 'body')
rm(path.join(fixture('watch/src'), 'remove'))
}
const ms = Metalsmith(fixture('watch'))
// windows file watchers are apparently slower, triggering an extra run
const lastBuild = platform() === 'win32' ? 4 : 3
initialBuild = 0

return new Promise((resolve, reject) => {
ms.watch(true).build(async (err, files) => {
if (err) reject(err)
else {
initialBuild += 1
if (initialBuild === 1) {
await batch()
// this will only trigger if the if clause succeeds in triggering the chokidar watcher
} else {
if (initialBuild === lastBuild) {
ms.watch(false)
try {
// doing the sort here because the order of execution of the batch is not guaranteed
assert.deepStrictEqual(
Object.keys(files).sort(),
initialFiles.slice(1, 2).concat(['added', 'renamed']).sort()
)
resolve()
} catch (err) {
reject(err)
}
}
}
}
})
})
})
})

0 comments on commit 629516e

Please sign in to comment.