• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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