Browse Source

testing: fixing tests

Torkel Ödegaard 8 năm trước cách đây
mục cha
commit
b228c23dbe

+ 4 - 4
package.json

@@ -66,7 +66,7 @@
     "karma-webpack": "^2.0.4",
     "lint-staged": "^4.2.3",
     "load-grunt-tasks": "3.5.2",
-    "mocha": "3.5.0",
+    "mocha": "^4.0.1",
     "ng-annotate-loader": "^0.6.1",
     "ng-annotate-webpack-plugin": "^0.2.1-pre",
     "ngtemplate-loader": "^2.0.1",
@@ -87,8 +87,8 @@
     "tslint-loader": "^3.5.3",
     "typescript": "^2.5.2",
     "webpack": "^3.6.0",
-    "webpack-cleanup-plugin": "^0.5.1",
     "webpack-bundle-analyzer": "^2.9.0",
+    "webpack-cleanup-plugin": "^0.5.1",
     "webpack-merge": "^4.1.0",
     "zone.js": "^0.7.2"
   },
@@ -97,7 +97,7 @@
     "watch": "./node_modules/.bin/webpack --progress --colors --watch --config scripts/webpack/webpack.dev.js",
     "build": "./node_modules/.bin/grunt build",
     "test": "./node_modules/.bin/grunt test",
-    "lint" : "./node_modules/.bin/tslint -c tslint.json --project tsconfig.json --type-check",
+    "lint": "./node_modules/.bin/tslint -c tslint.json --project tsconfig.json --type-check",
     "watch-test": "./node_modules/grunt-cli/bin/grunt karma:dev"
   },
   "license": "Apache-2.0",
@@ -119,9 +119,9 @@
     "mousetrap": "^1.6.0",
     "ngreact": "^0.4.1",
     "react": "^16.0.0",
-    "rxjs": "^5.4.3",
     "react-dom": "^16.0.0",
     "remarkable": "^1.7.1",
+    "rxjs": "^5.4.3",
     "tether": "^1.4.0",
     "tether-drop": "https://github.com/torkelo/drop"
   }

+ 24 - 26
public/app/features/dashboard/specs/history_srv_specs.ts

@@ -21,50 +21,48 @@ describe('historySrv', function() {
         return [200, restoreResponse(parsedData.version)];
       });
   }));
+
   beforeEach(ctx.createService('historySrv'));
 
