You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

202 lines
4.6 KiB

var path = require('path')
var mkdirp = require('mkdirp')
var mr = require('npm-registry-mock')
var osenv = require('osenv')
var rimraf = require('rimraf')
var cacheFile = require('npm-cache-filename')
var test = require('tap').test
var Tacks = require('tacks')
var File = Tacks.File
var common = require('../common-tap.js')
var PKG_DIR = path.resolve(__dirname, 'search')
var CACHE_DIR = path.resolve(PKG_DIR, 'cache')
var cacheBase = cacheFile(CACHE_DIR)(common.registry + '/-/all')
var cachePath = path.join(cacheBase, '.cache.json')
var server
test('setup', function (t) {
mr({port: common.port, throwOnUnmatched: true}, function (err, s) {
t.ifError(err, 'registry mocked successfully')
server = s
t.pass('all set up')
t.done()
})
})
var searches = [
{
term: 'cool',
description: 'non-regex search',
location: 103
},
{
term: '/cool/',
description: 'regex search',
location: 103
},
{
term: 'cool',
description: 'searches name field',
location: 103
},
{
term: 'ool',
description: 'excludes matches for --searchexclude',
location: 205,
inject: {
other: { name: 'other', description: 'this is a simple tool' }
},
extraOpts: ['--searchexclude', 'cool']
},
{
term: 'neat lib',
description: 'searches description field',
location: 141,
inject: {
cool: {
name: 'cool', version: '5.0.0', description: 'this is a neat lib'
}
}
},
{
term: 'foo',
description: 'skips description field with --no-description',
location: 80,
inject: {
cool: {
name: 'cool', version: '5.0.0', description: 'foo bar!'
}
},
extraOpts: ['--no-description']
},
{
term: 'zkat',
description: 'searches maintainers by name',
location: 155,
inject: {
cool: {
name: 'cool',
version: '5.0.0',
maintainers: [{
name: 'zkat'
}]
}
}
},
{
term: '=zkat',
description: 'searches maintainers unambiguously by =name',
location: 154,
inject: {
bar: { name: 'bar', description: 'zkat thing', version: '1.0.0' },
cool: {
name: 'cool',
version: '5.0.0',
maintainers: [{
name: 'zkat'
}]
}
}
},
{
term: 'github.com',
description: 'searches projects by url',
location: 205,
inject: {
bar: {
name: 'bar',
url: 'gitlab.com/bar',
// For historical reasons, `url` is only present if `versions` is there
versions: ['1.0.0'],
version: '1.0.0'
},
cool: {
name: 'cool',
version: '5.0.0',
versions: ['1.0.0'],
url: 'github.com/cool/cool'
}
}
},
{
term: 'monad',
description: 'searches projects by keywords',
location: 197,
inject: {
cool: {
name: 'cool',
version: '5.0.0',
keywords: ['monads']
}
}
}
]
// These test classic hand-matched searches
searches.forEach(function (search) {
test(search.description, function (t) {
setup()
server.get('/-/v1/search?text=' + encodeURIComponent(search.term) + '&size=20').once().reply(404, {})
var now = Date.now()
var cacheContents = {
'_updated': now,
bar: { name: 'bar', version: '1.0.0' },
cool: { name: 'cool', version: '5.0.0' },
foo: { name: 'foo', version: '2.0.0' },
other: { name: 'other', version: '1.0.0' }
}
for (var k in search.inject) {
cacheContents[k] = search.inject[k]
}
var fixture = new Tacks(File(cacheContents))
fixture.create(cachePath)
common.npm([
'search', search.term,
'--registry', common.registry,
'--cache', CACHE_DIR,
'--loglevel', 'error',
'--color', 'always'
].concat(search.extraOpts || []),
{},
function (err, code, stdout, stderr) {
t.equal(stderr, '', 'no error output')
t.notEqual(stdout, '', 'got output')
t.equal(code, 0, 'search finished successfully')
t.ifErr(err, 'search finished successfully')
// \033 == \u001B
var markStart = '\u001B\\[[0-9][0-9]m'
var markEnd = '\u001B\\[0m'
var re = new RegExp(markStart + '.*?' + markEnd)
var cnt = stdout.search(re)
t.equal(
cnt,
search.location,
search.description + ' search for ' + search.term
)
t.end()
})
})
})
test('cleanup', function (t) {
cleanup()
server.close()
t.end()
})
function setup () {
cleanup()
mkdirp.sync(cacheBase)
}
function cleanup () {
server.done()
process.chdir(osenv.tmpdir())
rimraf.sync(PKG_DIR)
}