Skip to content

Commit 48d2db6

Browse files
authored
fix: remove test coverage map (#4862)
Turns out there were three files that still had no test coverage because of the combination of the mocks in tests and the coverage map. Removing the map altogether exposed them. This PR removes the coverage map and fixes test to cover all lines that were being missed. While adding coverage to the `npm search` codebase multiple unneeded guards and at least one bug was found (it was impossible to exclude searches based on username). These were fixed. The `npm view` tests were also refactored to use the real npm object. Finally, a small inlining of lib/utils/file-exists.js was done.
1 parent 8e7ea9b commit 48d2db6

19 files changed

+729
-861
lines changed

lib/commands/completion.js

+12-6
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,26 @@
2929
// as an array.
3030
//
3131

32+
const fs = require('@npmcli/fs')
33+
const nopt = require('nopt')
34+
3235
const { definitions, shorthands } = require('../utils/config/index.js')
3336
const { aliases, cmdList, plumbing } = require('../utils/cmd-list.js')
3437
const aliasNames = Object.keys(aliases)
3538
const fullList = cmdList.concat(aliasNames).filter(c => !plumbing.includes(c))
36-
const nopt = require('nopt')
3739
const configNames = Object.keys(definitions)
3840
const shorthandNames = Object.keys(shorthands)
3941
const allConfs = configNames.concat(shorthandNames)
4042
const { isWindowsShell } = require('../utils/is-windows.js')
41-
const fileExists = require('../utils/file-exists.js')
43+
const fileExists = async (file) => {
44+
try {
45+
const stat = await fs.stat(file)
46+
return stat.isFile()
47+
} catch {
48+
return false
49+
}
50+
}
4251

43-
const { promisify } = require('util')
4452
const BaseCommand = require('../base-command.js')
4553

4654
class Completion extends BaseCommand {
@@ -189,12 +197,10 @@ class Completion extends BaseCommand {
189197
}
190198

191199
const dumpScript = async () => {
192-
const fs = require('fs')
193-
const readFile = promisify(fs.readFile)
194200
const { resolve } = require('path')
195201
const p = resolve(__dirname, '..', 'utils', 'completion.sh')
196202

197-
const d = (await readFile(p, 'utf8')).replace(/^#!.*?\n/, '')
203+
const d = (await fs.readFile(p, 'utf8')).replace(/^#!.*?\n/, '')
198204
await new Promise((res, rej) => {
199205
let done = false
200206
process.stdout.on('error', er => {

lib/commands/search.js

+27-20
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,33 @@ const Pipeline = require('minipass-pipeline')
33
const libSearch = require('libnpmsearch')
44
const log = require('../utils/log-shim.js')
55

6-
const formatPackageStream = require('../search/format-package-stream.js')
7-
const packageFilter = require('../search/package-filter.js')
6+
const formatSearchStream = require('../utils/format-search-stream.js')
7+
8+
function filter (data, include, exclude) {
9+
const words = [data.name]
10+
.concat(data.maintainers.map(m => `=${m.username}`))
11+
.concat(data.keywords || [])
12+
.map(f => f && f.trim && f.trim())
13+
.filter(f => f)
14+
.join(' ')
15+
.toLowerCase()
16+
17+
if (exclude.find(e => match(words, e))) {
18+
return false
19+
}
820

9-
function prepareIncludes (args) {
10-
return args
11-
.map(s => s.toLowerCase())
12-
.filter(s => s)
21+
return true
1322
}
1423

15-
function prepareExcludes (searchexclude) {
16-
var exclude
17-
if (typeof searchexclude === 'string') {
18-
exclude = searchexclude.split(/\s+/)
19-
} else {
20-
exclude = []
24+
function match (words, pattern) {
25+
if (pattern.startsWith('/')) {
26+
if (pattern.endsWith('/')) {
27+
pattern = pattern.slice(0, -1)
28+
}
29+
pattern = new RegExp(pattern.slice(1))
30+
return words.match(pattern)
2131
}
22-
23-
return exclude
24-
.map(s => s.toLowerCase())
25-
.filter(s => s)
32+
return words.indexOf(pattern) !== -1
2633
}
2734

2835
const BaseCommand = require('../base-command.js')
@@ -50,8 +57,8 @@ class Search extends BaseCommand {
5057
const opts = {
5158
...this.npm.flatOptions,
5259
...this.npm.flatOptions.search,
53-
include: prepareIncludes(args),
54-
exclude: prepareExcludes(this.npm.flatOptions.search.exclude),
60+
include: args.map(s => s.toLowerCase()).filter(s => s),
61+
exclude: this.npm.flatOptions.search.exclude.split(/\s+/),
5562
}
5663

5764
if (opts.include.length === 0) {
@@ -63,7 +70,7 @@ class Search extends BaseCommand {
6370

6471
class FilterStream extends Minipass {
6572
write (pkg) {
66-
if (packageFilter(pkg, opts.include, opts.exclude)) {
73+
if (filter(pkg, opts.include, opts.exclude)) {
6774
super.write(pkg)
6875
}
6976
}
@@ -73,7 +80,7 @@ class Search extends BaseCommand {
7380

7481
// Grab a configured output stream that will spit out packages in the
7582
// desired format.
76-
const outputStream = formatPackageStream({
83+
const outputStream = formatSearchStream({
7784
args, // --searchinclude options are not highlighted
7885
...opts,
7986
})

lib/commands/view.js

-3
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,6 @@ class View extends BaseCommand {
5757

5858
function getFields (d, f, pref) {
5959
f = f || []
60-
if (!d) {
61-
return f
62-
}
6360
pref = pref || []
6461
Object.keys(d).forEach((k) => {
6562
if (k.charAt(0) === '_' || k.indexOf('.') !== -1) {

lib/search/package-filter.js

-43
This file was deleted.

lib/utils/config/definitions.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1856,7 +1856,7 @@ define('searchexclude', {
18561856
`,
18571857
flatten (key, obj, flatOptions) {
18581858
flatOptions.search = flatOptions.search || { limit: 20 }
1859-
flatOptions.search.exclude = obj[key]
1859+
flatOptions.search.exclude = obj[key].toLowerCase()
18601860
},
18611861
})
18621862

lib/utils/file-exists.js

-10
This file was deleted.

lib/utils/format-bytes.js

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ const formatBytes = (bytes, space = true) => {
2323
return `${(bytes / 1000000).toFixed(1)}${spacer}MB`
2424
}
2525

26+
// GB
2627
return `${(bytes / 1000000000).toFixed(1)}${spacer}GB`
2728
}
2829

lib/search/format-package-stream.js renamed to lib/utils/format-search-stream.js

+17-49
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
// XXX these output classes should not live in here forever. it'd be good to
2-
// split them out, perhaps to libnpmsearch
3-
41
const Minipass = require('minipass')
52
const columnify = require('columnify')
63

@@ -18,32 +15,26 @@ const columnify = require('columnify')
1815
// The returned stream will format this package data
1916
// into a byte stream of formatted, displayable output.
2017

21-
module.exports = (opts = {}) =>
22-
opts.json ? new JSONOutputStream() : new TextOutputStream(opts)
18+
module.exports = (opts) => {
19+
return opts.json ? new JSONOutputStream() : new TextOutputStream(opts)
20+
}
2321

2422
class JSONOutputStream extends Minipass {
25-
constructor () {
26-
super()
27-
this._didFirst = false
28-
}
23+
#didFirst = false
2924

3025
write (obj) {
31-
if (!this._didFirst) {
26+
if (!this.#didFirst) {
3227
super.write('[\n')
33-
this._didFirst = true
28+
this.#didFirst = true
3429
} else {
3530
super.write('\n,\n')
3631
}
3732

38-
try {
39-
return super.write(JSON.stringify(obj))
40-
} catch (er) {
41-
return this.emit('error', er)
42-
}
33+
return super.write(JSON.stringify(obj))
4334
}
4435

4536
end () {
46-
super.write(this._didFirst ? ']\n' : '\n[]\n')
37+
super.write(this.#didFirst ? ']\n' : '\n[]\n')
4738
super.end()
4839
}
4940
}
@@ -61,22 +52,22 @@ class TextOutputStream extends Minipass {
6152
}
6253

6354
function prettify (data, num, opts) {
64-
opts = opts || {}
6555
var truncate = !opts.long
6656

6757
var pkg = normalizePackage(data, opts)
6858

69-
var columns = opts.description
70-
? ['name', 'description', 'author', 'date', 'version', 'keywords']
71-
: ['name', 'author', 'date', 'version', 'keywords']
59+
var columns = ['name', 'description', 'author', 'date', 'version', 'keywords']
7260

7361
if (opts.parseable) {
7462
return columns.map(function (col) {
7563
return pkg[col] && ('' + pkg[col]).replace(/\t/g, ' ')
7664
}).join('\t')
7765
}
7866

79-
var output = columnify(
67+
// stdout in tap is never a tty
68+
/* istanbul ignore next */
69+
const maxWidth = process.stdout.isTTY ? process.stdout.getWindowSize()[0] : Infinity
70+
let output = columnify(
8071
[pkg],
8172
{
8273
include: columns,
@@ -92,8 +83,8 @@ function prettify (data, num, opts) {
9283
keywords: { maxWidth: Infinity },
9384
},
9485
}
95-
)
96-
output = trimToMaxWidth(output)
86+
).split('\n').map(line => line.slice(0, maxWidth)).join('\n')
87+
9788
if (opts.color) {
9889
output = highlightSearchTerms(output, opts.args)
9990
}
@@ -140,26 +131,6 @@ function colorize (line) {
140131
return line.split('\u0000').join(uncolor)
141132
}
142133

143-
function getMaxWidth () {
144-
var cols
145-
try {
146-
var tty = require('tty')
147-
var stdout = process.stdout
148-
cols = !tty.isatty(stdout.fd) ? Infinity : process.stdout.getWindowSize()[0]
149-
cols = (cols === 0) ? Infinity : cols
150-
} catch (ex) {
151-
cols = Infinity
152-
}
153-
return cols
154-
}
155-
156-
function trimToMaxWidth (str) {
157-
var maxWidth = getMaxWidth()
158-
return str.split('\n').map(function (line) {
159-
return line.slice(0, maxWidth)
160-
}).join('\n')
161-
}
162-
163134
function highlightSearchTerms (str, terms) {
164135
terms.forEach(function (arg, i) {
165136
str = addColorMarker(str, arg, i)
@@ -169,13 +140,10 @@ function highlightSearchTerms (str, terms) {
169140
}
170141

171142
function normalizePackage (data, opts) {
172-
opts = opts || {}
173143
return {
174144
name: data.name,
175-
description: opts.description ? data.description : '',
176-
author: (data.maintainers || []).map(function (m) {
177-
return '=' + m.username
178-
}).join(' '),
145+
description: data.description,
146+
author: data.maintainers.map((m) => `=${m.username}`).join(' '),
179147
keywords: Array.isArray(data.keywords)
180148
? data.keywords.join(' ')
181149
: typeof data.keywords === 'string'

lib/utils/read-package-name.js

-9
This file was deleted.

package.json

+7-2
Original file line numberDiff line numberDiff line change
@@ -230,8 +230,13 @@
230230
],
231231
"color": 1,
232232
"files": "test/{lib,bin,index.js}",
233-
"coverage-map": "test/coverage-map.js",
234-
"timeout": 600
233+
"timeout": 600,
234+
"nyc-arg": [
235+
"--exclude",
236+
"workspaces/**",
237+
"--exclude",
238+
"tap-snapshots/**"
239+
]
235240
},
236241
"templateOSS": {
237242
"rootRepo": false,

0 commit comments

Comments
 (0)