Generate ESM Test Diff
9 removals
Lines | |
---|---|
Total | 205 |
Removed | -4.4%9 |
Words | |
Total | 709 |
Removed | -1.3%9 |
205 lines
15 additions
Lines | |
---|---|
Total | 210 |
Added | +6.7%14 |
Words | |
Total | 729 |
Added | +4.0%29 |
210 lines
'use strict'
'use strict'
// bailout if a test is broken
// bailout if a test is broken
// so that the folder can be inspected
// so that the folder can be inspected
process.env.TAP_BAIL = true
process.env.TAP_BAIL = true
const t = require('tap')
const t = require('tap')
const {
const {
mkdirSync,
mkdirSync,
readFileSync,
readFileSync,
readFile,
readFile,
promises: fsPromises,
promises: fsPromises,
unlink
unlink
} = require('fs')
} = require('fs')
const path = require('path')
const path = require('path')
const { promisify } = require('util')
const { promisify } = require('util')
const rimraf = require('rimraf')
const rimraf = require('rimraf')
const walker = require('walker')
const walker = require('walker')
const { generate, javascriptTemplate } = require('../generate')
const { generate, javascriptTemplate } = require('../generate')
const workdir = path.join(__dirname, 'workdir')
const workdir = path.join(__dirname, 'workdir')
const appTemplateDir = path.join(__dirname, '..', 'templates', 'app')
const appTemplateDir = path.join(__dirname, '..', 'templates', 'app-esm')
const cliPkg = require('../package')
const cliPkg = require('../package')
const { exec, execSync } = require('child_process')
const { exec, execSync } = require('child_process')
const pExec = promisify(exec)
const pExec = promisify(exec)
const pUnlink = promisify(unlink)
const pUnlink = promisify(unlink)
const minimatch = require('minimatch')
const minimatch = require('minimatch')
const strip = require('strip-ansi')
const strip = require('strip-ansi')
const expected = {}
const expected = {}
const initVersion = execSync('npm get init-version').toString().trim()
const initVersion = execSync('npm get init-version').toString().trim()
javascriptTemplate.dir = 'app-esm'
javascriptTemplate.type = 'module'
;(function (cb) {
;(function (cb) {
const files = []
const files = []
walker(appTemplateDir)
walker(appTemplateDir)
.on('file', function (file) {
.on('file', function (file) {
files.push(file)
files.push(file)
})
})
.on('end', function () {
.on('end', function () {
let count = 0
let count = 0
files.forEach(function (file) {
files.forEach(function (file) {
readFile(file, function (err, data) {
readFile(file, function (err, data) {
if (err) {
if (err) {
return cb(err)
return cb(err)
}
}
expected[file.replace(appTemplateDir, '').replace(/__/, '.')] = data.toString()
expected[file.replace(appTemplateDir, '').replace(/__/, '.')] = data.toString()
count++
count++
if (count === files.length) {
if (count === files.length) {
cb(null)
cb(null)
}
}
})
})
})
})
})
})
.on('error', cb)
.on('error', cb)
})(function (err) {
})(function (err) {
t.error(err)
t.error(err)
define(t)
define(t)
})
})
function define (t) {
function define (t) {
const { beforeEach, test } = t
const { beforeEach, test } = t
beforeEach(() => {
beforeEach(() => {
rimraf.sync(workdir)
rimraf.sync(workdir)
mkdirSync(workdir, { recursive: true })
mkdirSync(workdir, { recursive: true })
})
})
test('errors if directory exists', (t) => {
test('errors if directory exists', (t) => {
t.plan(2)
t.plan(2)
exec('node generate.js ./test/workdir', (err, stdout) => {
exec('node generate.js ./test/workdir --esm', (err, stdout) => {
t.equal('directory ./test/workdir already exists', strip(stdout.toString().trim()))
t.equal('directory ./test/workdir already exists', strip(stdout.toString().trim()))
t.equal(1, err.code)
t.equal(1, err.code)
})
})
})
})
test('errors if generate doesn\'t have <folder> arguments', (t) => {
test('errors if generate doesn\'t have <folder> arguments', (t) => {
t.plan(2)
t.plan(2)
exec('node generate.js', (err, stdout) => {
exec('node generate.js --esm', (err, stdout) => {
t.equal('must specify a directory to \'fastify generate\'', strip(stdout.toString().trim()))
t.equal('must specify a directory to \'fastify generate\'', strip(stdout.toString().trim()))
t.equal(1, err.code)
t.equal(1, err.code)
})
})
})
})
test('errors if package.json exists when use generate . and integrate flag is not set', (t) => {
test('errors if package.json exists when use generate . and integrate flag is not set', (t) => {
t.plan(2)
t.plan(2)
exec('node generate.js .', (err, stdout) => {
exec('node generate.js . --esm', (err, stdout) => {
t.equal('a package.json file already exists in target directory', strip(stdout.toString().trim()))
t.equal('a package.json file already exists in target directory', strip(stdout.toString().trim()))
t.equal(1, err.code)
t.equal(1, err.code)
})
})
})
})
test('errors if package.json exists when use generate ./ and integrate flag is not set', (t) => {
test('errors if package.json exists when use generate ./ and integrate flag is not set', (t) => {
t.plan(2)
t.plan(2)
exec('node generate.js ./', (err, stdout) => {
exec('node generate.js ./ --esm', (err, stdout) => {
t.equal('a package.json file already exists in target directory', strip(stdout.toString().trim()))
t.equal('a package.json file already exists in target directory', strip(stdout.toString().trim()))
t.equal(1, err.code)
t.equal(1, err.code)
})
})
})
})
test('errors if folder exists', (t) => {
test('errors if folder exists', (t) => {
t.plan(2)
t.plan(2)
exec('node generate.js test', (err, stdout) => {
exec('node generate.js test --esm', (err, stdout) => {
t.equal('directory test already exists', strip(stdout.toString().trim()))
t.equal('directory test already exists', strip(stdout.toString().trim()))
t.equal(1, err.code)
t.equal(1, err.code)
})
})
})
})
test('should finish succesfully with javascript template', async (t) => {
test('should finish successfully with ESM javascript template', async (t) => {
t.plan(14 + Object.keys(expected).length)
t.plan(14 + Object.keys(expected).length)
try {
try {
await generate(workdir, javascriptTemplate)
await generate(workdir, javascriptTemplate)
await verifyPkg(t)
await verifyPkg(t)
await verifyCopy(t, expected)
await verifyCopy(t, expected)
} catch (err) {
} catch (err) {
t.error(err)
t.error(err)
}
}
})
})
test('--integrate option will enhance preexisting package.json and overwrite preexisting files', async (t) => {
test('--integrate option will enhance preexisting package.json and overwrite preexisting files', async (t) => {
t.plan(14 + Object.keys(expected).length)
t.plan(14 + Object.keys(expected).length)
try {
try {
await generate(workdir, javascriptTemplate)
await generate(workdir, javascriptTemplate)
await pUnlink(path.join(workdir, 'package.json'))
await pUnlink(path.join(workdir, 'package.json'))
await pExec('npm init -y', { cwd: workdir })
await pExec('npm init -y', { cwd: workdir })
await pExec('node ../../generate . --integrate', { cwd: workdir })
await pExec('node ../../generate . --integrate --esm', { cwd: workdir })
await verifyPkg(t)
await verifyPkg(t)
await verifyCopy(t, expected)
await verifyCopy(t, expected)
} catch (err) {
} catch (err) {
t.error(err)
t.error(err)
}
}
})
})
test('--standardlint option will add standard lint dependencies and scripts to javascript template', async (t) => {
test('--standardlint option will add standard lint dependencies and scripts to javascript template', async (t) => {
const dir = path.join(__dirname, 'workdir-with-lint')
const dir = path.join(__dirname, 'workdir-with-lint')
const cwd = path.join(dir, '..')
const cwd = path.join(dir, '..')
const bin = path.join('..', 'generate')
const bin = path.join('..', 'generate')
rimraf.sync(dir)
rimraf.sync(dir)
await pExec(`node ${bin} ${dir} --standardlint`, { cwd })
await pExec(`node ${bin} ${dir} --standardlint --esm`, { cwd })
await verifyPkg(t, dir, 'workdir-with-lint')
await verifyPkg(t, dir, 'workdir-with-lint')
const data = await fsPromises.readFile(path.join(dir, 'package.json'))
const data = await fsPromises.readFile(path.join(dir, 'package.json'))
const pkg = JSON.parse(data)
const pkg = JSON.parse(data)
t.equal(pkg.scripts.pretest, 'standard')
t.equal(pkg.scripts.pretest, 'standard')
t.equal(pkg.scripts.lint, 'standard --fix')
t.equal(pkg.scripts.lint, 'standard --fix')
t.equal(pkg.devDependencies.standard, cliPkg.devDependencies.standard)
t.equal(pkg.devDependencies.standard, cliPkg.devDependencies.standard)
})
})
function verifyPkg (t, dir = workdir, pkgName = 'workdir') {
function verifyPkg (t, dir = workdir, pkgName = 'workdir') {
return new Promise((resolve, reject) => {
return new Promise((resolve, reject) => {
const pkgFile = path.join(dir, 'package.json')
const pkgFile = path.join(dir, 'package.json')
readFile(pkgFile, function (err, data) {
readFile(pkgFile, function (err, data) {
err && reject(err)
err && reject(err)
const pkg = JSON.parse(data)
const pkg = JSON.parse(data)
t.equal(pkg.name, pkgName)
t.equal(pkg.name, pkgName)
// we are not checking author because it depends on global npm configs
// we are not checking author because it depends on global npm configs
t.equal(pkg.version, initVersion)
t.equal(pkg.version, initVersion)
t.equal(pkg.description, 'This project was bootstrapped with Fastify-CLI.')
t.equal(pkg.description, 'This project was bootstrapped with Fastify-CLI.')
// by default this will be ISC but since we have a MIT licensed pkg file in upper dir, npm will set the license to MIT in this case
// by default this will be ISC but since we have a MIT licensed pkg file in upper dir, npm will set the license to MIT in this case
// so for local tests we need to accept MIT as well
// so for local tests we need to accept MIT as well
t.ok(pkg.license === 'ISC' || pkg.license === 'MIT')
t.ok(pkg.license === 'ISC' || pkg.license === 'MIT')
t.equal(pkg.scripts.test, 'tap "test/**/*.test.js"')
t.equal(pkg.scripts.test, 'tap "test/**/*.test.js"')
t.equal(pkg.scripts.start, 'fastify start -l info app.js')
t.equal(pkg.scripts.start, 'fastify start -l info app.js')
t.equal(pkg.scripts.dev, 'fastify start -w -l info -P app.js')
t.equal(pkg.scripts.dev, 'fastify start -w -l info -P app.js')
t.equal(pkg.dependencies['fastify-cli'], '^' + cliPkg.version)
t.equal(pkg.dependencies['fastify-cli'], '^' + cliPkg.version)
t.equal(pkg.dependencies.fastify, cliPkg.dependencies.fastify)
t.equal(pkg.dependencies.fastify, cliPkg.dependencies.fastify)
t.equal(pkg.dependencies['fastify-plugin'], cliPkg.devDependencies['fastify-plugin'] || cliPkg.dependencies['fastify-plugin'])
t.equal(pkg.dependencies['fastify-plugin'], cliPkg.devDependencies['fastify-plugin'] || cliPkg.dependencies['fastify-plugin'])
t.equal(pkg.dependencies['@fastify/autoload'], cliPkg.devDependencies['@fastify/autoload'])
t.equal(pkg.dependencies['@fastify/autoload'], cliPkg.devDependencies['@fastify/autoload'])
t.equal(pkg.dependencies['@fastify/sensible'], cliPkg.devDependencies['@fastify/sensible'])
t.equal(pkg.dependencies['@fastify/sensible'], cliPkg.devDependencies['@fastify/sensible'])
t.equal(pkg.devDependencies.tap, cliPkg.devDependencies.tap)
t.equal(pkg.devDependencies.tap, cliPkg.devDependencies.tap)
// Test for "type:module"
t.equal(pkg.type, 'module')
const testGlob = pkg.scripts.test.split(' ')[1].replace(/"/g, '')
const testGlob = pkg.scripts.test.split(' ')[1].replace(/"/g, '')
t.equal(minimatch.match(['test/services/plugins/more/test/here/ok.test.js'], testGlob).length, 1)
t.equal(minimatch.match(['test/services/plugins/more/test/here/ok.test.js'], testGlob).length, 1)
resolve()
resolve()
})
})
})
})
}
}
function verifyCopy (t, expected) {
function verifyCopy (t, expected) {
const pkgFile = path.join(workdir, 'package.json')
const pkgFile = path.join(workdir, 'package.json')
return new Promise((resolve, reject) => {
return new Promise((resolve, reject) => {
walker(workdir)
walker(workdir)
.on('file', function (file) {
.on('file', function (file) {
if (file === pkgFile) {
if (file === pkgFile) {
return
return
}
}
try {
try {
const data = readFileSync(file)
const data = readFileSync(file)
file = file.replace(workdir, '')
file = file.replace(workdir, '')
t.same(data.toString().replace(/\r\n/g, '\n'), expected[file], file + ' matching')
t.same(data.toString().replace(/\r\n/g, '\n'), expected[file], file + ' matching')
} catch (err) {
} catch (err) {
reject(err)
reject(err)
}
}
})
})
.on('end', function () {
.on('end', function () {
resolve()
resolve()
})
})
.on('error', function (err, entry, stat) {
.on('error', function (err, entry, stat) {
reject(err)
reject(err)
})
})
})
})
}
}
}
}