Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Achieve 100% test coverage #370

Merged
merged 22 commits into from
Apr 28, 2024
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
c7ca137
test: should throw an error when trying to load invalid hooks
jean-michelet Mar 11, 2024
40a5a09
test: should throw an error when trying to import hooks plugin using …
jean-michelet Mar 11, 2024
f2954ae
test: Should not accumulate plugin if doesn\'t comply to matchFilter
jean-michelet Mar 15, 2024
a8165e2
Should not accumulate plugin if ignoreFilter is matched
jean-michelet Mar 15, 2024
6a2a6be
Should be able to filter paths using string
jean-michelet Mar 15, 2024
8e8b07f
Should be able to filter paths using a function
jean-michelet Mar 15, 2024
9a688cd
should not set skip-override if hook plugin is not a function or asyn…
jean-michelet Mar 15, 2024
c01e74d
test: Should not enrich non-SyntaxError
jean-michelet Mar 16, 2024
c2a7589
test: should not fail if argv and execArgv are falsy
jean-michelet Mar 16, 2024
461ea4d
test: ignore code coverage for OS specific cwd management
jean-michelet Mar 16, 2024
d8f6d4a
refactor: rename fixture folders
jean-michelet Mar 16, 2024
fc1e47b
refactor: remove useless files in fixtures
jean-michelet Mar 16, 2024
cff2fbb
refactor: enforce 100% code coverage
jean-michelet Mar 16, 2024
559a17e
fix: revert changes in package.json
jean-michelet Mar 16, 2024
0351c42
fix: add needed blank line at end of fixture files
jean-michelet Mar 16, 2024
ce5ac35
fix: remove obsolet commented code
jean-michelet Mar 16, 2024
5293112
fix: ignore execArgv and process.args branches
jean-michelet Mar 18, 2024
e73b30d
fix: remove Logical condition on process.execArgv and arg
jean-michelet Apr 19, 2024
d287097
fix: add tsx --import flag for node >= 18
jean-michelet Apr 20, 2024
882b01e
fix: invalid hooks test, replace fixture identifier parsing error by …
jean-michelet Apr 20, 2024
2dfa3c8
fix: remove Extra semicolon
jean-michelet Apr 21, 2024
1f1c797
test: ignore OS specific branche evaluation
jean-michelet Apr 21, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .taprc
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
ts: true
jsx: false
flow: false
coverage: true
check-coverage: false
15 changes: 7 additions & 8 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ const { pathToFileURL } = require('node:url')

const isFastifyAutoloadTypescriptOverride = !!process.env.FASTIFY_AUTOLOAD_TYPESCRIPT
const isTsNode = (Symbol.for('ts-node.register.instance') in process) || !!process.env.TS_NODE_DEV
const isBabelNode = (process?.execArgv || []).concat(process?.argv || []).some((arg) => arg.indexOf('babel-node') >= 0)
const isBabelNode = (/* istanbul ignore next */process.execArgv || [])
.concat(/* istanbul ignore next */process.argv || [])
.some((arg) => arg.indexOf('babel-node') >= 0)

const isVitestEnvironment = process.env.VITEST === 'true' || process.env.VITEST_WORKER_ID !== undefined
const isJestEnvironment = process.env.JEST_WORKER_ID !== undefined
Expand Down Expand Up @@ -72,12 +74,9 @@ const fastifyAutoload = async function autoload (fastify, options) {
}

