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

File tree

19 files changed

+729
-861
lines changed

19 files changed

+729
-861
lines changed

‎lib/commands/completion.js‎

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,26 @@
2929
// as an array.
3030
//
3131

32+
constfs=require('@npmcli/fs')
33+
constnopt=require('nopt')
34+
3235
const{ definitions, shorthands }=require('../utils/config/index.js')
3336
const{ aliases, cmdList, plumbing }=require('../utils/cmd-list.js')
3437
constaliasNames=Object.keys(aliases)
3538
constfullList=cmdList.concat(aliasNames).filter(c=>!plumbing.includes(c))
36-
constnopt=require('nopt')
3739
constconfigNames=Object.keys(definitions)
3840
constshorthandNames=Object.keys(shorthands)
3941
constallConfs=configNames.concat(shorthandNames)
4042
const{ isWindowsShell }=require('../utils/is-windows.js')
41-
constfileExists=require('../utils/file-exists.js')
43+
constfileExists=async(file)=>{
44+
try{
45+
conststat=awaitfs.stat(file)
46+
returnstat.isFile()
47+
}catch{
48+
returnfalse
49+
}
50+
}
4251

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

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

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

197-
constd=(awaitreadFile(p,'utf8')).replace(/^#!.*?\n/,'')
203+
constd=(awaitfs.readFile(p,'utf8')).replace(/^#!.*?\n/,'')
198204
awaitnewPromise((res,rej)=>{
199205
letdone=false
200206
process.stdout.on('error',er=>{

‎lib/commands/search.js‎

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,33 @@ const Pipeline = require('minipass-pipeline')
33
constlibSearch=require('libnpmsearch')
44
constlog=require('../utils/log-shim.js')
55

6-
constformatPackageStream=require('../search/format-package-stream.js')
7-
constpackageFilter=require('../search/package-filter.js')
6+
constformatSearchStream=require('../utils/format-search-stream.js')
7+
8+
functionfilter(data,include,exclude){
9+
constwords=[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+
returnfalse
19+
}
820

9-
functionprepareIncludes(args){
10-
returnargs
11-
.map(s=>s.toLowerCase())
12-
.filter(s=>s)
21+
returntrue
1322
}
1423

15-
functionprepareExcludes(searchexclude){
16-
varexclude
17-
if(typeofsearchexclude==='string'){
18-
exclude=searchexclude.split(/\s+/)
19-
}else{
20-
exclude=[]
24+
functionmatch(words,pattern){
25+
if(pattern.startsWith('/')){
26+
if(pattern.endsWith('/')){
27+
pattern=pattern.slice(0,-1)
28+
}
29+
pattern=newRegExp(pattern.slice(1))
30+
returnwords.match(pattern)
2131
}
22-
23-
returnexclude
24-
.map(s=>s.toLowerCase())
25-
.filter(s=>s)
32+
returnwords.indexOf(pattern)!==-1
2633
}
2734

2835
constBaseCommand=require('../base-command.js')
@@ -50,8 +57,8 @@ class Search extends BaseCommand{
5057
constopts={
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
classFilterStreamextendsMinipass{
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-
constoutputStream=formatPackageStream({
83+
constoutputStream=formatSearchStream({
7784
args,// --searchinclude options are not highlighted
7885
...opts,
7986
})

‎lib/commands/view.js‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,6 @@ class View extends BaseCommand{
5757

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

‎lib/search/package-filter.js‎

Lines changed: 0 additions & 43 deletions
This file was deleted.

‎lib/utils/config/definitions.js‎

Lines changed: 1 addition & 1 deletion
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‎

Lines changed: 0 additions & 10 deletions
This file was deleted.

‎lib/utils/format-bytes.js‎

Lines changed: 1 addition & 0 deletions
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

Lines changed: 17 additions & 49 deletions
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
constMinipass=require('minipass')
52
constcolumnify=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 ? newJSONOutputStream() : newTextOutputStream(opts)
18+
module.exports=(opts)=>{
19+
returnopts.json ? newJSONOutputStream() : newTextOutputStream(opts)
20+
}
2321

2422
classJSONOutputStreamextendsMinipass{
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-
returnsuper.write(JSON.stringify(obj))
40-
}catch(er){
41-
returnthis.emit('error',er)
42-
}
33+
returnsuper.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
functionprettify(data,num,opts){
64-
opts=opts||{}
6555
vartruncate=!opts.long
6656

6757
varpkg=normalizePackage(data,opts)
6858

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

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

79-
varoutput=columnify(
67+
// stdout in tap is never a tty
68+
/* istanbul ignore next */
69+
constmaxWidth=process.stdout.isTTY ? process.stdout.getWindowSize()[0] : Infinity
70+
letoutput=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
returnline.split('\u0000').join(uncolor)
141132
}
142133

143-
functiongetMaxWidth(){
144-
varcols
145-
try{
146-
vartty=require('tty')
147-
varstdout=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-
returncols
154-
}
155-
156-
functiontrimToMaxWidth(str){
157-
varmaxWidth=getMaxWidth()
158-
returnstr.split('\n').map(function(line){
159-
returnline.slice(0,maxWidth)
160-
}).join('\n')
161-
}
162-
163134
functionhighlightSearchTerms(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
functionnormalizePackage(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
: typeofdata.keywords==='string'

‎lib/utils/read-package-name.js‎

Lines changed: 0 additions & 9 deletions
This file was deleted.

‎package.json‎

Lines changed: 7 additions & 2 deletions
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)