feat: add tests to check for changed files (#3893)

* feat: add tests to check for changed files

Make sure that if we are building or generating only files in buildDir and generate.dir are changed. If files in another location would also be changed due to a new config option, those locations should be guarded in lib/common/options so you cant set them lower then rootDir or srcDir.

* fix running tests inBand

use simpler path comparisons

* add debug logs for ci

use process.hrtime for waitFor test

* add debug logs for ci

use process.hrtime for waitFor test

* use writeFileSync should probably help

* use forEach instead of map when not returning a value

update waitFor test to compare values with jest

* fix appeveyor

* use lower limit than delay in waitFor test

revert isAppveyor export
This commit is contained in:
Pim 2018-09-18 16:26:41 +02:00 committed by Sébastien Chopin
parent 2dd2f2aea9
commit 88c9bae57b
8 changed files with 97 additions and 15 deletions

View File

@ -154,6 +154,7 @@
"get-port": "^4.0.0",
"jest": "^23.6.0",
"jsdom": "^12.0.0",
"klaw-sync": "^5.0.0",
"pug": "^2.0.3",
"pug-plain-loader": "^1.0.0",
"puppeteer": "^1.8.0",

View File

@ -1,10 +1,10 @@
import { existsSync } from 'fs'
import { existsSync, writeFileSync } from 'fs'
import http from 'http'
import { resolve } from 'path'
import { remove } from 'fs-extra'
import serveStatic from 'serve-static'
import finalhandler from 'finalhandler'
import { Builder, Generator, getPort, loadFixture, Nuxt, rp } from '../utils'
import { Builder, Generator, getPort, loadFixture, Nuxt, rp, listPaths, equalOrStartsWith } from '../utils'
let port
const url = route => 'http://localhost:' + port + route
@ -13,14 +13,24 @@ const distDir = resolve(rootDir, '.nuxt-generate')
let server = null
let generator = null
let pathsBefore
let changedFileName
describe('basic generate', () => {
beforeAll(async () => {
const config = await loadFixture('basic', { generate: { dir: '.nuxt-generate' } })
const nuxt = new Nuxt(config)
pathsBefore = listPaths(nuxt.options.rootDir)
// Make sure our check for changed files is really working
changedFileName = resolve(nuxt.options.generate.dir, '..', '.nuxt-generate-changed')
nuxt.hook('generate:done', () => {
writeFileSync(changedFileName, '')
})
const builder = new Builder(nuxt)
builder.build = jest.fn()
generator = new Generator(nuxt, builder)
await generator.generate()
@ -43,6 +53,24 @@ describe('basic generate', () => {
expect(generator.nuxt.__hook_ready_called__).toBe(true)
})
test('Check changed files', () => {
// When generating Nuxt we only expect files to change
// within nuxt.options.generate.dir, but also allow other
// .nuxt dirs for when tests are runInBand
const allowChangesDir = resolve(generator.nuxt.options.generate.dir, '..', '.nuxt')
let changedFileFound = false
const paths = listPaths(generator.nuxt.options.rootDir, pathsBefore)
paths.forEach((item) => {
if (item.path === changedFileName) {
changedFileFound = true
} else {
expect(equalOrStartsWith(allowChangesDir, item.path)).toBe(true)
}
})
expect(changedFileFound).toBe(true)
})
test('Format errors', () => {
const error = generator._formatErrors([
{ type: 'handled', route: '/h1', error: 'page not found' },

View File

@ -13,7 +13,7 @@ describe('generator', () => {
const routes = await generator.initRoutes()
expect(routes.length).toBe(array.length)
routes.map((route, index) => {
routes.forEach((route, index) => {
expect(route.route).toBe(array[index])
})
})
@ -32,7 +32,7 @@ describe('generator', () => {
const routes = await generator.initRoutes()
expect(routes.length).toBe(array.length)
routes.map((route, index) => {
routes.forEach((route, index) => {
expect(route.route).toBe(array[index])
})
})
@ -51,7 +51,7 @@ describe('generator', () => {
const routes = await generator.initRoutes(array)
expect(routes.length).toBe(array.length)
routes.map((route, index) => {
routes.forEach((route, index) => {
expect(route.route).toBe(array[index])
})
})
@ -70,7 +70,7 @@ describe('generator', () => {
const routes = await generator.initRoutes(...array)
expect(routes.length).toBe(array.length)
routes.map((route, index) => {
routes.forEach((route, index) => {
expect(route.route).toBe(array[index])
})
})

View File

@ -16,10 +16,15 @@ describe('utils', () => {
expect(ctx.res.b).toBe(2)
})
test.skip.appveyor('waitFor', async () => {
const s = Date.now()
await Utils.waitFor(100)
expect(Date.now() - s >= 100).toBe(true)
test('waitFor', async () => {
const delay = 100
const s = process.hrtime()
await Utils.waitFor(delay)
const t = process.hrtime(s)
// Node.js makes no guarantees about the exact timing of when callbacks will fire
// HTML5 specifies a minimum delay of 4ms for timeouts
// although arbitrary, use this value to determine our lower limit
expect((t[0] * 1e9 + t[1]) / 1e6).not.toBeLessThan(delay - 4)
await Utils.waitFor()
})

View File

@ -1,9 +1,18 @@
import { loadFixture, Nuxt, Builder } from './index'
import { loadFixture, Nuxt, Builder, listPaths, equalOrStartsWith } from './index'
export const buildFixture = function (fixture, callback, hooks = []) {
const pathsBefore = {}
let nuxt
test(`Build ${fixture}`, async () => {
const config = await loadFixture(fixture)
const nuxt = new Nuxt(config)
nuxt = new Nuxt(config)
pathsBefore.root = listPaths(nuxt.options.rootDir)
if (nuxt.options.rootDir !== nuxt.options.srcDir) {
pathsBefore.src = listPaths(nuxt.options.srcDir)
}
const buildDone = jest.fn()
hooks.forEach(([hook, fn]) => nuxt.hook(hook, fn))
nuxt.hook('build:done', buildDone)
@ -15,4 +24,17 @@ export const buildFixture = function (fixture, callback, hooks = []) {
callback(builder)
}
}, 120000)
test('Check changed files', () => {
expect.hasAssertions()
// When building Nuxt we only expect files to changed
// within the nuxt.options.buildDir
Object.keys(pathsBefore).forEach((key) => {
const paths = listPaths(nuxt.options[`${key}Dir`], pathsBefore[key])
paths.forEach((item) => {
expect(equalOrStartsWith(nuxt.options.buildDir, item.path)).toBe(true)
})
})
})
}

View File

@ -1,8 +1,9 @@
import path from 'path'
import fs from 'fs'
import klawSync from 'klaw-sync'
import _getPort from 'get-port'
import { defaultsDeep } from 'lodash'
import { defaultsDeep, find } from 'lodash'
import _rp from 'request-promise-native'
import pkg from '../../package.json'
import _Nuxt from '../../lib/index.js'
@ -51,3 +52,23 @@ export const waitUntil = async function waitUntil(condition, duration = 20, inte
}
return false
}
export const listPaths = function listPaths(dir, pathsBefore = [], options = {}) {
if (Array.isArray(pathsBefore) && pathsBefore.length) {
// only return files that didn't exist before building
// and files that have been changed
options.filter = (item) => {
const foundItem = find(pathsBefore, (itemBefore) => {
return item.path === itemBefore.path
})
return typeof foundItem === 'undefined' ||
item.stats.mtimeMs !== foundItem.stats.mtimeMs
}
}
return klawSync(dir, options)
}
export const equalOrStartsWith = function equalOrStartsWith(string1, string2) {
return string1 === string2 || string2.startsWith(string1)
}

View File

@ -1,4 +1,3 @@
const isAppveyor = !!process.env.APPVEYOR
describe.skip.appveyor = isAppveyor ? describe.skip : describe
test.skip.appveyor = isAppveyor ? test.skip : test

View File

@ -4611,6 +4611,12 @@ kind-of@^6.0.0, kind-of@^6.0.2:
version "6.0.2"
resolved "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051"
klaw-sync@^5.0.0:
version "5.0.0"
resolved "https://registry.npmjs.org/klaw-sync/-/klaw-sync-5.0.0.tgz#b8db1249f96a82751c311ee8a626a319db119904"
dependencies:
graceful-fs "^4.1.11"
kleur@^2.0.1:
version "2.0.2"
resolved "https://registry.npmjs.org/kleur/-/kleur-2.0.2.tgz#b704f4944d95e255d038f0cb05fb8a602c55a300"