From a89cdb0dc6dd5b27dbff82900c42b14ffceb41d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20D?= Date: Mon, 17 Aug 2015 01:19:38 +0200 Subject: [PATCH] Add coverage --- .gitignore | 16 +-- .istanbul.yml | 4 + README.md | 28 +++- dist/kmeans.js | 344 -------------------------------------------- dist/kmeans.min.js | 1 - lib/cluster.js | 62 -------- lib/helpers.js | 70 --------- lib/index.js | 45 ------ lib/point.js | 36 ----- lib/tools/index.js | 13 -- lib/tools/unique.js | 22 --- package.json | 23 ++- test/mocha.opts | 1 - 13 files changed, 40 insertions(+), 625 deletions(-) create mode 100644 .istanbul.yml delete mode 100644 dist/kmeans.js delete mode 100644 dist/kmeans.min.js delete mode 100644 lib/cluster.js delete mode 100644 lib/helpers.js delete mode 100644 lib/index.js delete mode 100644 lib/point.js delete mode 100644 lib/tools/index.js delete mode 100644 lib/tools/unique.js diff --git a/.gitignore b/.gitignore index a72b52e..f204804 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,5 @@ -lib-cov -*.seed *.log -*.csv -*.dat -*.out -*.pid -*.gz - -pids -logs -results - -npm-debug.log node_modules +dist +lib +coverage diff --git a/.istanbul.yml b/.istanbul.yml new file mode 100644 index 0000000..034c410 --- /dev/null +++ b/.istanbul.yml @@ -0,0 +1,4 @@ +# used for istanbul/isparta to care only about src +# otherwise it crashes https://github.com/douglasduteil/isparta/issues/47 +instrumentation: + root: src diff --git a/README.md b/README.md index 493c8ab..90e16ae 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Simple implementation of the k-means clustering method. -# How to use +### How to use ```javascript import kmeans, { Point } from 'algo-kmeans'; @@ -28,7 +28,7 @@ const clusters = kmeans(points, { }); ``` -# Install +### Install With [npm](https://npmjs.org) do: @@ -36,11 +36,29 @@ With [npm](https://npmjs.org) do: npm install algo-kmeans ``` -# Testing +### Commands ``` -npm test +Lifecycle scripts included in algo-kmeans: + test + _mocha --compilers js:babel/register + prepublish + npm run build && npm run build:umd + +available via `npm run-script`: + build + babel src --out-dir lib + clean + rimraf lib dist + build:umd + webpack src/index.js dist/kmeans.js && set NODE_ENV=production&& webpack src/index.js dist/kmeans.min.js + test:watch + _mocha watch + test:cov + babel-node ./node_modules/isparta/bin/isparta cover ./node_modules/mocha/bin/_mocha + lint + eslint src test ``` -# License +### License MIT diff --git a/dist/kmeans.js b/dist/kmeans.js deleted file mode 100644 index 941cc62..0000000 --- a/dist/kmeans.js +++ /dev/null @@ -1,344 +0,0 @@ -(function webpackUniversalModuleDefinition(root, factory) { - if(typeof exports === 'object' && typeof module === 'object') - module.exports = factory(); - else if(typeof define === 'function' && define.amd) - define(factory); - else if(typeof exports === 'object') - exports["kmeans"] = factory(); - else - root["kmeans"] = factory(); -})(this, function() { -return /******/ (function(modules) { // webpackBootstrap -/******/ // The module cache -/******/ var installedModules = {}; - -/******/ // The require function -/******/ function __webpack_require__(moduleId) { - -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) -/******/ return installedModules[moduleId].exports; - -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ exports: {}, -/******/ id: moduleId, -/******/ loaded: false -/******/ }; - -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); - -/******/ // Flag the module as loaded -/******/ module.loaded = true; - -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } - - -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; - -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; - -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = ""; - -/******/ // Load entry module and return exports -/******/ return __webpack_require__(0); -/******/ }) -/************************************************************************/ -/******/ ([ -/* 0 */ -/***/ function(module, exports, __webpack_require__) { - - 'use strict'; - - exports.__esModule = true; - - function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - - var _helpers = __webpack_require__(3); - - var _cluster = __webpack_require__(1); - - var _cluster2 = _interopRequireDefault(_cluster); - - var _point = __webpack_require__(2); - - var _point2 = _interopRequireDefault(_point); - - exports.Point = _point2['default']; - exports.Cluster = _cluster2['default']; - - exports['default'] = function (points, _ref) { - var nbClusters = _ref.nbClusters; - var initCentroids = _ref.initCentroids; - - var clusters = _helpers.initClusters(points, { - nbClusters: nbClusters, - initCentroids: initCentroids - }); - - var assignToNearest = function assignToNearest(p) { - _helpers.assignToNearestCluster(clusters, p); - }; - - do { - clusters.forEach(function (c) { - return c.dirty = false; - }); - points.forEach(assignToNearest); - clusters.forEach(function (c) { - return c.computeCentroid(); - }); - } while (clusters.some(function (c) { - return c.dirty; - })); - - return clusters; - }; - -/***/ }, -/* 1 */ -/***/ function(module, exports, __webpack_require__) { - - 'use strict'; - - exports.__esModule = true; - - function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - - function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } - - var _point = __webpack_require__(2); - - var _point2 = _interopRequireDefault(_point); - - var Cluster = (function () { - function Cluster(centroid) { - _classCallCheck(this, Cluster); - - this.centroid = centroid; - this.points = []; - this.dirty = false; - } - - Cluster.prototype.contains = function contains(point) { - for (var i = this.points.length - 1; i >= 0; i--) { - if (this.points[i].equals(point)) { - return true; - } - } - - return false; - }; - - Cluster.prototype.addPoint = function addPoint(point) { - this.points.push(point); - if (point.cluster) { - point.cluster.removePoint(point); - } - point.cluster = this; - this.dirty = true; - }; - - Cluster.prototype.removePoint = function removePoint(point) { - this.points.splice(this.points.indexOf(point), 1); - this.dirty = true; - }; - - Cluster.prototype.computeCentroid = function computeCentroid() { - this.centroid = new _point2['default'](this.points.map(function (p) { - return p.x; - }).reduce(function (a, b) { - return a + b; - }) / this.points.length, this.points.map(function (p) { - return p.y; - }).reduce(function (a, b) { - return a + b; - }) / this.points.length, this.points.map(function (p) { - return p.z; - }).reduce(function (a, b) { - return a + b; - }) / this.points.length); - }; - - return Cluster; - })(); - - exports['default'] = Cluster; - module.exports = exports['default']; - -/***/ }, -/* 2 */ -/***/ function(module, exports) { - - "use strict"; - - exports.__esModule = true; - - function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - - var Point = (function () { - function Point(x, y, z) { - _classCallCheck(this, Point); - - this.x = x; - this.y = y; - this.z = z; - this.cluster = null; - } - - Point.prototype.distanceTo = function distanceTo(point) { - var dx = point.x - this.x; - var dy = point.y - this.y; - var dz = point.z - this.z; - return Math.sqrt(dx * dx + dy * dy + dz * dz); - }; - - Point.prototype.distanceToCentroid = function distanceToCentroid() { - return this.cluster ? this.distanceTo(this.cluster.centroid) : null; - }; - - Point.prototype.equals = function equals(point) { - return this.x === point.x && this.y === point.y && this.z === point.z; - }; - - return Point; - })(); - - exports["default"] = Point; - module.exports = exports["default"]; - -/***/ }, -/* 3 */ -/***/ function(module, exports, __webpack_require__) { - - 'use strict'; - - exports.__esModule = true; - exports.initClusters = initClusters; - exports.assignToNearestCluster = assignToNearestCluster; - - function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - - var _tools = __webpack_require__(4); - - var _cluster = __webpack_require__(1); - - var _cluster2 = _interopRequireDefault(_cluster); - - function initClusters(p, _ref) { - var nbClusters = _ref.nbClusters; - var initCentroids = _ref.initCentroids; - - var clusters = []; - var points = p.slice(); // clone - - function haveClusterWithCentroid(point) { - for (var i = clusters.length - 1; i >= 0; i--) { - if (clusters[i].centroid.equals(point)) { - return true; - } - } - return false; - } - - if (nbClusters) { - // create the clusters with a random centroid inside - var pickRandomPoint = _tools.unique(points); - for (var i = nbClusters - 1; i >= 0; i--) { - var point = pickRandomPoint(); - if (haveClusterWithCentroid(point)) { - i++; - continue; - } - - var cluster = new _cluster2['default'](point); - clusters.push(cluster); - } - - // we need at least the expected number of clusters - if (clusters.length !== nbClusters) { - throw Error('Not enough different point coordinates to create clusters'); - } - } else if (initCentroids) { - clusters = initCentroids.map(function (init) { - return new _cluster2['default'](init); - }); - } - - return clusters; - } - - function assignToNearestCluster(clusters, point) { - var minDistance = null; - var nearestCluster = null; - for (var i = clusters.length - 1; i >= 0; i--) { - var cluster = clusters[i]; - var distance = point.distanceTo(cluster.centroid); - - if (minDistance === null || distance < minDistance) { - minDistance = distance; - nearestCluster = cluster; - } - } - - if (point.cluster !== nearestCluster) { - nearestCluster.addPoint(point); - } - } - -/***/ }, -/* 4 */ -/***/ function(module, exports, __webpack_require__) { - - 'use strict'; - - exports.__esModule = true; - - function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - - var _uniqueJs = __webpack_require__(5); - - var _uniqueJs2 = _interopRequireDefault(_uniqueJs); - - exports['default'] = { - unique: _uniqueJs2['default'] - }; - module.exports = exports['default']; - -/***/ }, -/* 5 */ -/***/ function(module, exports) { - - "use strict"; - - exports.__esModule = true; - exports["default"] = unique; - function swap(array, i, j) { - var tmp = array[i]; - array[i] = array[j]; - array[j] = tmp; - } - - function unique(arr) { - var maxLength = arr.length; - return function () { - // Fisher–Yates - var randomIndex = Math.random() * maxLength-- | 0; - var item = arr[randomIndex]; - swap(arr, randomIndex, maxLength); - return item; - }; - } - - module.exports = exports["default"]; - -/***/ } -/******/ ]) -}); -; \ No newline at end of file diff --git a/dist/kmeans.min.js b/dist/kmeans.min.js deleted file mode 100644 index d9fc446..0000000 --- a/dist/kmeans.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(t,n){"object"==typeof exports&&"object"==typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):"object"==typeof exports?exports.kmeans=n():t.kmeans=n()}(this,function(){return function(t){function n(r){if(e[r])return e[r].exports;var i=e[r]={exports:{},id:r,loaded:!1};return t[r].call(i.exports,i,i.exports,n),i.loaded=!0,i.exports}var e={};return n.m=t,n.c=e,n.p="",n(0)}([function(t,n,e){"use strict";function r(t){return t&&t.__esModule?t:{"default":t}}n.__esModule=!0;var i=e(3),o=e(1),u=r(o),s=e(2),c=r(s);n.Point=c.default,n.Cluster=u.default,n.default=function(t,n){var e=n.nbClusters,r=n.initCentroids,o=i.initClusters(t,{nbClusters:e,initCentroids:r}),u=function(t){i.assignToNearestCluster(o,t)};do o.forEach(function(t){return t.dirty=!1}),t.forEach(u),o.forEach(function(t){return t.computeCentroid()});while(o.some(function(t){return t.dirty}));return o}},function(t,n,e){"use strict";function r(t){return t&&t.__esModule?t:{"default":t}}function i(t,n){if(!(t instanceof n))throw new TypeError("Cannot call a class as a function")}n.__esModule=!0;var o=e(2),u=r(o),s=function(){function t(n){i(this,t),this.centroid=n,this.points=[],this.dirty=!1}return t.prototype.contains=function(t){for(var n=this.points.length-1;n>=0;n--)if(this.points[n].equals(t))return!0;return!1},t.prototype.addPoint=function(t){this.points.push(t),t.cluster&&t.cluster.removePoint(t),t.cluster=this,this.dirty=!0},t.prototype.removePoint=function(t){this.points.splice(this.points.indexOf(t),1),this.dirty=!0},t.prototype.computeCentroid=function(){this.centroid=new u.default(this.points.map(function(t){return t.x}).reduce(function(t,n){return t+n})/this.points.length,this.points.map(function(t){return t.y}).reduce(function(t,n){return t+n})/this.points.length,this.points.map(function(t){return t.z}).reduce(function(t,n){return t+n})/this.points.length)},t}();n.default=s,t.exports=n.default},function(t,n){"use strict";function e(t,n){if(!(t instanceof n))throw new TypeError("Cannot call a class as a function")}n.__esModule=!0;var r=function(){function t(n,r,i){e(this,t),this.x=n,this.y=r,this.z=i,this.cluster=null}return t.prototype.distanceTo=function(t){var n=t.x-this.x,e=t.y-this.y,r=t.z-this.z;return Math.sqrt(n*n+e*e+r*r)},t.prototype.distanceToCentroid=function(){return this.cluster?this.distanceTo(this.cluster.centroid):null},t.prototype.equals=function(t){return this.x===t.x&&this.y===t.y&&this.z===t.z},t}();n.default=r,t.exports=n.default},function(t,n,e){"use strict";function r(t){return t&&t.__esModule?t:{"default":t}}function i(t,n){function e(t){for(var n=o.length-1;n>=0;n--)if(o[n].centroid.equals(t))return!0;return!1}var r=n.nbClusters,i=n.initCentroids,o=[],s=t.slice();if(r){for(var f=u.unique(s),a=r-1;a>=0;a--){var l=f();if(e(l))a++;else{var d=new c.default(l);o.push(d)}}if(o.length!==r)throw Error("Not enough different point coordinates to create clusters")}else i&&(o=i.map(function(t){return new c.default(t)}));return o}function o(t,n){for(var e=null,r=null,i=t.length-1;i>=0;i--){var o=t[i],u=n.distanceTo(o.centroid);(null===e||e>u)&&(e=u,r=o)}n.cluster!==r&&r.addPoint(n)}n.__esModule=!0,n.initClusters=i,n.assignToNearestCluster=o;var u=e(4),s=e(1),c=r(s)},function(t,n,e){"use strict";function r(t){return t&&t.__esModule?t:{"default":t}}n.__esModule=!0;var i=e(5),o=r(i);n.default={unique:o.default},t.exports=n.default},function(t,n){"use strict";function e(t,n,e){var r=t[n];t[n]=t[e],t[e]=r}function r(t){var n=t.length;return function(){var r=Math.random()*n--|0,i=t[r];return e(t,r,n),i}}n.__esModule=!0,n.default=r,t.exports=n.default}])}); \ No newline at end of file diff --git a/lib/cluster.js b/lib/cluster.js deleted file mode 100644 index 82d8616..0000000 --- a/lib/cluster.js +++ /dev/null @@ -1,62 +0,0 @@ -'use strict'; - -exports.__esModule = true; - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } - -var _ = require('./'); - -var Cluster = (function () { - function Cluster(centroid) { - _classCallCheck(this, Cluster); - - this.centroid = centroid; - this.points = []; - this.dirty = false; - } - - Cluster.prototype.contains = function contains(point) { - for (var i = this.points.length - 1; i >= 0; i--) { - if (this.points[i].equals(point)) { - return true; - } - } - - return false; - }; - - Cluster.prototype.addPoint = function addPoint(point) { - this.points.push(point); - if (point.cluster) { - point.cluster.removePoint(point); - } - point.cluster = this; - this.dirty = true; - }; - - Cluster.prototype.removePoint = function removePoint(point) { - this.points.splice(this.points.indexOf(point), 1); - this.dirty = true; - }; - - Cluster.prototype.computeCentroid = function computeCentroid() { - this.centroid = new _.Point(this.points.map(function (p) { - return p.x; - }).reduce(function (a, b) { - return a + b; - }) / this.points.length, this.points.map(function (p) { - return p.y; - }).reduce(function (a, b) { - return a + b; - }) / this.points.length, this.points.map(function (p) { - return p.z; - }).reduce(function (a, b) { - return a + b; - }) / this.points.length); - }; - - return Cluster; -})(); - -exports['default'] = Cluster; -module.exports = exports['default']; \ No newline at end of file diff --git a/lib/helpers.js b/lib/helpers.js deleted file mode 100644 index 7bf16d9..0000000 --- a/lib/helpers.js +++ /dev/null @@ -1,70 +0,0 @@ -'use strict'; - -exports.__esModule = true; -exports.initClusters = initClusters; -exports.assignToNearestCluster = assignToNearestCluster; - -var _tools = require('./tools'); - -var _ = require('./'); - -function initClusters(p, _ref) { - var nbClusters = _ref.nbClusters; - var initCentroids = _ref.initCentroids; - - var clusters = []; - var points = p.slice(); // clone - - function haveClusterWithCentroid(point) { - for (var i = clusters.length - 1; i >= 0; i--) { - if (clusters[i].centroid.equals(point)) { - return true; - } - } - return false; - } - - if (nbClusters) { - // create the clusters with a random centroid inside - var pickRandomPoint = (0, _tools.unique)(points); - for (var i = nbClusters - 1; i >= 0; i--) { - var point = pickRandomPoint(); - if (haveClusterWithCentroid(point)) { - i++; - continue; - } - - var cluster = new _.Cluster(point); - clusters.push(cluster); - } - - // we need at least the expected number of clusters - if (clusters.length !== nbClusters) { - throw Error('Not enough different point coordinates to create clusters'); - } - } else if (initCentroids) { - clusters = initCentroids.map(function (init) { - return new _.Cluster(init); - }); - } - - return clusters; -} - -function assignToNearestCluster(clusters, point) { - var minDistance = null; - var nearestCluster = null; - for (var i = clusters.length - 1; i >= 0; i--) { - var cluster = clusters[i]; - var distance = point.distanceTo(cluster.centroid); - - if (minDistance === null || distance < minDistance) { - minDistance = distance; - nearestCluster = cluster; - } - } - - if (point.cluster !== nearestCluster) { - nearestCluster.addPoint(point); - } -} \ No newline at end of file diff --git a/lib/index.js b/lib/index.js deleted file mode 100644 index 46bceb1..0000000 --- a/lib/index.js +++ /dev/null @@ -1,45 +0,0 @@ -'use strict'; - -exports.__esModule = true; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -var _helpers = require('./helpers'); - -var _cluster = require('./cluster'); - -var _cluster2 = _interopRequireDefault(_cluster); - -var _point = require('./point'); - -var _point2 = _interopRequireDefault(_point); - -exports.Point = _point2['default']; -exports.Cluster = _cluster2['default']; - -exports['default'] = function (points, _ref) { - var nbClusters = _ref.nbClusters; - var initCentroids = _ref.initCentroids; - - var clusters = (0, _helpers.initClusters)(points, { - nbClusters: nbClusters, - initCentroids: initCentroids }); - - var assignToNearest = function assignToNearest(p) { - (0, _helpers.assignToNearestCluster)(clusters, p); - }; - - do { - clusters.forEach(function (c) { - return c.dirty = false; - }); - points.forEach(assignToNearest); - clusters.forEach(function (c) { - return c.computeCentroid(); - }); - } while (clusters.some(function (c) { - return c.dirty; - })); - - return clusters; -}; \ No newline at end of file diff --git a/lib/point.js b/lib/point.js deleted file mode 100644 index ca57fba..0000000 --- a/lib/point.js +++ /dev/null @@ -1,36 +0,0 @@ -"use strict"; - -exports.__esModule = true; - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var Point = (function () { - function Point(x, y, z) { - _classCallCheck(this, Point); - - this.x = x; - this.y = y; - this.z = z; - this.cluster = null; - } - - Point.prototype.distanceTo = function distanceTo(point) { - var dx = point.x - this.x; - var dy = point.y - this.y; - var dz = point.z - this.z; - return Math.sqrt(dx * dx + dy * dy + dz * dz); - }; - - Point.prototype.distanceToCentroid = function distanceToCentroid() { - return this.cluster ? this.distanceTo(this.cluster.centroid) : null; - }; - - Point.prototype.equals = function equals(point) { - return this.x === point.x && this.y === point.y && this.z === point.z; - }; - - return Point; -})(); - -exports["default"] = Point; -module.exports = exports["default"]; \ No newline at end of file diff --git a/lib/tools/index.js b/lib/tools/index.js deleted file mode 100644 index e6ec429..0000000 --- a/lib/tools/index.js +++ /dev/null @@ -1,13 +0,0 @@ -'use strict'; - -exports.__esModule = true; - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -var _uniqueJs = require('./unique.js'); - -var _uniqueJs2 = _interopRequireDefault(_uniqueJs); - -exports['default'] = { - unique: _uniqueJs2['default'] }; -module.exports = exports['default']; \ No newline at end of file diff --git a/lib/tools/unique.js b/lib/tools/unique.js deleted file mode 100644 index d09d8dd..0000000 --- a/lib/tools/unique.js +++ /dev/null @@ -1,22 +0,0 @@ -"use strict"; - -exports.__esModule = true; -exports["default"] = unique; -function swap(array, i, j) { - var tmp = array[i]; - array[i] = array[j]; - array[j] = tmp; -} - -function unique(arr) { - var maxLength = arr.length; - return function () { - // Fisher–Yates - var randomIndex = Math.random() * maxLength-- | 0; - var item = arr[randomIndex]; - swap(arr, randomIndex, maxLength); - return item; - }; -} - -module.exports = exports["default"]; \ No newline at end of file diff --git a/package.json b/package.json index f4eefc9..6799baf 100644 --- a/package.json +++ b/package.json @@ -4,12 +4,17 @@ "description": "Simple implementation of the k-means clustering method.", "main": "src/index.js", "scripts": { - "test": "./node_modules/.bin/_mocha", + "//": "we can't put --compilers js:babel/register in the global mocha.opts", + "//": "otherwise the test:cov fails because babel/polyfill is included twice", + "//": "once with mocha.opts and one with babel-node", + "test": "./node_modules/.bin/_mocha --compilers js:babel/register", "prepublish": "npm run build && npm run build:umd", "build": "babel src --out-dir lib", + "clean": "rimraf lib dist", "build:umd": "webpack src/index.js dist/kmeans.js && set NODE_ENV=production&& webpack src/index.js dist/kmeans.min.js", "test:watch": "./node_modules/.bin/_mocha watch", - "lint": "eslint src test" + "test:cov": "babel-node ./node_modules/isparta/bin/isparta cover ./node_modules/mocha/bin/_mocha", + "lint": "eslint src test" }, "author": "chtefi", "license": "MIT", @@ -22,23 +27,15 @@ "eslint": "^1.1.0", "eslint-config-airbnb": "0.0.7", "eslint-plugin-react": "^3.2.3", + "isparta": "^3.0.3", + "istanbul": "^0.3.17", "mocha": "^2.2.5", + "rimraf": "^2.4.2", "webpack": "^1.11.0" }, "directories": { "test": "test" }, - "dependencies": { - "babel": "^5.4.7", - "babel-core": "^5.8.22", - "babel-eslint": "^4.0.8", - "babel-loader": "^5.3.2", - "chai": "^2.3.0", - "eslint": "^1.1.0", - "eslint-config-airbnb": "^0.0.7", - "eslint-plugin-react": "^3.2.3", - "webpack": "^1.11.0" - }, "repository": { "type": "git", "url": "git+https://github.com/chtefi/algo-kmeans.git" diff --git a/test/mocha.opts b/test/mocha.opts index fcc8b7f..4a52320 100644 --- a/test/mocha.opts +++ b/test/mocha.opts @@ -1,2 +1 @@ ---compilers js:babel/register --recursive