1// this is a weird meta test. It verifies that all the instances of 2// `npm.config.get(...)` are: 3// a) Simple strings, and not variables 4// b) Documented 5// c) Defined in the `npmconf` package. 6 7var test = require('tap').test 8var fs = require('fs') 9var path = require('path') 10var root = path.resolve(__dirname, '..', '..') 11var lib = path.resolve(root, 'lib') 12var bin = path.resolve(root, 'bin') 13var nm = path.resolve(root, 'node_modules') 14var doc = path.resolve(root, 'docs/content/using-npm/config.md') 15var FILES = [] 16var CONFS = {} 17var DOC = {} 18 19var exceptions = [ 20 path.resolve(lib, 'adduser.js'), 21 path.resolve(lib, 'config.js'), 22 path.resolve(lib, 'config', 'pacote.js'), 23 path.resolve(lib, 'pack.js'), 24 path.resolve(lib, 'publish.js'), 25 path.resolve(lib, 'install', 'inflate-shrinkwrap.js'), 26 path.resolve(lib, 'utils', 'lifecycle.js'), 27 path.resolve(lib, 'utils', 'map-to-registry.js'), 28 path.resolve(nm, 'npm-registry-client', 'lib', 'publish.js'), 29 path.resolve(nm, 'npm-registry-client', 'lib', 'request.js') 30] 31 32test('get files', function (t) { 33 walk(nm) 34 walk(lib) 35 walk(bin) 36 t.pass('got files') 37 t.end() 38 39 function walk (lib) { 40 var files = fs.readdirSync(lib).map(function (f) { 41 return path.resolve(lib, f) 42 }) 43 files.forEach(function (f) { 44 try { 45 var s = fs.lstatSync(f) 46 } catch (er) { 47 return 48 } 49 if (s.isDirectory()) { 50 walk(f) 51 } else if (f.match(/\.js$/)) { 52 FILES.push(f) 53 } 54 }) 55 } 56}) 57 58test('get lines', function (t) { 59 FILES.forEach(function (f) { 60 var lines = fs.readFileSync(f, 'utf8').split(/\r|\n/) 61 lines.forEach(function (l, i) { 62 var matches = l.split(/conf(?:ig)?\.get\(/g) 63 matches.shift() 64 matches.forEach(function (m) { 65 m = m.split(')').shift() 66 var literal = m.match(/^[''].+?['']/) 67 if (literal) { 68 m = literal[0].slice(1, -1) 69 if (!m.match(/^_/) && m !== 'argv') { 70 CONFS[m] = { 71 file: f, 72 line: i 73 } 74 } 75 } else if (exceptions.indexOf(f) === -1 && f.indexOf('.cache') === -1) { 76 t.fail('non-string-literal config used in ' + f + ':' + i) 77 } 78 }) 79 }) 80 }) 81 t.pass('got lines') 82 t.end() 83}) 84 85test('get docs', function (t) { 86 var d = fs.readFileSync(doc, 'utf8').split(/\r|\n/) 87 // walk down until the '## Config Settings' section 88 for (var i = 0; i < d.length && d[i] !== '### Config Settings'; i++); 89 i++ 90 // now gather up all the ^###\s lines until the next ^##\s 91 for (; i < d.length && !d[i].match(/^### /); i++) { 92 if (d[i].match(/^#### /)) { 93 DOC[ d[i].replace(/^#### /, '').trim() ] = true 94 } 95 } 96 t.pass('read the docs') 97 t.end() 98}) 99 100test('check configs', function (t) { 101 var defs = require('../../lib/config/defaults.js') 102 var types = Object.keys(defs.types) 103 var defaults = Object.keys(defs.defaults) 104 for (var c1 in CONFS) { 105 if (CONFS[c1].file.indexOf(lib) === 0) { 106 t.ok(DOC[c1], 'should be documented ' + c1 + ' ' + 107 CONFS[c1].file + ':' + CONFS[c1].line) 108 t.ok(types.indexOf(c1) !== -1, 'should be defined in npmconf ' + c1) 109 t.ok(defaults.indexOf(c1) !== -1, 'should have default in npmconf ' + c1) 110 } 111 } 112 113 // TODO - needs better figgy-pudding introspection 114 // for (var c2 in DOC) { 115 // if (c2 !== 'versions' && c2 !== 'version' && c2 !== 'init.version' && c2 !== 'ham-it-up') { 116 // t.ok(CONFS[c2], 'config in doc should be used somewhere ' + c2) 117 // t.ok(types.indexOf(c2) !== -1, 'should be defined in npmconf ' + c2) 118 // t.ok(defaults.indexOf(c2) !== -1, 'should have default in npmconf ' + c2) 119 // } 120 // } 121 122 types.forEach(function (c) { 123 if (!c.match(/^_/) && c !== 'argv' && !c.match(/^versions?$/) && c !== 'ham-it-up') { 124 t.ok(DOC[c], 'defined type should be documented ' + c) 125 // t.ok(CONFS[c], 'defined type should be used ' + c) 126 } 127 }) 128 129 defaults.forEach(function (c) { 130 if (!c.match(/^_/) && c !== 'argv' && !c.match(/^versions?$/) && c !== 'ham-it-up') { 131 t.ok(DOC[c], 'defaulted type should be documented ' + c) 132 // t.ok(CONFS[c], 'defaulted type should be used ' + c) 133 } 134 }) 135 136 t.end() 137}) 138