improve cache help messages snapshot more (#2625)

* snapshot more, remove execa in tests for speed

* sub-command -> command, add snapshot

* restate execa
This commit is contained in:
Ben Kucera
2019-01-25 00:34:58 -05:00
committed by Brian Mann
parent e2705e96dd
commit ef8b240bc0
6 changed files with 205 additions and 65 deletions
+11
View File
@@ -0,0 +1,11 @@
exports['lib/tasks/cache .clear deletes cache folder and everything inside it 1'] = `
[no output]
`
exports['lib/tasks/cache .list lists all versions of cached binary 1'] = `
1.2.3, 2.3.4
`
exports['lib/tasks/cache .path lists path to cache 1'] = `
/.cache/Cypress
`
+96
View File
@@ -255,3 +255,99 @@ exports['cli -v no binary version 1'] = `
Cypress package version: 1.2.3
Cypress binary version: not installed
`
exports['cli unknown option shows help for cache command - unknown option --foo 1'] = `
command: bin/cypress cache --foo
code: 1
failed: true
killed: false
signal: null
timedOut: false
stdout:
-------
error: unknown option: --foo
Usage: cache [command]
Manages the Cypress binary cache
Options:
list list cached binary versions
path print the path to the binary cache
clear delete all cached binaries
-h, --help output usage information
-------
stderr:
-------
-------
`
exports['cli unknown option shows help for cache command - unknown sub-command foo 1'] = `
command: bin/cypress cache foo
code: 1
failed: true
killed: false
signal: null
timedOut: false
stdout:
-------
error: unknown command: cache foo
Usage: cache [command]
Manages the Cypress binary cache
Options:
list list cached binary versions
path print the path to the binary cache
clear delete all cached binaries
-h, --help output usage information
-------
stderr:
-------
-------
`
exports['cli unknown option shows help for cache command - no sub-command 1'] = `
command: bin/cypress cache
code: 1
failed: true
killed: false
signal: null
timedOut: false
stdout:
-------
Usage: cache [command]
Manages the Cypress binary cache
Options:
list list cached binary versions
path print the path to the binary cache
clear delete all cached binaries
-h, --help output usage information
-------
stderr:
-------
-------
`
+10 -6
View File
@@ -15,8 +15,7 @@ function unknownOption (flag, type = 'option') {
logger.error(` error: unknown ${type}:`, flag)
logger.error()
this.outputHelp()
logger.error()
process.exit(1)
util.exit(1)
}
commander.Command.prototype.unknownOption = unknownOption
@@ -62,9 +61,9 @@ const descriptions = {
dev: 'runs cypress in development and bypasses binary check',
forceInstall: 'force install the Cypress binary',
exit: 'keep the browser open after tests finish',
cachePath: 'print the cypress binary cache path',
cacheList: 'list the currently cached versions',
cacheClear: 'delete the Cypress binary cache',
cachePath: 'print the path to the binary cache',
cacheList: 'list cached binary versions',
cacheClear: 'delete all cached binaries',
group: 'a named group for recorded runs in the Cypress dashboard',
parallel: 'enables concurrent runs and automatic load balancing of specs across multiple machines or processes',
ciBuildId: 'the unique identifier for a run on your CI provider. typically a "BUILD_ID" env var. this value is automatically detected for most CI providers',
@@ -203,8 +202,13 @@ module.exports = {
.option('path', text('cachePath'))
.option('clear', text('cacheClear'))
.action(function (opts) {
if (!_.isString(opts)) {
this.outputHelp()
util.exit(1)
}
if (opts.command || !_.includes(['list', 'path', 'clear'], opts)) {
unknownOption.call(this, `cache ${opts}`, 'sub-command')
unknownOption.call(this, `cache ${opts}`, 'command')
}
cache[opts]()
+63 -55
View File
@@ -1,5 +1,6 @@
require('../spec_helper')
const os = require('os')
const cli = require(`${lib}/cli`)
const util = require(`${lib}/util`)
const logger = require(`${lib}/logger`)
@@ -11,13 +12,14 @@ const install = require(`${lib}/tasks/install`)
const snapshot = require('snap-shot-it')
const execa = require('execa-wrap')
describe('cli', function () {
describe('cli', () => {
require('mocha-banner').register()
beforeEach(function () {
beforeEach(() => {
logger.reset()
sinon.stub(process, 'exit')
sinon.stub(util, 'exit')
os.platform.returns('darwin')
// sinon.stub(util, 'exit')
sinon.stub(util, 'logErrorExit1')
this.exec = (args) => {
return cli.init(`node test ${args}`.split(' '))
@@ -30,48 +32,54 @@ describe('cli', function () {
return execa('bin/cypress', ['open', '--foo']).then((result) => {
snapshot('shows help for open --foo', result)
})
}
)
})
it('shows help for run command', () => {
return execa('bin/cypress', ['run', '--foo']).then((result) => {
snapshot('shows help for run --foo', result)
})
}
)
})
it('shows help for cache command - unknown option --foo', () => {
return execa('bin/cypress', ['cache', '--foo']).then(snapshot)
})
it('shows help for cache command - unknown sub-command foo', () => {
return execa('bin/cypress', ['cache', 'foo']).then(snapshot)
})
it('shows help for cache command - no sub-command', () => {
return execa('bin/cypress', ['cache']).then(snapshot)
})
})
context('help command', () => {
it('shows help', () => {
return execa('bin/cypress', ['help']).then(snapshot)
}
)
})
it('shows help for -h', () => {
return execa('bin/cypress', ['-h']).then(snapshot)
}
)
})
it('shows help for --help', () => {
return execa('bin/cypress', ['--help']).then(snapshot)
}
)
})
})
context('unknown command', () => {
it('shows usage and exits', () => {
return execa('bin/cypress', ['foo']).then(snapshot)
}
)
})
})
context('cypress version', function () {
context('cypress version', () => {
const binaryDir = '/binary/dir'
beforeEach(function () {
beforeEach(() => {
sinon.stub(state, 'getBinaryDir').returns(binaryDir)
})
it('reports package version', function (done) {
it('reports package version', (done) => {
sinon.stub(util, 'pkgVersion').returns('1.2.3')
sinon.stub(state, 'getBinaryPkgVersionAsync').withArgs(binaryDir).resolves('X.Y.Z')
@@ -82,7 +90,7 @@ describe('cli', function () {
})
})
it('reports package and binary message', function (done) {
it('reports package and binary message', (done) => {
sinon.stub(util, 'pkgVersion').returns('1.2.3')
sinon.stub(state, 'getBinaryPkgVersionAsync').resolves('X.Y.Z')
@@ -93,7 +101,7 @@ describe('cli', function () {
})
})
it('handles non-existent binary version', function (done) {
it('handles non-existent binary version', (done) => {
sinon.stub(util, 'pkgVersion').returns('1.2.3')
sinon.stub(state, 'getBinaryPkgVersionAsync').resolves(null)
@@ -104,7 +112,7 @@ describe('cli', function () {
})
})
it('handles non-existent binary --version', function (done) {
it('handles non-existent binary --version', (done) => {
sinon.stub(util, 'pkgVersion').returns('1.2.3')
sinon.stub(state, 'getBinaryPkgVersionAsync').resolves(null)
@@ -115,7 +123,7 @@ describe('cli', function () {
})
})
it('handles non-existent binary -v', function (done) {
it('handles non-existent binary -v', (done) => {
sinon.stub(util, 'pkgVersion').returns('1.2.3')
sinon.stub(state, 'getBinaryPkgVersionAsync').resolves(null)
@@ -127,13 +135,13 @@ describe('cli', function () {
})
})
context('cypress run', function () {
beforeEach(function () {
context('cypress run', () => {
beforeEach(() => {
sinon.stub(run, 'start').resolves(0)
util.exit.withArgs(0)
sinon.stub(util, 'exit').withArgs(0)
})
it('calls run.start with options + exits with code', function (done) {
it('calls run.start with options + exits with code', (done) => {
run.start.resolves(10)
this.exec('run')
@@ -143,7 +151,7 @@ describe('cli', function () {
})
})
it('run.start with options + catches errors', function (done) {
it('run.start with options + catches errors', (done) => {
const err = new Error('foo')
run.start.rejects(err)
@@ -155,110 +163,110 @@ describe('cli', function () {
})
})
it('calls run with port', function () {
it('calls run with port', () => {
this.exec('run --port 7878')
expect(run.start).to.be.calledWith({ port: '7878' })
})
it('calls run with spec', function () {
it('calls run with spec', () => {
this.exec('run --spec cypress/integration/foo_spec.js')
expect(run.start).to.be.calledWith({ spec: 'cypress/integration/foo_spec.js' })
})
it('calls run with port with -p arg', function () {
it('calls run with port with -p arg', () => {
this.exec('run -p 8989')
expect(run.start).to.be.calledWith({ port: '8989' })
})
it('calls run with env variables', function () {
it('calls run with env variables', () => {
this.exec('run --env foo=bar,host=http://localhost:8888')
expect(run.start).to.be.calledWith({ env: 'foo=bar,host=http://localhost:8888' })
})
it('calls run with config', function () {
it('calls run with config', () => {
this.exec('run --config watchForFileChanges=false,baseUrl=localhost')
expect(run.start).to.be.calledWith({ config: 'watchForFileChanges=false,baseUrl=localhost' })
})
it('calls run with key', function () {
it('calls run with key', () => {
this.exec('run --key asdf')
expect(run.start).to.be.calledWith({ key: 'asdf' })
})
it('calls run with --record', function () {
it('calls run with --record', () => {
this.exec('run --record')
expect(run.start).to.be.calledWith({ record: true })
})
it('calls run with --record false', function () {
it('calls run with --record false', () => {
this.exec('run --record false')
expect(run.start).to.be.calledWith({ record: false })
})
it('calls run with relative --project folder', function () {
it('calls run with relative --project folder', () => {
this.exec('run --project foo/bar')
expect(run.start).to.be.calledWith({ project: 'foo/bar' })
})
it('calls run with absolute --project folder', function () {
it('calls run with absolute --project folder', () => {
this.exec('run --project /tmp/foo/bar')
expect(run.start).to.be.calledWith({ project: '/tmp/foo/bar' })
})
it('calls run with headed', function () {
it('calls run with headed', () => {
this.exec('run --headed')
expect(run.start).to.be.calledWith({ headed: true })
})
it('calls run with --no-exit', function () {
it('calls run with --no-exit', () => {
this.exec('run --no-exit')
expect(run.start).to.be.calledWith({ exit: false })
})
it('calls run with --parallel', function () {
it('calls run with --parallel', () => {
this.exec('run --parallel')
expect(run.start).to.be.calledWith({ parallel: true })
})
it('calls runs with --ci-build-id', function () {
it('calls runs with --ci-build-id', () => {
this.exec('run --ci-build-id 123')
expect(run.start).to.be.calledWith({ ciBuildId: '123' })
})
it('calls runs with --group', function () {
it('calls runs with --group', () => {
this.exec('run --group staging')
expect(run.start).to.be.calledWith({ group: 'staging' })
})
})
context('cypress open', function () {
beforeEach(function () {
context('cypress open', () => {
beforeEach(() => {
sinon.stub(open, 'start').resolves(0)
})
it('calls open.start with relative --project folder', function () {
it('calls open.start with relative --project folder', () => {
this.exec('open --project foo/bar')
expect(open.start).to.be.calledWith({ project: 'foo/bar' })
})
it('calls open.start with absolute --project folder', function () {
it('calls open.start with absolute --project folder', () => {
this.exec('open --project /tmp/foo/bar')
expect(open.start).to.be.calledWith({ project: '/tmp/foo/bar' })
})
it('calls open.start with options', function () {
it('calls open.start with options', () => {
// sinon.stub(open, 'start').resolves()
this.exec('open --port 7878')
expect(open.start).to.be.calledWith({ port: '7878' })
})
it('calls open.start with global', function () {
it('calls open.start with global', () => {
// sinon.stub(open, 'start').resolves()
this.exec('open --port 7878 --global')
expect(open.start).to.be.calledWith({ port: '7878', global: true })
})
it('calls open.start + catches errors', function (done) {
it('calls open.start + catches errors', (done) => {
const err = new Error('foo')
open.start.rejects(err)
@@ -271,19 +279,19 @@ describe('cli', function () {
})
})
it('install calls install.start without forcing', function () {
it('install calls install.start without forcing', () => {
sinon.stub(install, 'start').resolves()
this.exec('install')
expect(install.start).not.to.be.calledWith({ force: true })
})
it('install calls install.start with force: true when passed', function () {
it('install calls install.start with force: true when passed', () => {
sinon.stub(install, 'start').resolves()
this.exec('install --force')
expect(install.start).to.be.calledWith({ force: true })
})
it('install calls install.start + catches errors', function (done) {
it('install calls install.start + catches errors', (done) => {
const err = new Error('foo')
sinon.stub(install, 'start').rejects(err)
@@ -294,15 +302,15 @@ describe('cli', function () {
done()
})
})
context('cypress verify', function () {
context('cypress verify', () => {
it('verify calls verify.start with force: true', function () {
it('verify calls verify.start with force: true', () => {
sinon.stub(verify, 'start').resolves()
this.exec('verify')
expect(verify.start).to.be.calledWith({ force: true, welcomeMessage: false })
})
it('verify calls verify.start + catches errors', function (done) {
it('verify calls verify.start + catches errors', (done) => {
const err = new Error('foo')
sinon.stub(verify, 'start').rejects(err)
+4
View File
@@ -6,6 +6,7 @@ const fs = require(`${lib}/fs`)
const state = require(`${lib}/tasks/state`)
const cache = require(`${lib}/tasks/cache`)
const stdout = require('../../support/stdout')
const snapshot = require('snap-shot-it')
describe('lib/tasks/cache', () => {
beforeEach(() => {
@@ -24,6 +25,9 @@ describe('lib/tasks/cache', () => {
})
afterEach(() => {
mockfs.restore()
this.stdout = this.stdout.toString().split('\n').slice(0, -2).join('\n')
snapshot(this.stdout.toString() || '[no output]')
stdout.restore()
})
+21 -4
View File
@@ -45,28 +45,33 @@ describe('lib/tasks/download', function () {
context('download url', () => {
it('returns url', () => {
const url = download.getUrl()
la(is.url(url), url)
})
it('returns latest desktop url', () => {
const url = download.getUrl()
snapshot('latest desktop url', normalize(url))
})
it('returns specific desktop version url', () => {
const url = download.getUrl('0.20.2')
snapshot('specific version desktop url', normalize(url))
})
it('returns input if it is already an https link', () => {
const url = 'https://somewhere.com'
const result = download.getUrl(url)
expect(result).to.equal(url)
})
it('returns input if it is already an http link', () => {
const url = 'http://local.com'
const result = download.getUrl(url)
expect(result).to.equal(url)
})
})
@@ -75,24 +80,28 @@ describe('lib/tasks/download', function () {
it('env var', () => {
process.env.CYPRESS_DOWNLOAD_MIRROR = 'https://cypress.example.com'
const url = download.getUrl('0.20.2')
snapshot('base url from CYPRESS_DOWNLOAD_MIRROR', normalize(url))
})
it('env var with trailing slash', () => {
process.env.CYPRESS_DOWNLOAD_MIRROR = 'https://cypress.example.com/'
const url = download.getUrl('0.20.2')
snapshot('base url from CYPRESS_DOWNLOAD_MIRROR with trailing slash', normalize(url))
})
it('env var with subdirectory', () => {
process.env.CYPRESS_DOWNLOAD_MIRROR = 'https://cypress.example.com/example'
const url = download.getUrl('0.20.2')
snapshot('base url from CYPRESS_DOWNLOAD_MIRROR with subdirectory', normalize(url))
})
it('env var with subdirectory and trailing slash', () => {
process.env.CYPRESS_DOWNLOAD_MIRROR = 'https://cypress.example.com/example/'
const url = download.getUrl('0.20.2')
snapshot('base url from CYPRESS_DOWNLOAD_MIRROR with subdirectory and trailing slash', normalize(url))
})
})
@@ -100,7 +109,9 @@ describe('lib/tasks/download', function () {
it('saves example.zip to options.downloadDestination', function () {
nock('https://aws.amazon.com')
.get('/some.zip')
.reply(200, () => fs.createReadStream('test/fixture/example.zip'))
.reply(200, () => {
return fs.createReadStream('test/fixture/example.zip')
})
nock('https://download.cypress.io')
.get('/desktop/1.2.3')
@@ -110,7 +121,6 @@ describe('lib/tasks/download', function () {
'x-version': '0.11.1',
})
const onProgress = sinon.stub().returns(undefined)
return download.start({
@@ -120,6 +130,7 @@ describe('lib/tasks/download', function () {
})
.then((responseVersion) => {
expect(responseVersion).to.eq('0.11.1')
return fs.statAsync(downloadDestination)
})
})
@@ -127,7 +138,9 @@ describe('lib/tasks/download', function () {
it('resolves with response x-version if present', function () {
nock('https://aws.amazon.com')
.get('/some.zip')
.reply(200, () => fs.createReadStream('test/fixture/example.zip'))
.reply(200, () => {
return fs.createReadStream('test/fixture/example.zip')
})
nock('https://download.cypress.io')
.get('/desktop/1.2.3')
@@ -147,7 +160,9 @@ describe('lib/tasks/download', function () {
nock('https://aws.amazon.com')
.get('/some.zip')
.reply(200, () => fs.createReadStream('test/fixture/example.zip'))
.reply(200, () => {
return fs.createReadStream('test/fixture/example.zip')
})
nock('https://download.cypress.io')
.get('/desktop/0.13.0')
@@ -159,6 +174,7 @@ describe('lib/tasks/download', function () {
return download.start(this.options).then((responseVersion) => {
expect(responseVersion).to.eq('0.13.0')
return fs.statAsync(downloadDestination)
})
})
@@ -167,6 +183,7 @@ describe('lib/tasks/download', function () {
const ctx = this
const err = new Error()
err.statusCode = 404
err.statusMessage = 'Not Found'
this.options.version = null