+  function wrapPromise(ctx, angularPromise) {
+    return new Promise((resolve, reject) => {
+      angularPromise.then(resolve, reject);
+      ctx.$httpBackend.flush();
+    });
+  }
+
   describe('getHistoryList', function() {
-    it('should return a versions array for the given dashboard id', function(done) {
-      ctx.service.getHistoryList({ id: 1 }).then(function(versions) {
+    it('should return a versions array for the given dashboard id', function() {
+      return wrapPromise(ctx, ctx.service.getHistoryList({ id: 1 }).then(function(versions) {
         expect(versions).to.eql(versionsResponse);
-        done();
-      });
-      ctx.$httpBackend.flush();
+      }));
     });
 
-    it('should return an empty array when not given an id', function(done) {
-      ctx.service.getHistoryList({ }).then(function(versions) {
+    it('should return an empty array when not given an id', function() {
+      return wrapPromise(ctx, ctx.service.getHistoryList({ }).then(function(versions) {
         expect(versions).to.eql([]);
-        done();
-      });
-      ctx.$httpBackend.flush();
+      }));
     });
 
-    it('should return an empty array when not given a dashboard', function(done) {
-      ctx.service.getHistoryList().then(function(versions) {
+    it('should return an empty array when not given a dashboard', function() {
+      return wrapPromise(ctx, ctx.service.getHistoryList().then(function(versions) {
         expect(versions).to.eql([]);
-        done();
-      });
-      ctx.$httpBackend.flush();
+      }));
     });
   });
 
   describe('restoreDashboard', function() {
-    it('should return a success response given valid parameters', function(done) {
-      var version = 6;
-      ctx.service.restoreDashboard({ id: 1 }, version).then(function(response) {
+    it('should return a success response given valid parameters', function() {
+      let version = 6;
+      return wrapPromise(ctx, ctx.service.restoreDashboard({ id: 1 }, version).then(function(response) {
         expect(response).to.eql(restoreResponse(version));
-        done();
-      });
-      ctx.$httpBackend.flush();
+      }));
     });
 
-    it('should return an empty object when not given an id', function(done) {
-      ctx.service.restoreDashboard({}, 6).then(function(response) {
+    it('should return an empty object when not given an id', function() {
+      return wrapPromise(ctx, ctx.service.restoreDashboard({}, 6).then(function(response) {
         expect(response).to.eql({});
-        done();
-      });
-      ctx.$httpBackend.flush();
+      }));
     });
   });
 });

+ 2 - 4
public/app/plugins/datasource/prometheus/completer.ts

@@ -33,7 +33,7 @@ export class PromCompleter {
           return;
         }
 
-        this.getLabelNameAndValueForMetric(metricName).then(result => {
+        return this.getLabelNameAndValueForMetric(metricName).then(result => {
           var labelNames = this.transformToCompletions(
             _.uniq(_.flatten(result.map(r => {
               return Object.keys(r.metric);
@@ -42,7 +42,6 @@ export class PromCompleter {
           this.labelNameCache[metricName] = labelNames;
           callback(null, labelNames);
         });
-        return;
       case 'string.quoted':
         metricName = this.findMetricName(session, pos.row, pos.column);
         if (!metricName) {
@@ -62,7 +61,7 @@ export class PromCompleter {
           return;
         }
 
-        this.getLabelNameAndValueForMetric(metricName).then(result => {
+        return this.getLabelNameAndValueForMetric(metricName).then(result => {
           var labelValues = this.transformToCompletions(
             _.uniq(result.map(r => {
               return r.metric[labelName];
@@ -72,7 +71,6 @@ export class PromCompleter {
           this.labelValueCache[metricName][labelName] = labelValues;
           callback(null, labelValues);
         });
-        return;
     }
 
     if (prefix === '[') {

+ 87 - 83
public/app/plugins/datasource/prometheus/specs/completer_specs.ts

@@ -4,111 +4,115 @@ import {PromCompleter} from '../completer';
 import {PrometheusDatasource} from '../datasource';
 
 describe('Prometheus editor completer', function() {
+  function getSessionStub(data) {
+    return {
+      getTokenAt: sinon.stub().returns(data.currentToken),
+      getTokens: sinon.stub().returns(data.tokens),
+      getLine: sinon.stub().returns(data.line),
+    };
+  }
 
-  let sessionData = {
-    currentToken: {},
-    tokens: [],
-    line: ''
-  };
-  let session = {
-    getTokenAt: sinon.stub().returns(sessionData.currentToken),
-    getTokens: sinon.stub().returns(sessionData.tokens),
-    getLine: sinon.stub().returns(sessionData.line),
-  };
-  let editor = { session: session };
-
+  let editor = {};
   let datasourceStub = <PrometheusDatasource>{
-    performInstantQuery: sinon.stub().withArgs({ expr: '{__name__="node_cpu"' }).returns(Promise.resolve(
-      [
-        {
-          metric: {
-            job: 'node',
-            instance: 'localhost:9100'
-          }
-        }
-      ]
-    )),
-    performSuggestQuery: sinon.stub().withArgs('node', true).returns(Promise.resolve(
-      [
-        'node_cpu'
-      ]
-    ))
+    performInstantQuery: sinon
+      .stub()
+      .withArgs({expr: '{__name__="node_cpu"'})
+      .returns(
+        Promise.resolve({
+          data: {
+            data: {
+              result: [
+                {
+                  metric: {
+                    job: 'node',
+                    instance: 'localhost:9100',
+                  },
+                },
+              ],
+            },
+          },
+        }),
+      ),
+    performSuggestQuery: sinon
+      .stub()
+      .withArgs('node', true)
+      .returns(Promise.resolve(['node_cpu'])),
   };
-  let completer = new PromCompleter(datasourceStub);
 
-  describe("When inside brackets", () => {
+  let completer = new PromCompleter(datasourceStub);
 
-    it("Should return range vectors", () => {
-      completer.getCompletions(editor, session, { row: 0, column: 10 }, '[', (s, res) => {
+  describe('When inside brackets', () => {
+    it('Should return range vectors', () => {
+      const session = getSessionStub({
+        currentToken: {},
+        tokens: [],
+        line: '',
+      });
+      completer.getCompletions(editor, session, {row: 0, column: 10}, '[', (s, res) => {
         expect(res[0]).to.eql({caption: '1s', value: '[1s', meta: 'range vector'});
       });
     });
-
   });
 
-  describe("When inside label matcher, and located at label name", () => {
-    sessionData = {
-      currentToken: { type: 'entity.name.tag', value: 'j', index: 2, start: 9 },
-      tokens: [
-        { type: 'identifier', value: 'node_cpu' },
-        { type: 'paren.lparen', value: '{' },
-        { type: 'entity.name.tag', value: 'j', index: 2, start: 9 },
-        { type: 'paren.rparen', value: '}' }
-      ],
-      line: 'node_cpu{j}'
-    };
+  describe('When inside label matcher, and located at label name', () => {
+    it('Should return label name list', () => {
+      const session = getSessionStub({
+        currentToken: {type: 'entity.name.tag', value: 'j', index: 2, start: 9},
+        tokens: [
+          {type: 'identifier', value: 'node_cpu'},
+          {type: 'paren.lparen', value: '{'},
+          {type: 'entity.name.tag', value: 'j', index: 2, start: 9},
+          {type: 'paren.rparen', value: '}'},
+        ],
+        line: 'node_cpu{j}',
+      });
 
-    it("Should return label name list", () => {
-      completer.getCompletions(editor, session, { row: 0, column: 10 }, 'j', (s, res) => {
-        expect(res[0]).to.eql({caption: 'job', value: 'job', meta: 'label name'});
+      return completer.getCompletions(editor, session, {row: 0, column: 10}, 'j', (s, res) => {
+        expect(res[0].meta).to.eql('label name');
       });
     });
-
   });
 
-  describe("When inside label matcher, and located at label name with __name__ match", () => {
-    sessionData = {
-      currentToken: { type: 'entity.name.tag', value: 'j', index: 5, start: 22 },
-      tokens: [
-        { type: 'paren.lparen', value: '{' },
-        { type: 'entity.name.tag', value: '__name__' },
-        { type: 'keyword.operator', value: '=~' },
-        { type: 'string.quoted', value: '"node_cpu"' },
-        { type: 'punctuation.operator', value: ',' },
-        { type: 'entity.name.tag', value: 'j', 'index': 5, 'start': 22 },
-        { type: 'paren.rparen', value: '}' }
-      ],
-      line: '{__name__=~"node_cpu",j}'
-    };
+  describe('When inside label matcher, and located at label name with __name__ match', () => {
+    it('Should return label name list', () => {
+      const session = getSessionStub({
+        currentToken: {type: 'entity.name.tag', value: 'j', index: 5, start: 22},
+        tokens: [
+          {type: 'paren.lparen', value: '{'},
+          {type: 'entity.name.tag', value: '__name__'},
+          {type: 'keyword.operator', value: '=~'},
+          {type: 'string.quoted', value: '"node_cpu"'},
+          {type: 'punctuation.operator', value: ','},
+          {type: 'entity.name.tag', value: 'j', index: 5, start: 22},
+          {type: 'paren.rparen', value: '}'},
+        ],
+        line: '{__name__=~"node_cpu",j}',
+      });
 
-    it("Should return label name list", () => {
-      completer.getCompletions(editor, session, { row: 0, column: 23 }, 'j', (s, res) => {
-        expect(res[0]).to.eql({caption: 'job', value: 'job', meta: 'label name'});
+      return completer.getCompletions(editor, session, {row: 0, column: 23}, 'j', (s, res) => {
+        expect(res[0].meta).to.eql('label name');
       });
     });
-
   });
 
-  describe("When inside label matcher, and located at label value", () => {
-    sessionData = {
-      currentToken: { type: 'string.quoted', value: '"n"', index: 4, start: 13 },
-      tokens: [
-        { type: 'identifier', value: 'node_cpu' },
-        { type: 'paren.lparen', value: '{' },
-        { type: 'entity.name.tag', value: 'job' },
-        { type: 'keyword.operator', value: '=' },
-        { type: 'string.quoted', value: '"n"', index: 4, start: 13 },
-        { type: 'paren.rparen', value: '}' }
-      ],
-      line: 'node_cpu{job="n"}'
-    };
+  describe('When inside label matcher, and located at label value', () => {
+    it('Should return label value list', () => {
+      const session = getSessionStub({
+        currentToken: {type: 'string.quoted', value: '"n"', index: 4, start: 13},
+        tokens: [
+          {type: 'identifier', value: 'node_cpu'},
+          {type: 'paren.lparen', value: '{'},
+          {type: 'entity.name.tag', value: 'job'},
+          {type: 'keyword.operator', value: '='},
+          {type: 'string.quoted', value: '"n"', index: 4, start: 13},
+          {type: 'paren.rparen', value: '}'},
+        ],
+        line: 'node_cpu{job="n"}',
+      });
 
-    it("Should return label value list", () => {
-      completer.getCompletions(editor, session, { row: 0, column: 15 }, 'n', (s, res) => {
-        expect(res[0]).to.eql({caption: 'node', value: 'node', meta: 'label value'});
+      return completer.getCompletions(editor, session, {row: 0, column: 15}, 'n', (s, res) => {
+        expect(res[0].meta).to.eql('label value');
       });
     });
-
   });
-
 });

+ 2 - 1
public/test/specs/helpers.js

@@ -103,7 +103,7 @@ define([
     };
 
     this.createService = function(name) {
-      return window.inject(function($q, $rootScope, $httpBackend, $injector, $location) {
+      return window.inject(function($q, $rootScope, $httpBackend, $injector, $location, $timeout) {
         self.$q = $q;
         self.$rootScope = $rootScope;
         self.$httpBackend =  $httpBackend;
@@ -111,6 +111,7 @@ define([
 
         self.$rootScope.onAppEvent = function() {};
         self.$rootScope.appEvent = function() {};
+        self.$timeout = $timeout;
 
         self.service = $injector.get(name);
       });

+ 1 - 1
scripts/webpack/webpack.dev.js

@@ -10,7 +10,7 @@ const WebpackCleanupPlugin = require('webpack-cleanup-plugin');
 const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
 
 module.exports = merge(common, {
-  devtool: "source-map",
+  devtool: "eval-source-map",
 
   entry: {
     dark: './public/sass/grafana.dark.scss',

+ 34 - 95
yarn.lock

@@ -1700,7 +1700,7 @@ combined-stream@^1.0.5, combined-stream@~1.0.5:
   dependencies:
     delayed-stream "~1.0.0"
 
-commander@2.11.x, commander@~2.11.0:
+commander@2.11.0, commander@2.11.x, commander@~2.11.0:
   version "2.11.0"
   resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563"
 
@@ -1710,7 +1710,7 @@ commander@2.8.x:
   dependencies:
     graceful-readlink ">= 1.0.0"
 
-commander@2.9.0, commander@2.9.x, commander@^2.8.1, commander@^2.9.0, commander@~2.9.0:
+commander@2.9.x, commander@^2.8.1, commander@^2.9.0, commander@~2.9.0:
   version "2.9.0"
   resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4"
   dependencies:
@@ -2134,9 +2134,9 @@ debug@2.3.3:
   dependencies:
     ms "0.7.2"
 
-debug@2.6.8:
-  version "2.6.8"
-  resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc"
+debug@3.1.0:
+  version "3.1.0"
+  resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
   dependencies:
     ms "2.0.0"
 
@@ -2255,14 +2255,18 @@ di@^0.0.1:
   version "0.0.1"
   resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c"
 
-diff@3.2.0, diff@^3.2.0:
-  version "3.2.0"
-  resolved "https://registry.yarnpkg.com/diff/-/diff-3.2.0.tgz#c9ce393a4b7cbd0b058a725c93df299027868ff9"
+diff@3.3.1:
+  version "3.3.1"
+  resolved "https://registry.yarnpkg.com/diff/-/diff-3.3.1.tgz#aa8567a6eed03c531fc89d3f711cd0e5259dec75"
 
 diff@^2.0.2:
   version "2.2.3"
   resolved "https://registry.yarnpkg.com/diff/-/diff-2.2.3.tgz#60eafd0d28ee906e4e8ff0a52c1229521033bf99"
 
+diff@^3.2.0:
+  version "3.2.0"
+  resolved "https://registry.yarnpkg.com/diff/-/diff-3.2.0.tgz#c9ce393a4b7cbd0b058a725c93df299027868ff9"
+
 diffie-hellman@^5.0.0:
   version "5.0.2"
   resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.2.tgz#b5835739270cfe26acf632099fded2a07f209e5e"
@@ -3352,14 +3356,14 @@ glob-parent@^2.0.0:
   dependencies:
     is-glob "^2.0.0"
 
-glob@7.1.1:
-  version "7.1.1"
-  resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8"
+glob@7.1.2, glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@~7.1.1, glob@~7.1.2:
+  version "7.1.2"
+  resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
   dependencies:
     fs.realpath "^1.0.0"
     inflight "^1.0.4"
     inherits "2"
-    minimatch "^3.0.2"
+    minimatch "^3.0.4"
     once "^1.3.0"
     path-is-absolute "^1.0.0"
 
@@ -3373,17 +3377,6 @@ glob@^5.0.1, glob@^5.0.15, glob@~5.0.0:
     once "^1.3.0"
     path-is-absolute "^1.0.0"
 
-glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@~7.1.1, glob@~7.1.2:
-  version "7.1.2"
-  resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
-  dependencies:
-    fs.realpath "^1.0.0"
-    inflight "^1.0.4"
-    inherits "2"
-    minimatch "^3.0.4"
-    once "^1.3.0"
-    path-is-absolute "^1.0.0"
-
 glob@~7.0.0:
   version "7.0.6"
   resolved "https://registry.yarnpkg.com/glob/-/glob-7.0.6.tgz#211bafaf49e525b8cd93260d14ab136152b3f57a"
@@ -3454,9 +3447,9 @@ graceful-fs@^4.1.0, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6,
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725"
 
-growl@1.9.2:
-  version "1.9.2"
-  resolved "https://registry.yarnpkg.com/growl/-/growl-1.9.2.tgz#0ea7743715db8d8de2c5ede1775e1b45ac85c02f"
+growl@1.10.3:
+  version "1.10.3"
+  resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.3.tgz#1926ba90cf3edfe2adb4927f5880bc22c66c790f"
 
 grunt-angular-templates@^1.1.0:
   version "1.1.0"
@@ -3772,7 +3765,7 @@ hawk@3.1.3, hawk@~3.1.3:
     hoek "2.x.x"
     sntp "1.x.x"
 
-he@1.1.x:
+he@1.1.1, he@1.1.x:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd"
 
@@ -4937,21 +4930,6 @@ lockfile@~1.0.3:
   version "1.0.3"
   resolved "https://registry.yarnpkg.com/lockfile/-/lockfile-1.0.3.tgz#2638fc39a0331e9cac1a04b71799931c9c50df79"
 
-lodash._baseassign@^3.0.0:
-  version "3.2.0"
-  resolved "https://registry.yarnpkg.com/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e"
-  dependencies:
-    lodash._basecopy "^3.0.0"
-    lodash.keys "^3.0.0"
-
-lodash._basecopy@^3.0.0:
-  version "3.0.1"
-  resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36"
-
-lodash._basecreate@^3.0.0:
-  version "3.0.3"
-  resolved "https://registry.yarnpkg.com/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz#1bc661614daa7fc311b7d03bf16806a0213cf821"
-
 lodash._baseuniq@~4.6.0:
   version "4.6.0"
   resolved "https://registry.yarnpkg.com/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz#0ebb44e456814af7905c6212fa2c9b2d51b841e8"
@@ -4963,14 +4941,6 @@ lodash._createset@~4.0.0:
   version "4.0.3"
   resolved "https://registry.yarnpkg.com/lodash._createset/-/lodash._createset-4.0.3.tgz#0f4659fbb09d75194fa9e2b88a6644d363c9fe26"
 
-lodash._getnative@^3.0.0:
-  version "3.9.1"
-  resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5"
-
-lodash._isiterateecall@^3.0.0:
-  version "3.0.9"
-  resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c"
-
 lodash._root@~3.0.0:
   version "3.0.1"
   resolved "https://registry.yarnpkg.com/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692"
@@ -4991,38 +4961,14 @@ lodash.clonedeep@^4.3.2, lodash.clonedeep@~4.5.0:
   version "4.5.0"
   resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"
 
-lodash.create@3.1.1:
-  version "3.1.1"
-  resolved "https://registry.yarnpkg.com/lodash.create/-/lodash.create-3.1.1.tgz#d7f2849f0dbda7e04682bb8cd72ab022461debe7"
-  dependencies:
-    lodash._baseassign "^3.0.0"
-    lodash._basecreate "^3.0.0"
-    lodash._isiterateecall "^3.0.0"
-
 lodash.flattendeep@^4.4.0:
   version "4.4.0"
   resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2"
 
-lodash.isarguments@^3.0.0:
-  version "3.1.0"
-  resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a"
-
-lodash.isarray@^3.0.0:
-  version "3.0.4"
-  resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55"
-
 lodash.kebabcase@^4.0.0:
   version "4.1.1"
   resolved "https://registry.yarnpkg.com/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz#8489b1cb0d29ff88195cceca448ff6d6cc295c36"
 
-lodash.keys@^3.0.0:
-  version "3.1.2"
-  resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a"
-  dependencies:
-    lodash._getnative "^3.0.0"
-    lodash.isarguments "^3.0.0"
-    lodash.isarray "^3.0.0"
-
 lodash.memoize@^4.1.2:
   version "4.1.2"
   resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
@@ -5393,21 +5339,20 @@ mkdirp@0.5.1, mkdirp@0.5.x, mkdirp@0.x.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdir
   dependencies:
     minimist "0.0.8"
 
-mocha@3.5.0:
-  version "3.5.0"
-  resolved "https://registry.yarnpkg.com/mocha/-/mocha-3.5.0.tgz#1328567d2717f997030f8006234bce9b8cd72465"
+mocha@^4.0.1:
+  version "4.0.1"
+  resolved "https://registry.yarnpkg.com/mocha/-/mocha-4.0.1.tgz#0aee5a95cf69a4618820f5e51fa31717117daf1b"
   dependencies:
     browser-stdout "1.3.0"
-    commander "2.9.0"
-    debug "2.6.8"
-    diff "3.2.0"
+    commander "2.11.0"
+    debug "3.1.0"
+    diff "3.3.1"
     escape-string-regexp "1.0.5"
-    glob "7.1.1"
-    growl "1.9.2"
-    json3 "3.3.2"
-    lodash.create "3.1.1"
+    glob "7.1.2"
+    growl "1.10.3"
+    he "1.1.1"
     mkdirp "0.5.1"
-    supports-color "3.1.2"
+    supports-color "4.4.0"
 
 moment@^2.18.1:
   version "2.18.1"
@@ -8010,11 +7955,11 @@ strip-json-comments@~2.0.1:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
 
-supports-color@3.1.2:
-  version "3.1.2"
-  resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.1.2.tgz#72a262894d9d408b956ca05ff37b2ed8a6e2a2d5"
+supports-color@4.4.0, supports-color@^4.0.0, supports-color@^4.2.1, supports-color@^4.4.0:
+  version "4.4.0"
+  resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.4.0.tgz#883f7ddabc165142b2a61427f3352ded195d1a3e"
   dependencies:
-    has-flag "^1.0.0"
+    has-flag "^2.0.0"
 
 supports-color@^2.0.0:
   version "2.0.0"
@@ -8026,12 +7971,6 @@ supports-color@^3.1.0, supports-color@^3.2.3:
   dependencies:
     has-flag "^1.0.0"
 
-supports-color@^4.0.0, supports-color@^4.2.1, supports-color@^4.4.0:
-  version "4.4.0"
-  resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.4.0.tgz#883f7ddabc165142b2a61427f3352ded195d1a3e"
-  dependencies:
-    has-flag "^2.0.0"
-
 svgo@^0.7.0:
   version "0.7.2"
   resolved "https://registry.yarnpkg.com/svgo/-/svgo-0.7.2.tgz#9f5772413952135c6fefbf40afe6a4faa88b4bb5"