mirror of https://github.com/lukechilds/node.git
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.
290 lines
7.2 KiB
290 lines
7.2 KiB
var fs = require('graceful-fs')
|
|
var path = require('path')
|
|
|
|
var mkdirp = require('mkdirp')
|
|
var mr = require('npm-registry-mock')
|
|
var osenv = require('osenv')
|
|
var rimraf = require('rimraf')
|
|
var test = require('tap').test
|
|
|
|
var common = require('../common-tap.js')
|
|
|
|
var pkg = path.resolve(__dirname, 'search')
|
|
var cache = path.resolve(pkg, 'cache')
|
|
var registryCache = path.resolve(cache, 'localhost_1337', '-', 'all')
|
|
var cacheJsonFile = path.resolve(registryCache, '.cache.json')
|
|
|
|
var timeMock = {
|
|
epoch: 1411727900,
|
|
future: 1411727900 + 100,
|
|
all: 1411727900 + 25,
|
|
since: 0 // filled by since server callback
|
|
}
|
|
|
|
var EXEC_OPTS = {}
|
|
|
|
var mocks = {
|
|
/* Since request, always response with an _update time > the time requested */
|
|
sinceFuture: function (server) {
|
|
server.filteringPathRegEx(/startkey=[^&]*/g, function (s) {
|
|
var _allMock = JSON.parse(JSON.stringify(allMock))
|
|
timeMock.since = _allMock._updated = s.replace('startkey=', '')
|
|
server.get('/-/all/since?stale=update_after&' + s)
|
|
.reply(200, _allMock)
|
|
return s
|
|
})
|
|
},
|
|
allFutureUpdatedOnly: function (server) {
|
|
server.get('/-/all')
|
|
.reply(200, stringifyUpdated(timeMock.future))
|
|
},
|
|
all: function (server) {
|
|
server.get('/-/all')
|
|
.reply(200, allMock)
|
|
}
|
|
}
|
|
|
|
test('No previous cache, init cache triggered by first search', function (t) {
|
|
cleanup()
|
|
|
|
mr({ port: common.port, plugin: mocks.allFutureUpdatedOnly }, function (err, s) {
|
|
t.ifError(err, 'mock registry started')
|
|
common.npm([
|
|
'search', 'do not do extra search work on my behalf',
|
|
'--registry', common.registry,
|
|
'--cache', cache,
|
|
'--loglevel', 'silent',
|
|
'--color', 'always'
|
|
],
|
|
EXEC_OPTS,
|
|
function (err, code) {
|
|
s.close()
|
|
t.equal(code, 0, 'search finished successfully')
|
|
t.ifErr(err, 'search finished successfully')
|
|
|
|
t.ok(
|
|
fs.existsSync(cacheJsonFile),
|
|
cacheJsonFile + ' expected to have been created'
|
|
)
|
|
|
|
var cacheData = JSON.parse(fs.readFileSync(cacheJsonFile, 'utf8'))
|
|
t.equal(cacheData._updated, String(timeMock.future))
|
|
t.end()
|
|
})
|
|
})
|
|
})
|
|
|
|
test('no arguments provided should error', function (t) {
|
|
common.npm(['search'], [], function (err, code, stdout, stderr) {
|
|
if (err) throw err
|
|
t.equal(code, 1, 'search finished unsuccessfully')
|
|
|
|
t.match(
|
|
stderr,
|
|
/search must be called with arguments/,
|
|
'should have correct error message'
|
|
)
|
|
t.end()
|
|
})
|
|
})
|
|
|
|
test('previous cache, _updated set, should trigger since request', function (t) {
|
|
setupCache()
|
|
|
|
function m (server) {
|
|
[ mocks.all, mocks.sinceFuture ].forEach(function (m) {
|
|
m(server)
|
|
})
|
|
}
|
|
mr({ port: common.port, plugin: m }, function (err, s) {
|
|
t.ifError(err, 'mock registry started')
|
|
common.npm([
|
|
'search', 'do not do extra search work on my behalf',
|
|
'--registry', common.registry,
|
|
'--cache', cache,
|
|
'--loglevel', 'silly',
|
|
'--color', 'always'
|
|
],
|
|
EXEC_OPTS,
|
|
function (err, code) {
|
|
s.close()
|
|
t.equal(code, 0, 'search finished successfully')
|
|
t.ifErr(err, 'search finished successfully')
|
|
|
|
var cacheData = JSON.parse(fs.readFileSync(cacheJsonFile, 'utf8'))
|
|
t.equal(
|
|
cacheData._updated,
|
|
timeMock.since,
|
|
'cache update time gotten from since response'
|
|
)
|
|
t.end()
|
|
})
|
|
})
|
|
})
|
|
|
|
var searches = [
|
|
{
|
|
term: 'f36b6a6123da50959741e2ce4d634f96ec668c56',
|
|
description: 'non-regex',
|
|
location: 241
|
|
},
|
|
{
|
|
term: '/f36b6a6123da50959741e2ce4d634f96ec668c56/',
|
|
description: 'regex',
|
|
location: 241
|
|
}
|
|
]
|
|
|
|
searches.forEach(function (search) {
|
|
test(search.description + ' search in color', function (t) {
|
|
cleanup()
|
|
mr({ port: common.port, plugin: mocks.all }, function (er, s) {
|
|
common.npm([
|
|
'search', search.term,
|
|
'--registry', common.registry,
|
|
'--cache', cache,
|
|
'--loglevel', 'silent',
|
|
'--color', 'always'
|
|
],
|
|
EXEC_OPTS,
|
|
function (err, code, stdout) {
|
|
s.close()
|
|
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()
|
|
t.end()
|
|
})
|
|
|
|
function cleanup () {
|
|
process.chdir(osenv.tmpdir())
|
|
rimraf.sync(pkg)
|
|
}
|
|
|
|
function setupCache () {
|
|
cleanup()
|
|
mkdirp.sync(cache)
|
|
mkdirp.sync(registryCache)
|
|
var res = fs.writeFileSync(cacheJsonFile, stringifyUpdated(timeMock.epoch))
|
|
if (res) throw new Error('Creating cache file failed')
|
|
}
|
|
|
|
function stringifyUpdated (time) {
|
|
return JSON.stringify({ _updated: String(time) })
|
|
}
|
|
|
|
var allMock = {
|
|
'_updated': timeMock.all,
|
|
'generator-frontcow': {
|
|
'name': 'generator-frontcow',
|
|
'description': 'f36b6a6123da50959741e2ce4d634f96ec668c56 This is a fake description to ensure we do not accidentally search the real npm registry or use some kind of cache',
|
|
'dist-tags': {
|
|
'latest': '0.1.19'
|
|
},
|
|
'maintainers': [
|
|
{
|
|
'name': 'bcabanes',
|
|
'email': 'contact@benjamincabanes.com'
|
|
}
|
|
],
|
|
'homepage': 'https://github.com/bcabanes/generator-frontcow',
|
|
'keywords': [
|
|
'sass',
|
|
'frontend',
|
|
'yeoman-generator',
|
|
'atomic',
|
|
'design',
|
|
'sass',
|
|
'foundation',
|
|
'foundation5',
|
|
'atomic design',
|
|
'bourbon',
|
|
'polyfill',
|
|
'font awesome'
|
|
],
|
|
'repository': {
|
|
'type': 'git',
|
|
'url': 'https://github.com/bcabanes/generator-frontcow'
|
|
},
|
|
'author': {
|
|
'name': 'ben',
|
|
'email': 'contact@benjamincabanes.com',
|
|
'url': 'https://github.com/bcabanes'
|
|
},
|
|
'bugs': {
|
|
'url': 'https://github.com/bcabanes/generator-frontcow/issues'
|
|
},
|
|
'license': 'MIT',
|
|
'readmeFilename': 'README.md',
|
|
'time': {
|
|
'modified': '2014-10-03T02:26:18.406Z'
|
|
},
|
|
'versions': {
|
|
'0.1.19': 'latest'
|
|
}
|
|
},
|
|
'marko': {
|
|
'name': 'marko',
|
|
'description': 'Marko is an extensible, streaming, asynchronous, high performance, HTML-based templating language that can be used in Node.js or in the browser.',
|
|
'dist-tags': {
|
|
'latest': '1.2.16'
|
|
},
|
|
'maintainers': [
|
|
{
|
|
'name': 'pnidem',
|
|
'email': 'pnidem@gmail.com'
|
|
},
|
|
{
|
|
'name': 'philidem',
|
|
'email': 'phillip.idem@gmail.com'
|
|
}
|
|
],
|
|
'homepage': 'https://github.com/raptorjs/marko',
|
|
'keywords': [
|
|
'templating',
|
|
'template',
|
|
'async',
|
|
'streaming'
|
|
],
|
|
'repository': {
|
|
'type': 'git',
|
|
'url': 'https://github.com/raptorjs/marko.git'
|
|
},
|
|
'author': {
|
|
'name': 'Patrick Steele-Idem',
|
|
'email': 'pnidem@gmail.com'
|
|
},
|
|
'bugs': {
|
|
'url': 'https://github.com/raptorjs/marko/issues'
|
|
},
|
|
'license': 'Apache License v2.0',
|
|
'readmeFilename': 'README.md',
|
|
'users': {
|
|
'pnidem': true
|
|
},
|
|
'time': {
|
|
'modified': '2014-10-03T02:27:31.775Z'
|
|
},
|
|
'versions': {
|
|
'1.2.16': 'latest'
|
|
}
|
|
}
|
|
}
|
|
|