• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1var fs = require('graceful-fs')
2var path = require('path')
3
4var mkdirp = require('mkdirp')
5var mr = require('npm-registry-mock')
6var osenv = require('osenv')
7var rimraf = require('rimraf')
8var test = require('tap').test
9
10var common = require('../common-tap.js')
11var server
12
13var pkg = path.resolve(__dirname, 'update-save')
14var cache = path.resolve(pkg, 'cache')
15
16var EXEC_OPTS = {
17  cwd: pkg,
18  stdio: 'ignore',
19  env: {
20    npm_config_registry: common.registry,
21    npm_config_loglevel: 'verbose',
22    npm_config_save_prefix: '^'
23  }
24}
25
26var json = {
27  name: 'update-save-example',
28  version: '1.2.3',
29  dependencies: {
30    mkdirp: '~0.3.0'
31  },
32  devDependencies: {
33    underscore: '~1.3.1'
34  }
35}
36
37function clone (a) {
38  return extend({}, a)
39}
40
41function extend (a, b) {
42  for (var key in b) { a[key] = b[key] }
43  return a
44}
45
46test('setup', function (t) {
47  setup()
48
49  mr({ port: common.port }, function (er, s) {
50    t.ifError(er)
51    server = s
52    t.end()
53  })
54})
55
56test('update regular dependencies only', function (t) {
57  setup()
58
59  common.npm(['update', '--save'], EXEC_OPTS, function (err, code) {
60    t.ifError(err)
61    t.notOk(code, 'npm update exited with code 0')
62
63    var pkgdata = JSON.parse(fs.readFileSync(path.join(pkg, 'package.json'), 'utf8'))
64    t.deepEqual(
65      pkgdata.dependencies,
66      { mkdirp: '^0.3.5' },
67      'only dependencies updated'
68    )
69    t.deepEqual(
70      pkgdata.devDependencies,
71      json.devDependencies,
72      'dev dependencies should be untouched'
73    )
74    t.deepEqual(
75      pkgdata.optionalDependencies,
76      json.optionalDependencies,
77      'optional dependencies should be untouched'
78    )
79
80    t.end()
81  })
82})
83
84test('update devDependencies only', function (t) {
85  setup()
86
87  common.npm(['update', '--save-dev'], EXEC_OPTS, function (err, code) {
88    t.ifError(err)
89    t.notOk(code, 'npm update exited with code 0')
90
91    var pkgdata = JSON.parse(fs.readFileSync(path.join(pkg, 'package.json'), 'utf8'))
92    t.deepEqual(
93      pkgdata.dependencies,
94      json.dependencies,
95      'dependencies should be untouched'
96    )
97    t.deepEqual(
98      pkgdata.devDependencies,
99      { underscore: '^1.3.3' },
100      'dev dependencies should be updated'
101    )
102    t.deepEqual(
103      pkgdata.optionalDependencies,
104      json.optionalDependencies,
105      'optional dependencies should be untouched'
106    )
107
108    t.end()
109  })
110})
111
112test('update optionalDependencies only', function (t) {
113  setup({ optionalDependencies: { underscore: '~1.3.1' } })
114
115  common.npm(['update', '--save-optional'], EXEC_OPTS, function (err, code) {
116    t.ifError(err)
117    t.notOk(code, 'npm update exited with code 0')
118
119    var pkgdata = JSON.parse(fs.readFileSync(path.join(pkg, 'package.json'), 'utf8'))
120    t.deepEqual(
121      pkgdata.dependencies,
122      json.dependencies,
123      'dependencies should be untouched'
124    )
125    t.deepEqual(
126      pkgdata.devDependencies,
127      json.devDependencies,
128      'dev dependencies should be untouched'
129    )
130    t.deepEqual(
131      pkgdata.optionalDependencies,
132      { underscore: '^1.3.3' },
133      'optional dependencies should be updated'
134    )
135
136    t.end()
137  })
138})
139
140test('optionalDependencies are merged into dependencies during --save', function (t) {
141  var cloned = setup({ optionalDependencies: { underscore: '~1.3.1' } })
142
143  common.npm(['update', '--save'], EXEC_OPTS, function (err, code) {
144    t.ifError(err)
145    t.notOk(code, 'npm update exited with code 0')
146
147    var pkgdata = JSON.parse(fs.readFileSync(path.join(pkg, 'package.json'), 'utf8'))
148    t.deepEqual(
149      pkgdata.dependencies,
150      { mkdirp: '^0.3.5' },
151      'dependencies should not include optional dependencies'
152    )
153    t.deepEqual(
154      pkgdata.devDependencies,
155      cloned.devDependencies,
156      'dev dependencies should be untouched'
157    )
158    t.deepEqual(
159      pkgdata.optionalDependencies,
160      cloned.optionalDependencies,
161      'optional dependencies should be untouched'
162    )
163
164    t.end()
165  })
166})
167
168test('semver prefix is replaced with configured save-prefix', function (t) {
169  setup()
170
171  common.npm(['update', '--save', '--save-prefix', '~'], EXEC_OPTS, function (err, code) {
172    t.ifError(err)
173    t.notOk(code, 'npm update exited with code 0')
174
175    var pkgdata = JSON.parse(fs.readFileSync(path.join(pkg, 'package.json'), 'utf8'))
176    t.deepEqual(
177      pkgdata.dependencies,
178      { mkdirp: '~0.3.5' },
179      'dependencies should be updated'
180    )
181    t.deepEqual(
182      pkgdata.devDependencies,
183      json.devDependencies,
184      'dev dependencies should be untouched'
185    )
186    t.deepEqual(
187      pkgdata.optionalDependencies,
188      json.optionalDependencies,
189      'optional dependencies should be updated'
190    )
191
192    t.end()
193  })
194})
195
196test('cleanup', function (t) {
197  server.close()
198  cleanup()
199  t.end()
200})
201
202function cleanup () {
203  process.chdir(osenv.tmpdir())
204  rimraf.sync(pkg)
205}
206
207function setup (extendWith) {
208  cleanup()
209  mkdirp.sync(cache)
210  process.chdir(pkg)
211
212  var template = clone(json)
213  extend(template, extendWith)
214  fs.writeFileSync(
215    path.join(pkg, 'package.json'),
216    JSON.stringify(template, null, 2)
217  )
218  return template
219}
220