await Promise.all(hookArray.map((h) => {
if (hooksMeta[h.file]) return null // hook plugin already loaded, skip this instance
return loadHook(h, opts)
.then((hookPlugin) => {
if (hookPlugin) {
hooksMeta[h.file] = hookPlugin
}
hooksMeta[h.file] = hookPlugin
})
.catch((err) => {
throw enrichError(err)
Expand All @@ -96,7 +95,7 @@ const fastifyAutoload = async function autoload (fastify, options) {
for (const hookFile of hookFiles) {
const hookPlugin = hooksMeta[hookFile.file]
// encapsulate hooks at plugin level
if (hookPlugin) app.register(hookPlugin)
app.register(hookPlugin)
}
registerAllPlugins(app, pluginFiles)
}
Expand All @@ -118,7 +117,7 @@ async function getPackageType (cwd) {
const directories = cwd.split(sep)

// required for paths that begin with the sep, such as linux root
directories[0] = directories[0] !== '' ? directories[0] : sep
directories[0] = /* istanbul ignore next */ directories[0] !== '' ? directories[0] : sep

while (directories.length > 0) {
const filePath = join(...directories, 'package.json')
Expand Down Expand Up @@ -409,7 +408,6 @@ function wrapRoutes (content) {
}

async function loadHook (hook, options) {
if (!hook) return null
let hookContent
if (options.forceESM || hook.type === 'module' || forceESMEnvironment) {
hookContent = await import(pathToFileURL(hook.file).href)
Expand All @@ -436,6 +434,7 @@ function enrichError (err) {
if (err instanceof SyntaxError) {
err.message += ' at ' + err.stack.split('\n', 1)[0]
}

return err
}

Expand Down
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"typescript:vitest": "vitest run",
"typescript:vitest:dev": "vitest",
"unit": "node scripts/unit.js",
"unit:with-modules": "tap test/commonjs/*.js test/module/*.js test/typescript/*.ts"
"unit:with-modules": "tap test/issues/*/test.js test/commonjs/*.js test/module/*.js test/typescript/*.ts"
},
"repository": {
"type": "git",
Expand All @@ -43,6 +43,7 @@
"url": "https://github.com/fastify/fastify-autoload/issues"
},
"homepage": "https://github.com/fastify/fastify-autoload#readme",
"dependencies": {},
"devDependencies": {
"@fastify/pre-commit": "^2.0.2",
"@fastify/url-data": "^5.0.0",
Expand All @@ -52,6 +53,8 @@
"@types/jest": "^29.0.0",
"@types/node": "^20.1.0",
"@types/tap": "^15.0.5",
"esbuild": "^0.19.2",
"esbuild-register": "^3.4.1",
"fastify": "^4.0.0-rc.2",
"fastify-plugin": "^4.0.0",
"jest": "^28.1.3",
Expand All @@ -65,12 +68,9 @@
"tsm": "^2.2.1",
"tsx": "^3.7.1",
"typescript": "^5.0.2",
"esbuild": "^0.19.2",
"esbuild-register": "^3.4.1",
"vite": "^5.0.0",
"vitest": "^0.34.1"
},
"dependencies": {},
"standard": {
"ignore": [
"test/*/*-error/lib/a.js"
Expand Down
1 change: 1 addition & 0 deletions test/issues/369/invalid-autohooks/.autohooks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This is not valid JS code...
Empty file.
1 change: 1 addition & 0 deletions test/issues/369/non-SyntaxError/.autohooks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
x
8 changes: 8 additions & 0 deletions test/issues/369/routes/.autohooks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
'use strict'

module.exports = async function (app, opts) {
app.addHook('onRequest', async (req, reply) => {
req.hooked = req.hooked || []
req.hooked.push('root')
})
}
8 changes: 8 additions & 0 deletions test/issues/369/routes/child/.autohooks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
'use strict'

module.exports = async function (app, opts) {
app.addHook('onRequest', async (req, reply) => {
req.hooked = req.hooked || []
req.hooked.push('child')
})
}
7 changes: 7 additions & 0 deletions test/issues/369/routes/child/routes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
'use strict'

module.exports = async function (app, opts, next) {
app.get('/', async function (req, reply) {
reply.status(200).send({ hooked: req.hooked })
})
}
10 changes: 10 additions & 0 deletions test/issues/369/routes/promisified/.autohooks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
'use strict'

module.exports = new Promise((res) => {
res(async function (app, opts) {
app.addHook('onRequest', async (req, reply) => {
req.hooked = req.hooked || []
req.hooked.push('promisified')
})
})
})
7 changes: 7 additions & 0 deletions test/issues/369/routes/promisified/routes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
'use strict'

module.exports = async function (app, opts, next) {
app.get('/', async function (req, reply) {
reply.status(200).send({ hooked: req.hooked })
})
}
7 changes: 7 additions & 0 deletions test/issues/369/routes/routes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
'use strict'

module.exports = async function (app, opts, next) {
app.get('/', async function (req, reply) {
reply.status(200).send({ hooked: req.hooked })
})
}
183 changes: 183 additions & 0 deletions test/issues/369/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
'use strict'

const { test } = require('tap')
const Fastify = require('fastify')
const path = require('path')
const autoload = require('../../..')

test('Should throw an error when trying to load invalid hooks', async (t) => {
const app = Fastify()
app.register(autoload, {
dir: path.join(__dirname, 'invalid-autohooks'),
autoHooks: true
})

await t.rejects(app.ready(), new SyntaxError(`Unexpected identifier at ${path.join(__dirname, 'invalid-autohooks/.autohooks.js')}:1`))
})

test('Should throw an error when trying to import hooks plugin using index.ts if typescriptSupport is not enabled', async (t) => {
const app = Fastify()
app.register(autoload, {
dir: path.join(__dirname, 'invalid-index-type'),
autoHooks: true
})

await t.rejects(app.ready(), new Error(`@fastify/autoload cannot import hooks plugin at '${path.join(__dirname, 'invalid-index-type/index.ts')}'. To fix this error compile TypeScript to JavaScript or use 'ts-node' to run your app.`))
})

test('Should not accumulate plugin if doesn\'t comply to matchFilter', async (t) => {
const app = Fastify()
app.register(autoload, {
dir: path.join(__dirname, 'routes')
})

await app.ready()

const res = await app.inject({
url: '/'
})

t.equal(res.statusCode, 200)

const app2 = Fastify()
app2.register(autoload, {
dir: path.join(__dirname, 'routes'),
matchFilter: /invalid/
})

await app2.ready()

const res2 = await app2.inject({
url: '/'
})

t.equal(res2.statusCode, 404)
})

test('Should be able to filter paths using a string', async (t) => {
const app = Fastify()
app.register(autoload, {
dir: path.join(__dirname, 'routes'),
matchFilter: 'routes.js'
})

await app.ready()

const res = await app.inject({
url: '/'
})

t.equal(res.statusCode, 200)

const app2 = Fastify()
app2.register(autoload, {
dir: path.join(__dirname, 'routes'),
matchFilter: 'invalid-path'
})

await app2.ready()

const res2 = await app2.inject({
url: '/'
})

t.equal(res2.statusCode, 404)
})

test('Should be able to filter paths using a function', async (t) => {
const app = Fastify()
app.register(autoload, {
dir: path.join(__dirname, 'routes'),
matchFilter: (path) => path.includes('routes.js')
})

await app.ready()

const res = await app.inject({
url: '/'
})

t.equal(res.statusCode, 200)

const app2 = Fastify()
app2.register(autoload, {
dir: path.join(__dirname, 'routes'),
matchFilter: (path) => path.includes('invalid-path')
})

await app2.ready()

const res2 = await app2.inject({
url: '/'
})

t.equal(res2.statusCode, 404)
})

test('Should not accumulate plugin if ignoreFilter is matched', async (t) => {
const app = Fastify()
app.register(autoload, {
dir: path.join(__dirname, 'routes'),
ignoreFilter: /\/not-exists.js/
})

await app.ready()

const res = await app.inject({
url: '/'
})

t.equal(res.statusCode, 200)

const app2 = Fastify()
app2.register(autoload, {
dir: path.join(__dirname, 'routes'),
ignoreFilter: /\/routes.js/,
autoHooks: true
})

await app2.ready()

const res2 = await app2.inject({
url: '/'
})

t.equal(res2.statusCode, 404)
})

test('Should not set skip-override if hook plugin is not a function or async function', async (t) => {
const app = Fastify()
app.register(autoload, {
dir: path.join(__dirname, 'routes'),
autoHooks: true,
cascadeHooks: true
})

app.decorateRequest('hooked', '')

await app.ready()

const res = await app.inject({
url: '/child'
})

t.equal(res.statusCode, 200)
t.same(JSON.parse(res.payload), { hooked: ['root', 'child'] })

const res2 = await app.inject({
url: '/promisified'
})

t.equal(res2.statusCode, 200)
t.same(JSON.parse(res2.payload), { hooked: ['root'] })
})

test('Should not enrich non-SyntaxError', async (t) => {
const app = Fastify()
app.register(autoload, {
dir: path.join(__dirname, 'non-SyntaxError'),
autoHooks: true
})

t.rejects(app.ready(), new ReferenceError('x is not defined'))
})
Loading