diff --git a/.eslintrc.js b/.eslintrc.js index 6f72f754..16f94483 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -31,6 +31,7 @@ module.exports = { excludedFiles: [ 'app/**', 'addon/**', + 'test/fixtures/**', 'tests/dummy/app/**' ], parserOptions: { diff --git a/.travis.yml b/.travis.yml index 6d0aafed..ae7e33f3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,11 @@ --- language: node_js node_js: - - "4" - "6" + - "8" -dist: trusty sudo: false +dist: trusty addons: chrome: stable @@ -17,13 +17,13 @@ stages: - lint - test - deploy - + jobs: fail_fast: true - + include: - stage: lint - script: yarn lint:js + script: npm run-script lint:js - stage: deploy if: tag IS present node_js: "6" @@ -46,4 +46,4 @@ install: - yarn install --no-lockfile --non-interactive script: - - yarn node-test + - npm run-script node-test diff --git a/app/utils/my-covered-util.js b/app/utils/my-covered-util.js deleted file mode 100644 index 4c33e85b..00000000 --- a/app/utils/my-covered-util.js +++ /dev/null @@ -1 +0,0 @@ -export { default } from 'ember-cli-code-coverage/utils/my-covered-util'; diff --git a/app/utils/my-uncovered-util.js b/app/utils/my-uncovered-util.js deleted file mode 100644 index 5ff69ce4..00000000 --- a/app/utils/my-uncovered-util.js +++ /dev/null @@ -1,2 +0,0 @@ -export { default } from 'ember-cli-code-coverage/utils/my-uncovered-util'; - diff --git a/index.js b/index.js index 814c614e..1d1c5dc4 100644 --- a/index.js +++ b/index.js @@ -93,13 +93,6 @@ module.exports = { }); }, - treeFor() { - // Only include test fixtures when testing the addon. - if (this._parentName() === this.name) { - return this._super.treeFor.apply(this, arguments); - } - }, - // Custom Methods /** diff --git a/package.json b/package.json index 3c10edf6..ef2c651a 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "chai": "^4.1.2", "chai-files": "^1.2.0", "ember-cli": "~3.0.0-beta.2", + "ember-cli-addon-tests": "^0.11.0", "ember-cli-dependency-checker": "^2.0.0", "ember-cli-eslint": "^4.2.1", "ember-cli-htmlbars": "^2.0.1", diff --git a/addon/utils/my-covered-util.js b/test/fixtures/my-addon/addon/utils/my-covered-util.js similarity index 100% rename from addon/utils/my-covered-util.js rename to test/fixtures/my-addon/addon/utils/my-covered-util.js diff --git a/addon/utils/my-uncovered-util.js b/test/fixtures/my-addon/addon/utils/my-uncovered-util.js similarity index 100% rename from addon/utils/my-uncovered-util.js rename to test/fixtures/my-addon/addon/utils/my-uncovered-util.js diff --git a/test/fixtures/my-addon/app/utils/my-covered-util.js b/test/fixtures/my-addon/app/utils/my-covered-util.js new file mode 100644 index 00000000..b32e61dc --- /dev/null +++ b/test/fixtures/my-addon/app/utils/my-covered-util.js @@ -0,0 +1 @@ +export { default } from '../../addon/utils/my-covered-util'; diff --git a/test/fixtures/my-addon/app/utils/my-uncovered-util.js b/test/fixtures/my-addon/app/utils/my-uncovered-util.js new file mode 100644 index 00000000..bef567b1 --- /dev/null +++ b/test/fixtures/my-addon/app/utils/my-uncovered-util.js @@ -0,0 +1,2 @@ +export { default } from '../../addon/utils/my-uncovered-util'; + diff --git a/test/fixtures/my-app/.eslintrc.js b/test/fixtures/my-app/.eslintrc.js new file mode 100644 index 00000000..08d7cee5 --- /dev/null +++ b/test/fixtures/my-app/.eslintrc.js @@ -0,0 +1,43 @@ +module.exports = { + root: true, + parserOptions: { + ecmaVersion: 2017, + sourceType: 'module' + }, + extends: [ + 'eslint:recommended' + ], + env: { + browser: true + }, + rules: { + }, + overrides: [ + // node files + { + files: [ + 'index.js', + 'testem.js', + 'ember-cli-build.js', + 'config/**/*.js', + 'lib/**', + 'test/**', + 'tests/dummy/config/**/*.js' + ], + excludedFiles: [ + 'app/**', + 'addon/**', + 'test/fixtures/**', + 'tests/dummy/app/**' + ], + parserOptions: { + sourceType: 'script', + ecmaVersion: 2015 + }, + env: { + browser: false, + node: true + } + } + ] +}; diff --git a/test/fixtures/my-app/app/utils/my-covered-util.js b/test/fixtures/my-app/app/utils/my-covered-util.js new file mode 100644 index 00000000..50867b0d --- /dev/null +++ b/test/fixtures/my-app/app/utils/my-covered-util.js @@ -0,0 +1,3 @@ +export default function myCoveredUtil() { + return true; +} diff --git a/test/fixtures/my-app/app/utils/my-uncovered-util.js b/test/fixtures/my-app/app/utils/my-uncovered-util.js new file mode 100644 index 00000000..8f531cba --- /dev/null +++ b/test/fixtures/my-app/app/utils/my-uncovered-util.js @@ -0,0 +1,3 @@ +export default function myUncoveredUtil() { + return true; +} diff --git a/test/fixtures/my-app/testem.js b/test/fixtures/my-app/testem.js new file mode 100644 index 00000000..d1755a4e --- /dev/null +++ b/test/fixtures/my-app/testem.js @@ -0,0 +1,24 @@ +module.exports = { + test_page: 'tests/index.html?hidepassed', + disable_watching: true, + launch_in_ci: [ + 'Chrome' + ], + launch_in_dev: [ + 'Chrome' + ], + browser_args: { + Chrome: { + mode: 'ci', + args: [ + // --no-sandbox is needed when running Chrome inside a container + process.env.TRAVIS ? '--no-sandbox' : null, + + '--disable-gpu', + '--headless', + '--remote-debugging-port=0', + '--window-size=1440,900' + ].filter(Boolean) + } + } +}; diff --git a/test/fixtures/my-app/tests/unit/.gitkeep b/test/fixtures/my-app/tests/unit/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/test/fixtures/my-app/tests/unit/utils/my-covered-util-test.js b/test/fixtures/my-app/tests/unit/utils/my-covered-util-test.js new file mode 100644 index 00000000..9f998b4d --- /dev/null +++ b/test/fixtures/my-app/tests/unit/utils/my-covered-util-test.js @@ -0,0 +1,10 @@ +import myCoveredUtil from 'my-app/utils/my-covered-util'; +import { module, test } from 'qunit'; + +module('Unit | Utility | my covered util'); + +// Replace this with your real tests. +test('it works', function(assert) { + let result = myCoveredUtil(); + assert.ok(result); +}); diff --git a/test/helpers/run-command.js b/test/helpers/run-command.js deleted file mode 100644 index 48066c9a..00000000 --- a/test/helpers/run-command.js +++ /dev/null @@ -1,33 +0,0 @@ -'use strict'; - -var RSVP = require('rsvp'); -var spawn = require('child_process').spawn; - -module.exports = function runCommand(command, args, opts) { - opts = opts || {}; - - opts.stdio = opts.stdio || 'inherit'; - - var newENV = {}; - var item, envOption; - - for (item in process.env) { - newENV[item] = process.env[item]; - } - for (envOption in opts.env) { - newENV[envOption] = opts.env[envOption]; - } - - opts.env = newENV; - - return new RSVP.Promise(function(resolve, reject) { - var p = spawn(command, args, opts); - p.on('close', function(code) { - if (code !== 0) { - reject(new Error('Command ' + command + ' ' + args.join(' ') + ' exited ' + code)); - } else { - resolve(); - } - }); - }); -}; diff --git a/test/integration/app-coverage-test.js b/test/integration/app-coverage-test.js new file mode 100644 index 00000000..87a29f9a --- /dev/null +++ b/test/integration/app-coverage-test.js @@ -0,0 +1,111 @@ +'use strict'; + +var fs = require('fs-extra'); +var RSVP = require('rsvp'); +var rimraf = RSVP.denodeify(require('rimraf')); +var chai = require('chai'); +var expect = chai.expect; +var chaiFiles = require('chai-files'); +var dir = chaiFiles.dir; +var file = chaiFiles.file; + +const AddonTestApp = require('ember-cli-addon-tests').AddonTestApp; + +chai.use(chaiFiles); + +let app; + +describe('app coverage generation', function() { + this.timeout(10000000); + beforeEach(function() { + app = new AddonTestApp(); + return app.create('my-app', { + emberVersion: '2.16.0' + }).then(() => { + app.editPackageJSON(pkg => { + pkg.devDependencies['ember-exam'] = '0.7.0'; + }); + return app.run('npm', 'install').then(() => { + return rimraf(`${app.path}/coverage*`); + }); + }); + }); + + afterEach(function() { + return RSVP.all([ + rimraf(`${app.path}/config/coverage.js`) + ]); + }); + + it('runs coverage when env var is set', function() { + expect(dir(`${app.path}/coverage`)).to.not.exist; + process.env.COVERAGE = true; + return app.run('ember', 'test').then(function() { + expect(file(`${app.path}/coverage/lcov-report/index.html`)).to.not.be.empty; + expect(file(`${app.path}/coverage/index.html`)).to.not.be.empty; + var summary = fs.readJSONSync(`${app.path}/coverage/coverage-summary.json`); + expect(summary.total.lines.pct).to.equal(83.33); + }); + }); + + it('does not run coverage when env var is NOT set', function() { + expect(dir(`${app.path}/coverage`)).to.not.exist; + process.env.COVERAGE = false; + return app.run('ember', 'test').then(function() { + expect(dir(`${app.path}/coverage`)).to.not.exist; + }); + }); + + it('excludes files when the configuration is set', function() { + fs.copySync('tests/dummy/config/coverage-excludes.js', `${app.path}/config/coverage.js`); + process.env.COVERAGE = true; + return app.run('ember', 'test').then(function() { + expect(file(`${app.path}/coverage/lcov-report/index.html`)).to.not.be.empty; + expect(file(`${app.path}/coverage/index.html`)).to.not.be.empty; + var summary = fs.readJSONSync(`${app.path}/coverage/coverage-summary.json`); + expect(summary.total.lines.pct).to.equal(100); + }); + }); + + it('uses parallel configuration and merges coverage when merge-coverage command is issued', function() { + expect(dir(`${app.path}/coverage`)).to.not.exist; + fs.copySync('tests/dummy/config/coverage-parallel.js', `${app.path}/config/coverage.js`); + process.env.COVERAGE = true; + return app.run('ember', 'exam', '--split=2', '--parallel=true').then(function() { + expect(dir(`${app.path}/coverage`)).to.not.exist; + return app.run('ember', 'coverage-merge'); + }).then(function() { + expect(file(`${app.path}/coverage/lcov-report/index.html`)).to.not.be.empty; + expect(file(`${app.path}/coverage/index.html`)).to.not.be.empty; + var summary = fs.readJSONSync(`${app.path}/coverage/coverage-summary.json`); + expect(summary.total.lines.pct).to.equal(83.33); + }); + }); + + it('uses nested coverageFolder and parallel configuration and run merge-coverage', function() { + var coverageFolder = `${app.path}/coverage/abc/easy-as/123`; + + expect(dir(coverageFolder)).to.not.exist; + fs.copySync('tests/dummy/config/coverage-nested-folder.js', `${app.path}/config/coverage.js`); + process.env.COVERAGE = true; + return app.run('ember', 'exam', '--split=2', '--parallel=true').then(function() { + expect(dir(coverageFolder)).to.not.exist; + return app.run('ember', 'coverage-merge'); + }).then(function() { + expect(file(`${coverageFolder}/lcov-report/index.html`)).to.not.be.empty; + expect(file(`${coverageFolder}/index.html`)).to.not.be.empty; + var summary = fs.readJSONSync(`${coverageFolder}/coverage-summary.json`); + expect(summary.total.lines.pct).to.equal(83.33); + }); + }); + + it('runs coverage when a module has an import error', function() { + expect(dir(`${app.path}/coverage`)).to.not.exist; + fs.copySync('test/helpers/error-module.js', `${app.path}/app/error-module.js`); + process.env.COVERAGE = true; + return app.run('ember', 'test').then(function() { + expect(dir(`${app.path}/coverage`)).to.exist; + return rimraf(`${app.path}/app/error-module.js`); + }); + }); +}); diff --git a/test/integration/coverage-test.js b/test/integration/coverage-test.js deleted file mode 100644 index 1c60fe54..00000000 --- a/test/integration/coverage-test.js +++ /dev/null @@ -1,100 +0,0 @@ -'use strict'; - -var fs = require('fs-extra'); -var RSVP = require('rsvp'); -var rimraf = RSVP.denodeify(require('rimraf')); -var runCommand = require('../helpers/run-command'); -var chai = require('chai'); -var expect = chai.expect; -var chaiFiles = require('chai-files'); -var dir = chaiFiles.dir; -var file = chaiFiles.file; - -chai.use(chaiFiles); - -describe('`ember test`', function() { - beforeEach(function() { - return rimraf('coverage*') - }); - - afterEach(function() { - return RSVP.all([ - rimraf('tests/dummy/config/coverage.js'), - rimraf('tests/dummy/app/routes/index.js') - ]); - }); - - it('runs coverage when env var is set', function() { - this.timeout(100000); - expect(dir('coverage')).to.not.exist; - return runCommand('ember', ['test'], {env: {COVERAGE: true}}).then(function() { - expect(file('coverage/lcov-report/index.html')).to.not.be.empty; - expect(file('coverage/index.html')).to.not.be.empty; - var summary = fs.readJSONSync('coverage/coverage-summary.json'); - expect(summary.total.lines.pct).to.equal(50); - }); - }); - - it('does not run coverage when env var is NOT set', function() { - this.timeout(100000); - expect(dir('coverage')).to.not.exist; - return runCommand('ember', ['test']).then(function() { - expect(dir('coverage')).to.not.exist; - }); - }); - - it('excludes files when the configuration is set', function() { - this.timeout(100000); - fs.copySync('tests/dummy/config/coverage-excludes.js', 'tests/dummy/config/coverage.js'); - return runCommand('ember', ['test'], {env: {COVERAGE: true}}).then(function() { - expect(file('coverage/lcov-report/index.html')).to.not.be.empty; - expect(file('coverage/index.html')).to.not.be.empty; - var summary = fs.readJSONSync('coverage/coverage-summary.json'); - expect(summary.total.lines.pct).to.equal(100); - }); - }); - - it('uses parallel configuration and merges coverage when merge-coverage command is issued', function() { - this.timeout(100000); - expect(dir('coverage')).to.not.exist; - fs.copySync('tests/dummy/config/coverage-parallel.js', 'tests/dummy/config/coverage.js'); - return runCommand('ember', ['exam', '--split=2', '--parallel=true'], {env: {COVERAGE: true}}).then(function() { - expect(dir('coverage')).to.not.exist; - return runCommand('ember', ['coverage-merge']); - }).then(function() { - expect(file('coverage/lcov-report/index.html')).to.not.be.empty; - expect(file('coverage/index.html')).to.not.be.empty; - var summary = fs.readJSONSync('coverage/coverage-summary.json'); - expect(summary.total.lines.pct).to.equal(50); - }); - }); - - it('uses nested coverageFolder and parallel configuration and run merge-coverage', function() { - this.timeout(100000); - var coverageFolder = 'coverage/abc/easy-as/123'; - - expect(dir(coverageFolder)).to.not.exist; - fs.copySync('tests/dummy/config/coverage-nested-folder.js', 'tests/dummy/config/coverage.js'); - return runCommand('ember', ['exam', '--split=2', '--parallel=true'], {env: {COVERAGE: true}}).then(function() { - expect(dir(coverageFolder)).to.not.exist; - return runCommand('ember', ['coverage-merge']); - }).then(function() { - expect(file(coverageFolder + '/lcov-report/index.html')).to.not.be.empty; - expect(file(coverageFolder + '/index.html')).to.not.be.empty; - var summary = fs.readJSONSync(coverageFolder + '/coverage-summary.json'); - expect(summary.total.lines.pct).to.equal(50); - }); - }); - - it('runs coverage when a module has an import error', function() { - this.timeout(100000); - expect(dir('coverage')).to.not.exist; - fs.copySync('test/helpers/error-module.js', 'addon/error-module.js'); - return runCommand('ember', ['test'], {env: {COVERAGE: true}}).then(function() { - expect(dir('coverage')).to.exist; - }).finally(function() { - rimraf('addon/error-module.js'); - }); - }); - -}); diff --git a/test/unit/index-test.js b/test/unit/index-test.js index 8bdb034b..d4f24c22 100644 --- a/test/unit/index-test.js +++ b/test/unit/index-test.js @@ -115,11 +115,11 @@ describe('index.js', function() { describe('_getIncludes', function() { beforeEach(function() { - sandbox.stub(Index, 'project').value({ root: process.cwd() }); + sandbox.stub(Index, 'project').value({ root: 'test/fixtures/my-addon/' }); }); it('gets files to include from the app directory', function() { - Index._getIncludes('app', 'my-app'); + Index._getIncludes('test/fixtures/my-addon/app', 'my-app'); expect(Index.fileLookup).to.deep.equal({ 'my-app/utils/my-covered-util.js': 'app/utils/my-covered-util.js', 'my-app/utils/my-uncovered-util.js': 'app/utils/my-uncovered-util.js' @@ -127,7 +127,7 @@ describe('index.js', function() { }); it('gets files to include from the addon directory', function() { - Index._getIncludes('addon', 'my-addon'); + Index._getIncludes('test/fixtures/my-addon/addon', 'my-addon'); expect(Index.fileLookup).to.deep.equal({ 'my-addon/utils/my-covered-util.js': 'addon/utils/my-covered-util.js', 'my-addon/utils/my-uncovered-util.js': 'addon/utils/my-uncovered-util.js' @@ -334,7 +334,7 @@ describe('index.js', function() { beforeEach(function() { sandbox.stub(Index, 'IstanbulPlugin').value('istanbul'); sandbox.stub(Index, '_getExcludes').returns([]); - sandbox.stub(Index, 'project').value({ root: process.cwd() }); + sandbox.stub(Index, 'project').value({ root: 'test/fixtures/my-addon/' }); sandbox.stub(Index, 'parent').value({ name() { return 'my-app' }, }); @@ -499,7 +499,7 @@ describe('index.js', function() { ] } }, - root: process.cwd(), + root: 'test/fixtures/my-addon/', findAddonByName() { return addon; } }); }); diff --git a/testem.js b/testem.js index 50aea2b0..d1755a4e 100644 --- a/testem.js +++ b/testem.js @@ -11,12 +11,14 @@ module.exports = { Chrome: { mode: 'ci', args: [ + // --no-sandbox is needed when running Chrome inside a container process.env.TRAVIS ? '--no-sandbox' : null, + '--disable-gpu', '--headless', '--remote-debugging-port=0', '--window-size=1440,900' - ] + ].filter(Boolean) } } }; diff --git a/tests/dummy/app/utils/my-covered-util.js b/tests/dummy/app/utils/my-covered-util.js new file mode 100644 index 00000000..50867b0d --- /dev/null +++ b/tests/dummy/app/utils/my-covered-util.js @@ -0,0 +1,3 @@ +export default function myCoveredUtil() { + return true; +} diff --git a/tests/dummy/app/utils/my-uncovered-util.js b/tests/dummy/app/utils/my-uncovered-util.js new file mode 100644 index 00000000..8f531cba --- /dev/null +++ b/tests/dummy/app/utils/my-uncovered-util.js @@ -0,0 +1,3 @@ +export default function myUncoveredUtil() { + return true; +} diff --git a/yarn.lock b/yarn.lock index d4fa9a74..4eb5952d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3,8 +3,8 @@ "@ember/test-helpers@^0.7.9": - version "0.7.14" - resolved "https://registry.yarnpkg.com/@ember/test-helpers/-/test-helpers-0.7.14.tgz#e53b0a66f144a0a85579c4432e56960971a3f739" + version "0.7.16" + resolved "https://registry.yarnpkg.com/@ember/test-helpers/-/test-helpers-0.7.16.tgz#73a4acf4c7d1b92ce866f4c9e40c9723da4cf1e8" dependencies: broccoli-funnel "^2.0.1" ember-cli-babel "^6.10.0" @@ -993,8 +993,8 @@ broccoli-asset-rewrite@^1.1.0: broccoli-filter "^1.2.3" broccoli-babel-transpiler@^6.0.0, broccoli-babel-transpiler@^6.1.2: - version "6.1.2" - resolved "https://registry.yarnpkg.com/broccoli-babel-transpiler/-/broccoli-babel-transpiler-6.1.2.tgz#26019c045b5ea3e44cfef62821302f9bd483cabd" + version "6.1.3" + resolved "https://registry.yarnpkg.com/broccoli-babel-transpiler/-/broccoli-babel-transpiler-6.1.3.tgz#f70553d832083b2cbec843e8268210e0c283e6e9" dependencies: babel-core "^6.14.0" broccoli-funnel "^1.0.0" @@ -1892,7 +1892,7 @@ debug@2.3.3: dependencies: ms "0.7.2" -debug@3.1.0, debug@^3.1.0: +debug@3.1.0, debug@^3.0.0, debug@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" dependencies: @@ -1971,6 +1971,10 @@ delegates@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" +denodeify@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/denodeify/-/denodeify-1.2.1.tgz#3a36287f5034e699e7577901052c2e6c94251631" + depd@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.1.tgz#5783b4e1c459f06fa5ca27f991f3d06e7a310359" @@ -2051,8 +2055,22 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" electron-to-chromium@^1.3.30: - version "1.3.31" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.31.tgz#00d832cba9fe2358652b0c48a8816c8e3a037e9f" + version "1.3.32" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.32.tgz#11d0684c0840e003c4be8928f8ac5f35dbc2b4e6" + +ember-cli-addon-tests@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/ember-cli-addon-tests/-/ember-cli-addon-tests-0.11.0.tgz#7f5a07ce91317b9b06c792274e6d6a2cc43f1ee9" + dependencies: + chalk "^2.0.1" + debug "^3.0.0" + denodeify "^1.2.1" + findup-sync "^2.0.0" + fs-extra "^4.0.2" + lodash "^4.0.0" + semver "^5.3.0" + symlink-or-copy "^1.1.3" + temp "^0.8.3" ember-cli-babel@^6.0.0-beta.4, ember-cli-babel@^6.0.0-beta.7, ember-cli-babel@^6.10.0, ember-cli-babel@^6.3.0, ember-cli-babel@^6.6.0, ember-cli-babel@^6.8.1: version "6.11.0" @@ -2974,7 +2992,7 @@ find-up@^2.1.0: dependencies: locate-path "^2.0.0" -findup-sync@2.0.0: +findup-sync@2.0.0, findup-sync@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-2.0.0.tgz#9326b1488c22d1a6088650a86901b2d9a90a2cbc" dependencies: @@ -4594,7 +4612,7 @@ lodash@^3.10.1: version "3.10.1" resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" -lodash@^4.14.0, lodash@^4.17.4, lodash@^4.3.0, lodash@^4.6.1: +lodash@^4.0.0, lodash@^4.14.0, lodash@^4.17.4, lodash@^4.3.0, lodash@^4.6.1: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" @@ -6457,7 +6475,7 @@ supports-color@^5.1.0: dependencies: has-flag "^2.0.0" -symlink-or-copy@^1.0.0, symlink-or-copy@^1.0.1, symlink-or-copy@^1.1.8: +symlink-or-copy@^1.0.0, symlink-or-copy@^1.0.1, symlink-or-copy@^1.1.3, symlink-or-copy@^1.1.8: version "1.1.8" resolved "https://registry.yarnpkg.com/symlink-or-copy/-/symlink-or-copy-1.1.8.tgz#cabe61e0010c1c023c173b25ee5108b37f4b4aa3" @@ -6502,7 +6520,7 @@ tar@^2.2.1: fstream "^1.0.2" inherits "2" -temp@0.8.3: +temp@0.8.3, temp@^0.8.3: version "0.8.3" resolved "https://registry.yarnpkg.com/temp/-/temp-0.8.3.tgz#e0c6bc4d26b903124410e4fed81103014dfc1f59" dependencies: