navy 6.0.0 → 7.0.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (149) hide show
  1. package/lib/__tests__/config-provider.js +75 -0
  2. package/lib/__tests__/config.js +130 -0
  3. package/lib/__tests__/driver-logging.js +148 -0
  4. package/lib/__tests__/driver.js +19 -0
  5. package/lib/__tests__/errors.js +49 -0
  6. package/lib/__tests__/http-proxy.js +214 -0
  7. package/lib/__tests__/index.js +25 -0
  8. package/lib/__tests__/service.js +16 -0
  9. package/lib/cli/__tests__/develop.js +239 -0
  10. package/lib/cli/__tests__/external-ip.js +68 -0
  11. package/lib/cli/__tests__/health.js +257 -0
  12. package/lib/cli/__tests__/https.js +210 -0
  13. package/lib/cli/__tests__/import.js +110 -0
  14. package/lib/cli/__tests__/index.js +118 -0
  15. package/lib/cli/__tests__/lan-ip.js +90 -0
  16. package/lib/cli/__tests__/launch.js +179 -0
  17. package/lib/cli/__tests__/live.js +155 -0
  18. package/lib/cli/__tests__/local-ip.js +72 -0
  19. package/lib/cli/__tests__/logs.js +52 -0
  20. package/lib/cli/__tests__/open.js +65 -0
  21. package/lib/cli/__tests__/program.js +472 -0
  22. package/lib/cli/__tests__/ps.js +345 -0
  23. package/lib/cli/__tests__/refresh-config.js +95 -0
  24. package/lib/cli/__tests__/run.js +54 -0
  25. package/lib/cli/__tests__/status.js +204 -0
  26. package/lib/cli/__tests__/updates.js +243 -0
  27. package/lib/cli/__tests__/wait-for-healthy.js +134 -0
  28. package/lib/cli/config/__tests__/index.js +275 -0
  29. package/lib/cli/config/__tests__/wrapper.js +53 -0
  30. package/lib/cli/config/index.js +19 -37
  31. package/lib/cli/config/wrapper.js +0 -6
  32. package/lib/cli/develop.js +7 -21
  33. package/lib/cli/doctor/__tests__/clean-compose-files.js +78 -0
  34. package/lib/cli/doctor/__tests__/index.js +67 -0
  35. package/lib/cli/doctor/__tests__/invalid-compose-config.js +103 -0
  36. package/lib/cli/doctor/__tests__/invalid-state.js +83 -0
  37. package/lib/cli/doctor/__tests__/util.js +91 -0
  38. package/lib/cli/doctor/clean-compose-files.js +5 -13
  39. package/lib/cli/doctor/index.js +0 -12
  40. package/lib/cli/doctor/invalid-compose-config.js +0 -4
  41. package/lib/cli/doctor/invalid-state.js +0 -6
  42. package/lib/cli/doctor/util.js +0 -10
  43. package/lib/cli/external-ip.js +0 -4
  44. package/lib/cli/health.js +0 -12
  45. package/lib/cli/https.js +9 -25
  46. package/lib/cli/import.js +0 -12
  47. package/lib/cli/index.js +0 -9
  48. package/lib/cli/lan-ip.js +2 -8
  49. package/lib/cli/launch.js +0 -9
  50. package/lib/cli/live.js +6 -16
  51. package/lib/cli/local-ip.js +2 -7
  52. package/lib/cli/logs.js +0 -3
  53. package/lib/cli/open.js +2 -7
  54. package/lib/cli/program.js +73 -101
  55. package/lib/cli/ps.js +1 -21
  56. package/lib/cli/refresh-config.js +0 -7
  57. package/lib/cli/run.js +0 -3
  58. package/lib/cli/status.js +0 -11
  59. package/lib/cli/updates.js +0 -22
  60. package/lib/cli/util/__tests__/get-or-initialise-navy.js +66 -0
  61. package/lib/cli/util/__tests__/import.js +123 -0
  62. package/lib/cli/util/__tests__/index.js +17 -0
  63. package/lib/cli/util/__tests__/merge-action-options.js +47 -0
  64. package/lib/cli/util/__tests__/reconfigure.js +78 -0
  65. package/lib/cli/util/get-or-initialise-navy.js +0 -7
  66. package/lib/cli/util/import.js +0 -9
  67. package/lib/cli/util/index.js +0 -2
  68. package/lib/cli/util/merge-action-options.js +20 -0
  69. package/lib/cli/util/reconfigure.js +0 -4
  70. package/lib/cli/wait-for-healthy.js +0 -21
  71. package/lib/client/registry/__tests__/get-credentials.js +62 -0
  72. package/lib/client/registry/__tests__/get-endpoint.js +124 -0
  73. package/lib/client/registry/__tests__/get-fat-manifest.js +67 -0
  74. package/lib/client/registry/__tests__/get-token.js +66 -0
  75. package/lib/client/registry/__tests__/helpers.js +26 -0
  76. package/lib/client/registry/get-credentials.js +3 -9
  77. package/lib/client/registry/get-endpoint.js +29 -63
  78. package/lib/client/registry/get-fat-manifest.js +2 -9
  79. package/lib/client/registry/get-token.js +2 -13
  80. package/lib/client/registry/helpers.js +0 -4
  81. package/lib/config-provider.js +0 -12
  82. package/lib/config-providers/filesystem/__tests__/index.js +176 -0
  83. package/lib/config-providers/filesystem/index.js +5 -23
  84. package/lib/config-providers/npm/__tests__/index.js +226 -0
  85. package/lib/config-providers/npm/__tests__/util.js +1 -2
  86. package/lib/config-providers/npm/index.js +12 -35
  87. package/lib/config-providers/npm/util.js +0 -3
  88. package/lib/config.js +4 -19
  89. package/lib/domain/__tests__/container-image.js +81 -0
  90. package/lib/domain/__tests__/oci-api-specification.js +23 -0
  91. package/lib/domain/container-image.js +8 -21
  92. package/lib/domain/oci-api-specification.js +3 -5
  93. package/lib/driver-logging.js +0 -19
  94. package/lib/driver.js +0 -4
  95. package/lib/drivers/docker-compose/__tests__/client.js +249 -0
  96. package/lib/drivers/docker-compose/__tests__/index.js +430 -0
  97. package/lib/drivers/docker-compose/client.js +0 -16
  98. package/lib/drivers/docker-compose/index.js +7 -49
  99. package/lib/errors.js +0 -10
  100. package/lib/http-proxy.js +28 -23
  101. package/lib/index.js +1 -9
  102. package/lib/middleware/__tests__/add-service-proxy-config.js +258 -0
  103. package/lib/middleware/__tests__/develop.js +120 -0
  104. package/lib/middleware/__tests__/helpers.js +154 -0
  105. package/lib/middleware/__tests__/port-override.js +125 -0
  106. package/lib/middleware/__tests__/set-env-vars.js +94 -0
  107. package/lib/middleware/__tests__/set-image.js +76 -0
  108. package/lib/middleware/__tests__/set-logging-driver.js +94 -0
  109. package/lib/middleware/__tests__/tag-override.js +92 -0
  110. package/lib/middleware/add-service-proxy-config.js +8 -16
  111. package/lib/middleware/develop.js +2 -5
  112. package/lib/middleware/helpers.js +6 -12
  113. package/lib/middleware/port-override.js +5 -8
  114. package/lib/middleware/set-env-vars.js +6 -6
  115. package/lib/middleware/set-image.js +4 -5
  116. package/lib/middleware/set-logging-driver.js +6 -6
  117. package/lib/middleware/tag-override.js +4 -6
  118. package/lib/navy/__tests__/default-middleware.js +40 -0
  119. package/lib/navy/__tests__/index.js +1612 -0
  120. package/lib/navy/__tests__/middleware.js +71 -0
  121. package/lib/navy/__tests__/plugin-interface.js +121 -0
  122. package/lib/navy/__tests__/state.js +103 -0
  123. package/lib/navy/__tests__/util.js +24 -0
  124. package/lib/navy/default-middleware.js +0 -10
  125. package/lib/navy/index.js +83 -138
  126. package/lib/navy/middleware.js +0 -6
  127. package/lib/navy/plugin-interface.js +2 -10
  128. package/lib/navy/state.js +12 -24
  129. package/lib/navy/util.js +0 -1
  130. package/lib/service.js +2 -3
  131. package/lib/util/__tests__/exec-async.js +83 -0
  132. package/lib/util/__tests__/external-ip.js +97 -2
  133. package/lib/util/__tests__/get-lan-ip.js +46 -0
  134. package/lib/util/__tests__/has-update.js +136 -0
  135. package/lib/util/__tests__/https.js +301 -0
  136. package/lib/util/__tests__/navyrc.js +45 -0
  137. package/lib/util/__tests__/service-host.js +63 -5
  138. package/lib/util/__tests__/table.js +44 -0
  139. package/lib/util/docker-client.js +2 -10
  140. package/lib/util/exec-async.js +0 -4
  141. package/lib/util/external-ip.js +8 -12
  142. package/lib/util/fs.js +1 -6
  143. package/lib/util/get-lan-ip.js +0 -5
  144. package/lib/util/has-update.js +2 -14
  145. package/lib/util/https.js +11 -55
  146. package/lib/util/navyrc.js +0 -5
  147. package/lib/util/service-host.js +0 -17
  148. package/lib/util/table.js +0 -6
  149. package/package.json +14 -13
