diff --git a/.gitignore b/.gitignore index c6befdab3fb..64683de2978 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ build dist node_modules +coverage npm-debug.log # Signing Identity @@ -19,4 +20,4 @@ cache settings.json # IDEs -.idea \ No newline at end of file +.idea diff --git a/.jshintrc b/.jshintrc index 9240a3ae9fa..daeaf45072b 100644 --- a/.jshintrc +++ b/.jshintrc @@ -27,5 +27,5 @@ "jest": true, "pit": true }, - "predef": [ "-Promise" ] + "predef": [ "Promise" ] } diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000000..dabf9318079 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,13 @@ +language: node_js +node_js: + - "0.10" + +sudo: false + +cache: + directories: + - resources + - node_modules + +after_success: + - which ./node_modules/coveralls/bin/coveralls.js && cat coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js diff --git a/README.md b/README.md index 834ac194ec0..f363f71fe74 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ -[![CircleCI](https://img.shields.io/circleci/project/kitematic/kitematic.svg)](https://circleci.com/gh/kitematic/kitematic/tree/master) +[![Build Status](https://travis-ci.org/kitematic/kitematic.svg?branch=master)](https://travis-ci.org/kitematic/kitematic) +[![Coverage Status](https://coveralls.io/repos/kitematic/kitematic/badge.svg?branch=master)](https://coveralls.io/r/kitematic/kitematic?branch=master) [![bitHound Score](https://app.bithound.io/kitematic/kitematic/badges/score.svg)](http://app.bithound.io/kitematic/kitematic) [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/kitematic/kitematic?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) diff --git a/circle.yml b/circle.yml index 0ddf9ac841d..99331471694 100644 --- a/circle.yml +++ b/circle.yml @@ -5,3 +5,6 @@ dependencies: cache_directories: - "resources" - "node_modules" +notify: + webhooks: + - url: https://coveralls.io/webhook diff --git a/package.json b/package.json index 060c0a72e6b..34f55d73ad2 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "bugs": "https://github.com/kitematic/kitematic/issues", "scripts": { "start": "gulp", - "test": "jest", + "test": "jest --coverage", "release": "gulp release", "release:beta": "gulp release --beta", "lint": "jsxhint src && jsxhint browser", @@ -27,16 +27,21 @@ "jest": { "scriptPreprocessor": "/util/preprocessor.js", "setupEnvScriptFile": "/util/testenv.js", + "collectCoverage": true, + "testDirectoryName": "src", + "testPathIgnorePatterns": [ + "/node_modules/", + "^((?!-test).)*$" + ], "unmockedModulePathPatterns": [ + "stream", "tty", "net", "crypto", - "stream", + "/node_modules/.*JSONStream", "/node_modules/object-assign", "/node_modules/underscore", - "/node_modules/react", - "/node_modules/bluebird", - "/node_modules/babel" + "/node_modules/bluebird" ] }, "docker-version": "1.5.0", @@ -53,7 +58,8 @@ "async": "^0.9.0", "bluebird": "^2.9.12", "bugsnag-js": "^2.4.7", - "dockerode": "^2.0.7", + "coveralls": "^2.11.2", + "dockerode": "^2.1.1", "exec": "0.2.0", "fs-extra": "^0.17.0", "fs-promise": "^0.3.1", @@ -81,6 +87,7 @@ "gulp-cssmin": "^0.1.6", "gulp-download-atom-shell": "0.0.4", "gulp-if": "^1.2.5", + "gulp-insert": "^0.4.0", "gulp-less": "^3.0.1", "gulp-livereload": "^3.8.0", "gulp-plumber": "^0.6.6", @@ -89,7 +96,7 @@ "gulp-shell": "^0.3.0", "gulp-sourcemaps": "^1.5.0", "gulp-util": "^3.0.4", - "jest-cli": "^0.4.0", + "jest-cli": "kitematic/jest", "jsxhint": "^0.12.1", "react-tools": "^0.12.2", "run-sequence": "^1.0.2" diff --git a/src/ContainerHome.react.js b/src/ContainerHome.react.js index 0bb752b9990..4cb9df636b6 100644 --- a/src/ContainerHome.react.js +++ b/src/ContainerHome.react.js @@ -74,7 +74,9 @@ var ContainerHome = React.createClass({ if (this.props.error) { body = (
-

There was a problem connecting to the Docker Engine in the VirtualBox VM.
This could be caused because this Mac is currently connected to a VPN, blocking access to the VM. If the issue persists, please file a ticket on our GitHub repo.

+

An error occurred:

+

{this.props.error.statusCode} {this.props.error.reason} - {this.props.error.json}

+

