Welcome to mirror list, hosted at ThFree Co, Russian Federation.

mock-npm.js « fixtures « test - github.com/npm/cli.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: a51ec3e5bb879681098a57c9378b7dfc3a9d57dd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
const npmlog = require('npmlog')
const procLog = require('../../lib/utils/proc-log-listener.js')
procLog.reset()

// In theory we shouldn't have to do this if all the tests were tearing down
// their listeners properly, we're still getting warnings even though
// perfStop() and procLog.reset() is in the teardown script.  This silences the
// warnings for now
require('events').defaultMaxListeners = Infinity

const realLog = {}
for (const level in npmlog.levels) {
  realLog[level] = npmlog[level]
}

const { title, execPath } = process

// Eventually this should default to having a prefix of an empty testdir, and
// awaiting npm.load() unless told not to (for npm tests for example).  Ideally
// the prefix of an empty dir is inferred rather than explicitly set
const RealMockNpm = (t, otherMocks = {}) => {
  const mock = {}
  mock.logs = []
  mock.outputs = []
  mock.joinedOutput = () => {
    return mock.outputs.map(o => o.join(' ')).join('\n')
  }
  mock.filteredLogs = title => mock.logs.filter(([t]) => t === title).map(([, , msg]) => msg)
  const Npm = t.mock('../../lib/npm.js', otherMocks)
  class MockNpm extends Npm {
    constructor () {
      super()
      for (const level in npmlog.levels) {
        npmlog[level] = (...msg) => {
          mock.logs.push([level, ...msg])

          const l = npmlog.level
          npmlog.level = 'silent'
          realLog[level](...msg)
          npmlog.level = l
        }
      }
      // npm.js tests need this restored to actually test this function!
      mock.npmOutput = this.output
      this.output = (...msg) => mock.outputs.push(msg)
    }
  }
  mock.Npm = MockNpm
  t.afterEach(() => {
    mock.outputs.length = 0
    mock.logs.length = 0
  })

  t.teardown(() => {
    process.removeAllListeners('time')
    process.removeAllListeners('timeEnd')
    npmlog.record.length = 0
    for (const level in npmlog.levels) {
      npmlog[level] = realLog[level]
    }
    procLog.reset()
    process.title = title
    process.execPath = execPath
    delete process.env.npm_command
    delete process.env.COLOR
  })

  return mock
}

const realConfig = require('../../lib/utils/config')

// Basic npm fixture that you can give a config object that acts like
// npm.config You still need a separate flatOptions. Tests should migrate to
// using the real npm mock above
class MockNpm {
  constructor (base = {}) {
    this._mockOutputs = []
    this.isMockNpm = true
    this.base = base

    const config = base.config || {}

    for (const attr in base) {
      if (attr !== 'config') {
        this[attr] = base[attr]
      }
    }

    this.flatOptions = base.flatOptions || {}
    this.config = {
      // for now just set `find` to what config.find should return
      // this works cause `find` is not an existing config entry
      find: (k) => ({ ...realConfig.defaults, ...config })[k],
      get: (k) => ({ ...realConfig.defaults, ...config })[k],
      set: (k, v) => config[k] = v,
      list: [{ ...realConfig.defaults, ...config }],
    }
    if (!this.log) {
      this.log = {
        clearProgress: () => {},
        disableProgress: () => {},
        enableProgress: () => {},
        http: () => {},
        info: () => {},
        levels: [],
        notice: () => {},
        pause: () => {},
        silly: () => {},
        verbose: () => {},
        warn: () => {},
      }
    }
  }

  output (...msg) {
    if (this.base.output) {
      return this.base.output(msg)
    }
    this._mockOutputs.push(msg)
  }
}

const FakeMockNpm = (base = {}) => {
  return new MockNpm(base)
}

module.exports = {
  fake: FakeMockNpm,
  real: RealMockNpm,
}