@@ -0,0 +1,345 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ var _chai = require("chai");
5
+ var _sinon = _interopRequireDefault(require("sinon"));
6
+ var _proxyquire = _interopRequireDefault(require("proxyquire"));
7
+ var _stripAnsi = _interopRequireDefault(require("strip-ansi"));
8
+ /* eslint-env mocha */
9
+
10
+ describe('cli/ps', function () {
11
+ let sandbox;
12
+ let getNavyStub;
13
+ let getUrlFromServiceStub;
14
+ let navyStub;
15
+ let consoleLogStub;
16
+ let originalIsTTY;
17
+ let originalGetWindowSize;
18
+ let psCli;
19
+ function makeService(overrides = {}) {
20
+ return {
21
+ id: 'abcdefghijklmnop',
22
+ name: 'api',
23
+ image: 'navy/api:latest',
24
+ status: 'running',
25
+ raw: undefined,
26
+ ...overrides
27
+ };
28
+ }
29
+ beforeEach(function () {
30
+ sandbox = _sinon.default.createSandbox();
31
+ navyStub = {
32
+ ps: sandbox.stub().resolves([]),
33
+ getState: sandbox.stub().resolves(null)
34
+ };
35
+ getNavyStub = sandbox.stub().returns(navyStub);
36
+ getUrlFromServiceStub = sandbox.stub().returns(null);
37
+ consoleLogStub = sandbox.stub(console, 'log');
38
+ originalIsTTY = process.stdout.isTTY;
39
+ originalGetWindowSize = process.stdout.getWindowSize;
40
+ process.stdout.isTTY = false;
41
+ process.stdout.getWindowSize = () => [200, 50];
42
+ psCli = _proxyquire.default.noCallThru()('../ps', {
43
+ '../': {
44
+ getNavy: getNavyStub
45
+ },
46
+ '../util/service-host': {
47
+ getUrlFromService: getUrlFromServiceStub
48
+ }
49
+ });
50
+ });
51
+ afterEach(function () {
52
+ sandbox.restore();
53
+ process.stdout.isTTY = originalIsTTY;
54
+ if (originalGetWindowSize === undefined) {
55
+ delete process.stdout.getWindowSize;
56
+ } else {
57
+ process.stdout.getWindowSize = originalGetWindowSize;
58
+ }
59
+ });
60
+ function lastLoggedString() {
61
+ const last = consoleLogStub.lastCall;
62
+ return last ? String(last.args[0]) : '';
63
+ }
64
+ describe('default export', function () {
65
+ it('should resolve the navy instance using opts.navy', async function () {
66
+ await psCli({
67
+ navy: 'env-1'
68
+ });
69
+ (0, _chai.expect)(getNavyStub.calledOnce).to.equal(true);
70
+ (0, _chai.expect)(getNavyStub.firstCall.args[0]).to.equal('env-1');
71
+ });
72
+ it('should print JSON when opts.json is true', async function () {
73
+ const services = [makeService({
74
+ id: 'svc-id',
75
+ name: 'api'
76
+ })];
77
+ navyStub.ps.resolves(services);
78
+ await psCli({
79
+ navy: 'env-1',
80
+ json: true
81
+ });
82
+ (0, _chai.expect)(consoleLogStub.calledOnce).to.equal(true);
83
+ (0, _chai.expect)(consoleLogStub.firstCall.args[0]).to.equal(JSON.stringify(services, null, 2));
84
+ });
85
+ it('should render the wide 6-column table by default in non-TTY', async function () {
86
+ navyStub.ps.resolves([makeService()]);
87
+ await psCli({
88
+ navy: 'env-1'
89
+ });
90
+ const text = (0, _stripAnsi.default)(lastLoggedString());
91
+ (0, _chai.expect)(text).to.contain('IMAGE');
92
+ (0, _chai.expect)(text).to.contain('navy/api:latest');
93
+ });
94
+ it('should render the small 5-column table when TTY width is below threshold', async function () {
95
+ process.stdout.isTTY = true;
96
+ process.stdout.getWindowSize = () => [80, 50];
97
+ navyStub.ps.resolves([makeService()]);
98
+ await psCli({
99
+ navy: 'env-1'
100
+ });
101
+ const text = (0, _stripAnsi.default)(lastLoggedString());
102
+ (0, _chai.expect)(text).to.contain('NAME');
103
+ (0, _chai.expect)(text).to.contain('STATUS');
104
+ (0, _chai.expect)(text).to.not.contain('IMAGE');
105
+ });
106
+ it('should render the wide 6-column table when TTY width is at or above threshold', async function () {
107
+ process.stdout.isTTY = true;
108
+ process.stdout.getWindowSize = () => [200, 50];
109
+ navyStub.ps.resolves([makeService()]);
110
+ await psCli({
111
+ navy: 'env-1'
112
+ });
113
+ const text = (0, _stripAnsi.default)(lastLoggedString());
114
+ (0, _chai.expect)(text).to.contain('IMAGE');
115
+ });
116
+ it('should truncate the service id to 12 characters', async function () {
117
+ navyStub.ps.resolves([makeService({
118
+ id: '0123456789abcdef9999'
119
+ })]);
120
+ await psCli({
121
+ navy: 'env-1'
122
+ });
123
+ const text = (0, _stripAnsi.default)(lastLoggedString());
124
+ (0, _chai.expect)(text).to.contain('0123456789ab');
125
+ (0, _chai.expect)(text).not.to.contain('0123456789abcdef');
126
+ });
127
+ });
128
+ describe('getStatus (via default export)', function () {
129
+ it('should print the status as-is when not exited and no state present', async function () {
130
+ navyStub.ps.resolves([makeService({
131
+ status: 'running'
132
+ })]);
133
+ await psCli({
134
+ navy: 'env-1'
135
+ });
136
+ const text = (0, _stripAnsi.default)(lastLoggedString());
137
+ (0, _chai.expect)(text).to.contain('running');
138
+ (0, _chai.expect)(text).not.to.contain('(development)');
139
+ (0, _chai.expect)(text).not.to.contain('@');
140
+ });
141
+ it('should render the exited status (taking the chalk.red branch)', async function () {
142
+ navyStub.ps.resolves([makeService({
143
+ status: 'exited'
144
+ })]);
145
+ await psCli({
146
+ navy: 'env-1'
147
+ });
148
+ const text = (0, _stripAnsi.default)(lastLoggedString());
149
+ (0, _chai.expect)(text).to.contain('exited');
150
+ });
151
+ it('should append (development) when the service has _develop set in state', async function () {
152
+ navyStub.ps.resolves([makeService({
153
+ name: 'api'
154
+ })]);
155
+ navyStub.getState.resolves({
156
+ services: {
157
+ api: {
158
+ _develop: true
159
+ }
160
+ }
161
+ });
162
+ await psCli({
163
+ navy: 'env-1'
164
+ });
165
+ const text = (0, _stripAnsi.default)(lastLoggedString());
166
+ (0, _chai.expect)(text).to.contain('(development)');
167
+ });
168
+ it('should append the @ tag when the service has _tag set in state', async function () {
169
+ navyStub.ps.resolves([makeService({
170
+ name: 'api'
171
+ })]);
172
+ navyStub.getState.resolves({
173
+ services: {
174
+ api: {
175
+ _tag: 'v1.2.3'
176
+ }
177
+ }
178
+ });
179
+ await psCli({
180
+ navy: 'env-1'
181
+ });
182
+ const text = (0, _stripAnsi.default)(lastLoggedString());
183
+ (0, _chai.expect)(text).to.contain('@ v1.2.3');
184
+ });
185
+ it('should append both (development) and the @ tag when both are set', async function () {
186
+ navyStub.ps.resolves([makeService({
187
+ name: 'api'
188
+ })]);
189
+ navyStub.getState.resolves({
190
+ services: {
191
+ api: {
192
+ _develop: true,
193
+ _tag: 'v9'
194
+ }
195
+ }
196
+ });
197
+ await psCli({
198
+ navy: 'env-1'
199
+ });
200
+ const text = (0, _stripAnsi.default)(lastLoggedString());
201
+ (0, _chai.expect)(text).to.contain('(development)');
202
+ (0, _chai.expect)(text).to.contain('@ v9');
203
+ });
204
+ it('should not annotate the status when state has no entry for the service name', async function () {
205
+ navyStub.ps.resolves([makeService({
206
+ name: 'api'
207
+ })]);
208
+ navyStub.getState.resolves({
209
+ services: {
210
+ web: {
211
+ _develop: true
212
+ }
213
+ }
214
+ });
215
+ await psCli({
216
+ navy: 'env-1'
217
+ });
218
+ const text = (0, _stripAnsi.default)(lastLoggedString());
219
+ (0, _chai.expect)(text).not.to.contain('(development)');
220
+ });
221
+ it('should handle a state object with no services map', async function () {
222
+ navyStub.ps.resolves([makeService({
223
+ name: 'api'
224
+ })]);
225
+ navyStub.getState.resolves({});
226
+ await psCli({
227
+ navy: 'env-1'
228
+ });
229
+ const text = (0, _stripAnsi.default)(lastLoggedString());
230
+ (0, _chai.expect)(text).to.contain('running');
231
+ (0, _chai.expect)(text).not.to.contain('(development)');
232
+ });
233
+ });
234
+ describe('getPorts (via default export)', function () {
235
+ it('should render - when raw is missing', async function () {
236
+ navyStub.ps.resolves([makeService({
237
+ raw: undefined
238
+ })]);
239
+ await psCli({
240
+ navy: 'env-1'
241
+ });
242
+ const text = (0, _stripAnsi.default)(lastLoggedString());
243
+ (0, _chai.expect)(text).to.match(/-/);
244
+ });
245
+ it('should render - when raw.NetworkSettings is missing', async function () {
246
+ navyStub.ps.resolves([makeService({
247
+ raw: {}
248
+ })]);
249
+ await psCli({
250
+ navy: 'env-1'
251
+ });
252
+ const text = (0, _stripAnsi.default)(lastLoggedString());
253
+ (0, _chai.expect)(text).to.match(/-/);
254
+ });
255
+ it('should render - when raw.NetworkSettings.Ports is missing', async function () {
256
+ navyStub.ps.resolves([makeService({
257
+ raw: {
258
+ NetworkSettings: {}
259
+ }
260
+ })]);
261
+ await psCli({
262
+ navy: 'env-1'
263
+ });
264
+ const text = (0, _stripAnsi.default)(lastLoggedString());
265
+ (0, _chai.expect)(text).to.match(/-/);
266
+ });
267
+ it('should render only the port key when there are no host bindings', async function () {
268
+ navyStub.ps.resolves([makeService({
269
+ raw: {
270
+ NetworkSettings: {
271
+ Ports: {
272
+ '8080/tcp': null
273
+ }
274
+ }
275
+ }
276
+ })]);
277
+ await psCli({
278
+ navy: 'env-1'
279
+ });
280
+ const text = (0, _stripAnsi.default)(lastLoggedString());
281
+ (0, _chai.expect)(text).to.contain('8080/tcp');
282
+ (0, _chai.expect)(text).not.to.contain('->');
283
+ });
284
+ it('should render HostPort->portKey when bindings exist', async function () {
285
+ navyStub.ps.resolves([makeService({
286
+ raw: {
287
+ NetworkSettings: {
288
+ Ports: {
289
+ '8080/tcp': [{
290
+ HostPort: '32001'
291
+ }, {
292
+ HostPort: '32002'
293
+ }]
294
+ }
295
+ }
296
+ }
297
+ })]);
298
+ await psCli({
299
+ navy: 'env-1'
300
+ });
301
+ const text = (0, _stripAnsi.default)(lastLoggedString());
302
+ (0, _chai.expect)(text).to.contain('32001, 32002->8080/tcp');
303
+ });
304
+ it('should join multiple port keys with commas', async function () {
305
+ navyStub.ps.resolves([makeService({
306
+ raw: {
307
+ NetworkSettings: {
308
+ Ports: {
309
+ '8080/tcp': [{
310
+ HostPort: '32001'
311
+ }],
312
+ '9090/tcp': null
313
+ }
314
+ }
315
+ }
316
+ })]);
317
+ await psCli({
318
+ navy: 'env-1'
319
+ });
320
+ const text = (0, _stripAnsi.default)(lastLoggedString());
321
+ (0, _chai.expect)(text).to.contain('32001->8080/tcp');
322
+ (0, _chai.expect)(text).to.contain('9090/tcp');
323
+ });
324
+ });
325
+ describe('getDisplayUrl (via default export)', function () {
326
+ it('should render - when getUrlFromService returns null', async function () {
327
+ getUrlFromServiceStub.returns(null);
328
+ navyStub.ps.resolves([makeService()]);
329
+ await psCli({
330
+ navy: 'env-1'
331
+ });
332
+ const text = (0, _stripAnsi.default)(lastLoggedString());
333
+ (0, _chai.expect)(text).to.match(/\s-\s|\s-$/);
334
+ });
335
+ it('should render the URL string when getUrlFromService returns a string', async function () {
336
+ getUrlFromServiceStub.returns('https://api.example.local');
337
+ navyStub.ps.resolves([makeService()]);
338
+ await psCli({
339
+ navy: 'env-1'
340
+ });
341
+ const text = (0, _stripAnsi.default)(lastLoggedString());
342
+ (0, _chai.expect)(text).to.contain('https://api.example.local');
343
+ });
344
+ });
345
+ });
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ var _chai = require("chai");
5
+ var _sinon = _interopRequireDefault(require("sinon"));
6
+ var _proxyquire = _interopRequireDefault(require("proxyquire"));
7
+ /* eslint-env mocha */
8
+
9
+ describe('cli/refresh-config', function () {
10
+ let sandbox;
11
+ let getNavyStub;
12
+ let navyStub;
13
+ let configProvider;
14
+ let startDriverLoggingStub;
15
+ let stopDriverLoggingStub;
16
+ let consoleLogStub;
17
+ let refreshConfigCli;
18
+ beforeEach(function () {
19
+ sandbox = _sinon.default.createSandbox();
20
+ configProvider = {
21
+ refreshConfig: sandbox.stub().resolves()
22
+ };
23
+ navyStub = {
24
+ name: 'env-1',
25
+ getConfigProvider: sandbox.stub().resolves(configProvider),
26
+ reconfigure: sandbox.stub().resolves()
27
+ };
28
+ getNavyStub = sandbox.stub().returns(navyStub);
29
+ startDriverLoggingStub = sandbox.stub();
30
+ stopDriverLoggingStub = sandbox.stub();
31
+ consoleLogStub = sandbox.stub(console, 'log');
32
+ refreshConfigCli = _proxyquire.default.noCallThru()('../refresh-config', {
33
+ '../': {
34
+ getNavy: getNavyStub
35
+ },
36
+ '../driver-logging': {
37
+ startDriverLogging: startDriverLoggingStub,
38
+ stopDriverLogging: stopDriverLoggingStub
39
+ }
40
+ });
41
+ });
42
+ afterEach(function () {
43
+ sandbox.restore();
44
+ });
45
+ describe('default export', function () {
46
+ it('should resolve the navy instance using opts.navy', async function () {
47
+ await refreshConfigCli({
48
+ navy: 'env-1'
49
+ });
50
+ (0, _chai.expect)(getNavyStub.calledOnce).to.equal(true);
51
+ (0, _chai.expect)(getNavyStub.firstCall.args[0]).to.equal('env-1');
52
+ });
53
+ it('should call refreshConfig on the resolved config provider', async function () {
54
+ await refreshConfigCli({
55
+ navy: 'env-1'
56
+ });
57
+ (0, _chai.expect)(navyStub.getConfigProvider.calledOnce).to.equal(true);
58
+ (0, _chai.expect)(configProvider.refreshConfig.calledOnce).to.equal(true);
59
+ });
60
+ it('should bracket reconfigure with start/stopDriverLogging', async function () {
61
+ await refreshConfigCli({
62
+ navy: 'env-1'
63
+ });
64
+ (0, _chai.expect)(startDriverLoggingStub.calledOnce).to.equal(true);
65
+ (0, _chai.expect)(navyStub.reconfigure.calledOnce).to.equal(true);
66
+ (0, _chai.expect)(stopDriverLoggingStub.calledOnce).to.equal(true);
67
+ (0, _chai.expect)(startDriverLoggingStub.calledBefore(navyStub.reconfigure)).to.equal(true);
68
+ (0, _chai.expect)(navyStub.reconfigure.calledBefore(stopDriverLoggingStub)).to.equal(true);
69
+ });
70
+ it('should log a success message naming the navy', async function () {
71
+ await refreshConfigCli({
72
+ navy: 'env-1'
73
+ });
74
+ const printed = consoleLogStub.getCalls().map(c => c.args[0] || '').join(' ');
75
+ (0, _chai.expect)(printed).to.contain('Config refreshed');
76
+ (0, _chai.expect)(printed).to.contain('env-1');
77
+ });
78
+ it('should throw an invariant violation when the navy has no config provider', async function () {
79
+ navyStub.getConfigProvider.resolves(null);
80
+ let caught;
81
+ try {
82
+ await refreshConfigCli({
83
+ navy: 'env-1'
84
+ });
85
+ } catch (err) {
86
+ caught = err;
87
+ }
88
+ (0, _chai.expect)(caught).to.be.an('error');
89
+ (0, _chai.expect)(caught.message).to.match(/NO_CONFIG_PROVIDER/);
90
+ (0, _chai.expect)(configProvider.refreshConfig.called).to.equal(false);
91
+ (0, _chai.expect)(navyStub.reconfigure.called).to.equal(false);
92
+ (0, _chai.expect)(startDriverLoggingStub.called).to.equal(false);
93
+ });
94
+ });
95
+ });
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ var _chai = require("chai");
5
+ var _sinon = _interopRequireDefault(require("sinon"));
6
+ var _proxyquire = _interopRequireDefault(require("proxyquire"));
7
+ /* eslint-env mocha */
8
+
9
+ describe('cli/run', function () {
10
+ let sandbox;
11
+ let getNavyStub;
12
+ let navyStub;
13
+ let run;
14
+ beforeEach(function () {
15
+ sandbox = _sinon.default.createSandbox();
16
+ navyStub = {
17
+ ensurePluginsLoaded: sandbox.stub().resolves(),
18
+ invokeCommand: sandbox.stub().resolves()
19
+ };
20
+ getNavyStub = sandbox.stub().returns(navyStub);
21
+ run = _proxyquire.default.noCallThru()('../run', {
22
+ '../': {
23
+ getNavy: getNavyStub
24
+ }
25
+ });
26
+ });
27
+ afterEach(function () {
28
+ sandbox.restore();
29
+ });
30
+ describe('default export', function () {
31
+ it('should resolve the navy instance using opts.navy', async function () {
32
+ await run('cmd', [], {
33
+ navy: 'env-1'
34
+ });
35
+ (0, _chai.expect)(getNavyStub.calledOnce).to.equal(true);
36
+ (0, _chai.expect)(getNavyStub.firstCall.args[0]).to.equal('env-1');
37
+ });
38
+ it('should call ensurePluginsLoaded before invokeCommand', async function () {
39
+ await run('cmd', ['a'], {
40
+ navy: 'env-1'
41
+ });
42
+ (0, _chai.expect)(navyStub.ensurePluginsLoaded.calledOnce).to.equal(true);
43
+ (0, _chai.expect)(navyStub.invokeCommand.calledOnce).to.equal(true);
44
+ (0, _chai.expect)(navyStub.ensurePluginsLoaded.calledBefore(navyStub.invokeCommand)).to.equal(true);
45
+ });
46
+ it('should pass through name and args to invokeCommand', async function () {
47
+ await run('migrate', ['--up', 'db'], {
48
+ navy: 'env-1'
49
+ });
50
+ (0, _chai.expect)(navyStub.invokeCommand.firstCall.args[0]).to.equal('migrate');
51
+ (0, _chai.expect)(navyStub.invokeCommand.firstCall.args[1]).to.eql(['--up', 'db']);
52
+ });
53
+ });
54
+ });
@@ -0,0 +1,204 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ var _chai = require("chai");
5
+ var _sinon = _interopRequireDefault(require("sinon"));
6
+ var _proxyquire = _interopRequireDefault(require("proxyquire"));
7
+ var _stripAnsi = _interopRequireDefault(require("strip-ansi"));
8
+ /* eslint-env mocha */
9
+
10
+ describe('cli/status', function () {
11
+ let sandbox;
12
+ let getLaunchedNaviesStub;
13
+ let getConfigStub;
14
+ let consoleLogStub;
15
+ let statusCli;
16
+ function makeNavy(overrides = {}) {
17
+ return {
18
+ name: 'env-1',
19
+ ps: sandbox.stub().resolves([]),
20
+ getState: sandbox.stub().resolves({
21
+ configProvider: 'filesystem'
22
+ }),
23
+ getConfigProvider: sandbox.stub().resolves({
24
+ getLocationDisplayName: sandbox.stub().resolves('/path/to/cfg')
25
+ }),
26
+ url: sandbox.stub().callsFake(async svc => `http://${svc}.local`),
27
+ ...overrides
28
+ };
29
+ }
30
+ beforeEach(function () {
31
+ sandbox = _sinon.default.createSandbox();
32
+ getLaunchedNaviesStub = sandbox.stub().resolves([]);
33
+ getConfigStub = sandbox.stub().resolves({
34
+ defaultNavy: 'env-1'
35
+ });
36
+ consoleLogStub = sandbox.stub(console, 'log');
37
+ statusCli = _proxyquire.default.noCallThru()('../status', {
38
+ '../': {
39
+ getLaunchedNavies: getLaunchedNaviesStub
40
+ },
41
+ '../config': {
42
+ getConfig: getConfigStub
43
+ }
44
+ });
45
+ });
46
+ afterEach(function () {
47
+ sandbox.restore();
48
+ });
49
+ function combinedLog() {
50
+ return consoleLogStub.getCalls().map(c => String(c.args[0] || '')).join('\n');
51
+ }
52
+ describe('default export', function () {
53
+ it('should render an empty table when there are no navies', async function () {
54
+ getLaunchedNaviesStub.resolves([]);
55
+ await statusCli({});
56
+ (0, _chai.expect)(consoleLogStub.calledOnce).to.equal(true);
57
+ const text = (0, _stripAnsi.default)(consoleLogStub.firstCall.args[0]);
58
+ (0, _chai.expect)(text).to.contain('NAME');
59
+ (0, _chai.expect)(text).to.contain('ACTIVE');
60
+ (0, _chai.expect)(text).to.contain('SERVICES');
61
+ (0, _chai.expect)(text).to.contain('CONFIG PROVIDER');
62
+ (0, _chai.expect)(text).to.contain('CONFIG LOCATION');
63
+ (0, _chai.expect)(text).to.contain('URL');
64
+ });
65
+ it('should mark a navy with at least one running service as active', async function () {
66
+ const navy = makeNavy();
67
+ navy.ps.resolves([{
68
+ name: 'api',
69
+ status: 'running'
70
+ }, {
71
+ name: 'db',
72
+ status: 'exited'
73
+ }]);
74
+ getLaunchedNaviesStub.resolves([navy]);
75
+ await statusCli({});
76
+ const text = (0, _stripAnsi.default)(combinedLog());
77
+ (0, _chai.expect)(text).to.contain('yes');
78
+ (0, _chai.expect)(text).to.contain('2');
79
+ });
80
+ it('should mark a navy with no running services as inactive', async function () {
81
+ const navy = makeNavy();
82
+ navy.ps.resolves([{
83
+ name: 'api',
84
+ status: 'exited'
85
+ }]);
86
+ getLaunchedNaviesStub.resolves([navy]);
87
+ await statusCli({});
88
+ const text = (0, _stripAnsi.default)(combinedLog());
89
+ (0, _chai.expect)(text).to.contain('no');
90
+ (0, _chai.expect)(text).to.contain('1');
91
+ });
92
+ it('should highlight the default navy with (default)', async function () {
93
+ const navy = makeNavy({
94
+ name: 'env-1'
95
+ });
96
+ getLaunchedNaviesStub.resolves([navy]);
97
+ getConfigStub.resolves({
98
+ defaultNavy: 'env-1'
99
+ });
100
+ await statusCli({});
101
+ const text = (0, _stripAnsi.default)(combinedLog());
102
+ (0, _chai.expect)(text).to.contain('env-1');
103
+ (0, _chai.expect)(text).to.contain('(default)');
104
+ });
105
+ it('should not highlight non-default navies as default', async function () {
106
+ const navy = makeNavy({
107
+ name: 'env-2'
108
+ });
109
+ getLaunchedNaviesStub.resolves([navy]);
110
+ getConfigStub.resolves({
111
+ defaultNavy: 'env-1'
112
+ });
113
+ await statusCli({});
114
+ const text = (0, _stripAnsi.default)(combinedLog());
115
+ (0, _chai.expect)(text).to.contain('env-2');
116
+ (0, _chai.expect)(text).not.to.contain('(default)');
117
+ });
118
+ it('should include the config provider name and the config location', async function () {
119
+ const navy = makeNavy();
120
+ navy.getState.resolves({
121
+ configProvider: 'filesystem'
122
+ });
123
+ navy.getConfigProvider.resolves({
124
+ getLocationDisplayName: sandbox.stub().resolves('/etc/navy')
125
+ });
126
+ getLaunchedNaviesStub.resolves([navy]);
127
+ await statusCli({});
128
+ const text = (0, _stripAnsi.default)(combinedLog());
129
+ (0, _chai.expect)(text).to.contain('filesystem');
130
+ (0, _chai.expect)(text).to.contain('/etc/navy');
131
+ });
132
+ it('should call navy.url with the dimmed "service" placeholder for the table column', async function () {
133
+ const navy = makeNavy();
134
+ getLaunchedNaviesStub.resolves([navy]);
135
+ await statusCli({});
136
+ (0, _chai.expect)(navy.url.calledOnce).to.equal(true);
137
+ (0, _chai.expect)((0, _stripAnsi.default)(navy.url.firstCall.args[0])).to.equal('service');
138
+ });
139
+ it('should print JSON when opts.json is true', async function () {
140
+ const navy = makeNavy({
141
+ name: 'env-1'
142
+ });
143
+ navy.ps.resolves([{
144
+ name: 'api',
145
+ status: 'running'
146
+ }]);
147
+ navy.getState.resolves({
148
+ configProvider: 'filesystem'
149
+ });
150
+ navy.getConfigProvider.resolves({
151
+ getLocationDisplayName: sandbox.stub().resolves('/cfg/location')
152
+ });
153
+ navy.url.resolves('http://[service].local');
154
+ getLaunchedNaviesStub.resolves([navy]);
155
+ await statusCli({
156
+ json: true
157
+ });
158
+ (0, _chai.expect)(consoleLogStub.calledOnce).to.equal(true);
159
+ const parsed = JSON.parse(consoleLogStub.firstCall.args[0]);
160
+ (0, _chai.expect)(parsed).to.be.an('array').with.lengthOf(1);
161
+ (0, _chai.expect)(parsed[0]).to.deep.include({
162
+ name: 'env-1',
163
+ isActive: true,
164
+ configProvider: 'filesystem',
165
+ configLocation: '/cfg/location',
166
+ url: 'http://[service].local'
167
+ });
168
+ (0, _chai.expect)(parsed[0].services).to.be.an('array').with.lengthOf(1);
169
+ (0, _chai.expect)(parsed[0].state).to.deep.equal({
170
+ configProvider: 'filesystem'
171
+ });
172
+ });
173
+ it('should mark JSON output as inactive when no services are running', async function () {
174
+ const navy = makeNavy();
175
+ navy.ps.resolves([{
176
+ name: 'api',
177
+ status: 'exited'
178
+ }]);
179
+ getLaunchedNaviesStub.resolves([navy]);
180
+ await statusCli({
181
+ json: true
182
+ });
183
+ const parsed = JSON.parse(consoleLogStub.firstCall.args[0]);
184
+ (0, _chai.expect)(parsed[0].isActive).to.equal(false);
185
+ });
186
+ it('should not call getConfig when running in json mode', async function () {
187
+ const navy = makeNavy();
188
+ getLaunchedNaviesStub.resolves([navy]);
189
+ await statusCli({
190
+ json: true
191
+ });
192
+ (0, _chai.expect)(getConfigStub.called).to.equal(false);
193
+ });
194
+ it('should pass [service] (not chalk-dim "service") to navy.url when in json mode', async function () {
195
+ const navy = makeNavy();
196
+ getLaunchedNaviesStub.resolves([navy]);
197
+ await statusCli({
198
+ json: true
199
+ });
200
+ (0, _chai.expect)(navy.url.calledOnce).to.equal(true);
201
+ (0, _chai.expect)(navy.url.firstCall.args[0]).to.equal('[service]');
202
+ });
203
+ });
204
+ });