If you feel that this error is invalid, please file a ticket on our GitHub repo.

); diff --git a/src/ContainerHomePreview.react.js b/src/ContainerHomePreview.react.js index 91995c82ef5..880462b1297 100644 --- a/src/ContainerHomePreview.react.js +++ b/src/ContainerHomePreview.react.js @@ -38,9 +38,6 @@ var ContainerHomePreview = React.createClass({ }); } }, - componentDidUpdate: function () { - this.reload(); - }, componentWillUnmount: function() { clearInterval(this.timer); }, diff --git a/src/ContainerList.react.js b/src/ContainerList.react.js index 1d6d25a034f..d2954dc6038 100644 --- a/src/ContainerList.react.js +++ b/src/ContainerList.react.js @@ -9,8 +9,14 @@ var ContainerList = React.createClass({ render: function () { var self = this; var containers = this.props.containers.map(function (container) { + var containerId = container.Id; + if (!containerId && container.State.Downloading) { + // Fall back to the container image name when there is no id. (when the + // image is downloading). + containerId = container.Image; + } return ( - + ); }); var newItem; diff --git a/src/ContainerStore.js b/src/ContainerStore.js index b0cc3940df1..109a022d191 100644 --- a/src/ContainerStore.js +++ b/src/ContainerStore.js @@ -56,6 +56,12 @@ var ContainerStore = assign(Object.create(EventEmitter.prototype), { var data = JSON.parse(str); console.log(data); + if (data.error) { + _error = data.error; + callback(data.error); + return; + } + if (data.status && (data.status === 'Pulling dependent layers' || data.status.indexOf('already being pulled by another client') !== -1)) { blockedCallback(); return; @@ -82,7 +88,8 @@ var ContainerStore = assign(Object.create(EventEmitter.prototype), { progressCallback(totalProgress); }); stream.on('end', function () { - callback(); + callback(_error); + _error = null; }); }); }); diff --git a/src/ImageCard.react.js b/src/ImageCard.react.js index db895f6e322..659d1407e6d 100644 --- a/src/ImageCard.react.js +++ b/src/ImageCard.react.js @@ -31,11 +31,11 @@ var ImageCard = React.createClass({ handleTagOverlayClick: function (name) { var $tagOverlay = $(this.getDOMNode()).find('.tag-overlay'); $tagOverlay.fadeIn(300); - $.get('https://registry.hub.docker.com/v1/repositories/' + name + '/tags', function (result) { + $.get('https://registry.hub.docker.com/v1/repositories/' + name + '/tags', result => { this.setState({ tags: result }); - }.bind(this)); + }); }, handleCloseTagOverlay: function () { var $tagOverlay = $(this.getDOMNode()).find('.tag-overlay'); @@ -50,6 +50,14 @@ var ImageCard = React.createClass({ } util.exec(['open', $repoUri + this.props.image.name]); }, + componentDidMount: function() { + $.get('https://registry.hub.docker.com/v1/repositories/' + this.props.image.name + '/tags', result => { + this.setState({ + tags: result, + chosenTag: result[0].name + }); + }); + }, render: function () { var self = this; var name; diff --git a/__tests__/SetupStore-test.js b/src/SetupStore-test.js similarity index 93% rename from __tests__/SetupStore-test.js rename to src/SetupStore-test.js index b26471e2c87..b8ddc798929 100644 --- a/__tests__/SetupStore-test.js +++ b/src/SetupStore-test.js @@ -1,10 +1,9 @@ -jest.dontMock('../src/SetupStore'); -var setupStore = require('../src/SetupStore'); -var virtualBox = require('../src/VirtualBox'); -var util = require('../src/Util'); -var machine = require('../src/DockerMachine'); -var setupUtil = require('../src/SetupUtil'); -var Promise = require('bluebird'); +jest.dontMock('./SetupStore'); +var setupStore = require('./SetupStore'); +var virtualBox = require('./VirtualBox'); +var util = require('./Util'); +var machine = require('./DockerMachine'); +var setupUtil = require('./SetupUtil'); describe('SetupStore', function () { describe('download step', function () { diff --git a/__tests__/Virtualbox-test.js b/src/Virtualbox-test.js similarity index 76% rename from __tests__/Virtualbox-test.js rename to src/Virtualbox-test.js index 1a8efa7aab3..567210a08ad 100644 --- a/__tests__/Virtualbox-test.js +++ b/src/Virtualbox-test.js @@ -1,7 +1,6 @@ -jest.dontMock('../src/VirtualBox'); -var virtualBox = require('../src/VirtualBox'); -var util = require('../src/Util'); -var Promise = require('bluebird'); +jest.dontMock('./VirtualBox'); +var virtualBox = require('./VirtualBox'); +var util = require('./Util'); describe('VirtualBox', function () { it('returns the right command', function () {