From f2efa50beb86bf2370ce336e0142579931389904 Mon Sep 17 00:00:00 2001 From: Karolis Narkevicius Date: Wed, 26 Aug 2015 11:58:17 +0100 Subject: [PATCH 1/4] Remove lodash - massively reduces the size of the lib --- lib/dash.js | 102 ++++++++++++++++++++++++++++++++++++++++++++++----- package.json | 2 +- 2 files changed, 93 insertions(+), 11 deletions(-) diff --git a/lib/dash.js b/lib/dash.js index 2dd63ad..9d9e9a6 100644 --- a/lib/dash.js +++ b/lib/dash.js @@ -1,11 +1,93 @@ -module.exports = { - map: require('lodash/collection/map'), - each: require('lodash/collection/each'), - reduce: require('lodash/collection/reduce'), - pluck: require('lodash/collection/pluck'), - extend: require('lodash/object/assign'), - pick: require('lodash/object/pick'), - toArray: require('lodash/lang/toArray'), - clone: require('lodash/lang/clone'), - isEqual: require('lodash/lang/isEqual') +'use strict'; + +function reduce(list, iterator) { + list = list || []; + var keys = getKeys(list); + var i = 0; + var accumulator = list[0]; + + if (arguments.length === 2) { + i = 1; + } else if (arguments.length === 3) { + accumulator = arguments[2]; + } + + for (var len = keys.length; i < len; i++) { + var key = keys[i]; + var value = list[key]; + accumulator = iterator.call(null, accumulator, value, key, list); + } + + return accumulator; +} + +function getKeys(obj) { + var keys = []; + for (var key in obj) { + if (obj.hasOwnProperty(key)) { + keys.push(key); + } + } + return keys; +} + +function map(list, iterator) { + return reduce(list, function (accumulator, value, i) { + accumulator.push(iterator.call(null, value, i)); + return accumulator; + }, []); +} + +function each(list, iterator) { + map(list, iterator); +} + +function pluck(list, attr) { + return map(list, function (item) { + return item[attr]; + }); +} + +function pick(obj, attrs) { + return reduce(attrs, function (accumulator, attr) { + accumulator[attr] = obj[attr]; + return accumulator; + }, {}); } + +function toArray(args) { + return Array.prototype.slice.call(args); +} + +function extend(obj1, obj2) { + return reduce(obj2 || {}, function (accumulator, value, key) { + obj1[key] = value; + return obj1; + }, obj1 || {}); +} + +function clone(obj) { + return isArray(obj) ? obj.slice(0) : extend({}, obj); +} + +function isArray(obj) { + return Object.prototype.toString.call(obj) === '[object Array]'; +} + +function isEqual(obj1, obj2) { + return reduce(obj1, function (accumulator, value, key) { + return accumulator && obj2[key] === value; + }, true) && getKeys(obj1).length === getKeys(obj2).length; +} + +module.exports = { + reduce: reduce, + map: map, + each: each, + pluck: pluck, + pick: pick, + toArray: toArray, + extend: extend, + clone: clone, + isEqual: isEqual +}; \ No newline at end of file diff --git a/package.json b/package.json index d620415..651d3cc 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,6 @@ }, "dependencies": { "location-bar": "^2.0.0", - "lodash": "^3.3.0", "path-to-regexp": "^1.0.3", "qs": "^2.3.3" }, @@ -54,6 +53,7 @@ "karma-sourcemap-loader": "^0.3.4", "karma-webpack": "^1.7.0", "kn-release": "^1.0.1", + "lodash": "^3.3.0", "mocha": "^2.2.0", "prompt": "^0.2.14", "referee": "^1.1.1", From 2a9794f6915c8166f6efa057d09efdf49dda2af4 Mon Sep 17 00:00:00 2001 From: Karolis Narkevicius Date: Sun, 30 Aug 2015 23:44:42 +0100 Subject: [PATCH 2/4] An es6 style implementation of dash.js utils --- lib/dash.js | 114 ++++++++++++----------------------------- tests/unit/dashTest.js | 22 ++++++++ 2 files changed, 54 insertions(+), 82 deletions(-) create mode 100644 tests/unit/dashTest.js diff --git a/lib/dash.js b/lib/dash.js index 9d9e9a6..a024dc0 100644 --- a/lib/dash.js +++ b/lib/dash.js @@ -1,93 +1,43 @@ -'use strict'; - -function reduce(list, iterator) { - list = list || []; - var keys = getKeys(list); - var i = 0; - var accumulator = list[0]; - - if (arguments.length === 2) { - i = 1; - } else if (arguments.length === 3) { - accumulator = arguments[2]; +// helpers +let keys = Object.keys +let apply = (fn, args) => fn.apply(null, args) +let identity = x => x +let append = (item, list) => { list.push(item); return list } +let assoc = (obj, attr, val) => { obj[attr] = val; return obj } + +// exports +export let reduce = (list = [], iterator = identity, ...rest) => { + let i = rest.length ? 0 : 1 + let acc = rest.length ? rest[0] : list[0] + let keyList = keys(list) + for (let len = keyList.length; i < len; i++) { + let key = keyList[i] + acc = apply(iterator, [acc, list[key], key, list]) } - - for (var len = keys.length; i < len; i++) { - var key = keys[i]; - var value = list[key]; - accumulator = iterator.call(null, accumulator, value, key, list); - } - - return accumulator; -} - -function getKeys(obj) { - var keys = []; - for (var key in obj) { - if (obj.hasOwnProperty(key)) { - keys.push(key); - } - } - return keys; -} - -function map(list, iterator) { - return reduce(list, function (accumulator, value, i) { - accumulator.push(iterator.call(null, value, i)); - return accumulator; - }, []); + return acc } -function each(list, iterator) { - map(list, iterator); -} +export let map = (list, iterator) => + reduce(list, (acc, value, i) => + append(apply(iterator, [value, i]), acc), []) -function pluck(list, attr) { - return map(list, function (item) { - return item[attr]; - }); -} +export let each = (...args) => { apply(map, args) } -function pick(obj, attrs) { - return reduce(attrs, function (accumulator, attr) { - accumulator[attr] = obj[attr]; - return accumulator; - }, {}); -} +export let pluck = (list, attr) => map(list, item => item[attr]) -function toArray(args) { - return Array.prototype.slice.call(args); -} +export let toArray = args => Array.prototype.slice.call(args) -function extend(obj1, obj2) { - return reduce(obj2 || {}, function (accumulator, value, key) { - obj1[key] = value; - return obj1; - }, obj1 || {}); -} +export let isArray = obj => Object.prototype.toString.call(obj) === '[object Array]' -function clone(obj) { - return isArray(obj) ? obj.slice(0) : extend({}, obj); -} +export let clone = obj => isArray(obj) ? obj.slice(0) : extend({}, obj) -function isArray(obj) { - return Object.prototype.toString.call(obj) === '[object Array]'; -} +export let pick = (obj, attrs) => + reduce(attrs, (acc, attr) => + assoc(acc, attr, obj[attr]), {}) -function isEqual(obj1, obj2) { - return reduce(obj1, function (accumulator, value, key) { - return accumulator && obj2[key] === value; - }, true) && getKeys(obj1).length === getKeys(obj2).length; -} +export let extend = (obj1, obj2) => + reduce(obj2 || {}, (__, value, key) => assoc(obj1, key, value), obj1 || {}) -module.exports = { - reduce: reduce, - map: map, - each: each, - pluck: pluck, - pick: pick, - toArray: toArray, - extend: extend, - clone: clone, - isEqual: isEqual -}; \ No newline at end of file +export let isEqual = (obj1, obj2) => + keys(obj1).length === keys(obj2).length && + reduce(obj1, (acc, value, key) => acc && obj2[key] === value, true) diff --git a/tests/unit/dashTest.js b/tests/unit/dashTest.js new file mode 100644 index 0000000..038ea1e --- /dev/null +++ b/tests/unit/dashTest.js @@ -0,0 +1,22 @@ +let {assert} = require('referee') +let {suite, test} = window +let _ = require('../../lib/dash') + +suite('_') + +test('map', () => { + assert.equals(_.map([1, 2, 3], i => i * 2), [2, 4, 6]) +}) + +test('pick', () => { + assert.equals(_.pick({a: 1, b: 2, c: 3}, ['a', 'c']), {a: 1, c: 3}) +}) + +test('pluck', () => { + assert.equals(_.pluck([{a: 1, b: 2}, {a: 3, b: 4}], 'a'), [1, 3]) +}) + +test('isArray', () => { + assert.equals(_.isArray([]), true) + assert.equals(_.isArray({}), false) +}) From 19d4379a4a55ccbdba4c23b811e1883653a2d999 Mon Sep 17 00:00:00 2001 From: Karolis Narkevicius Date: Mon, 31 Aug 2015 11:25:34 +0100 Subject: [PATCH 3/4] Use es5 native methods instead of lodash --- CHANGELOG.md | 1 + README.md | 7 ++++++ karma.conf-ci.js | 3 +-- karma.conf.js | 5 ++-- lib/dash.js | 53 +++++++++++++++--------------------------- lib/path.js | 3 +-- lib/router.js | 20 ++++++++-------- lib/transition.js | 2 +- package.json | 1 - tasks/build.sh | 2 +- tests/routerTest.js | 13 ++++++----- tests/unit/dashTest.js | 46 +++++++++++++++++++++++++++--------- 12 files changed, 85 insertions(+), 71 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 15bc789..7123994 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ * Make params, query and route array immutable between transitions, i.e. modifying those directly on the transition only affects that transition * Replace `paramNames` with `params` in the route descriptor * Drop the `ancestors` attribute from the route descriptor +* Drop support for es3 environments (IE8), to use Cherrytree - es5 polyfills for native `map`, `reduce` and `forEach` needs to be used now ### v2.0.0-alpha.12 diff --git a/README.md b/README.md index 9d1eb53..61a41bb 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,13 @@ In an AMD environment, require the standalone UMD build - this version has all o require('cherrytree/standalone') +# Environment + +Cherrytree requires es5 environment and es6 promises. If you have to support older browsers, you will have to use polyfills, e.g.: + +* https://github.com/es-shims/es5-shim +* https://github.com/jakearchibald/es6-promise + # Size The size excluding all deps is ~10.96 kB gzipped and the standalone build with all deps is ~12.82 kB gzipped. diff --git a/karma.conf-ci.js b/karma.conf-ci.js index c2aa1d8..61574e9 100644 --- a/karma.conf-ci.js +++ b/karma.conf-ci.js @@ -1,5 +1,4 @@ var fs = require('fs') -var _ = require('lodash') var config = require('./karma.conf').config // Use ENV vars on CI and sauce.json locally to get credentials @@ -50,7 +49,7 @@ var customLaunchers = { } module.exports = function (c) { - c.set(_.extend(config, { + c.set(Object.assign(config, { sauceLabs: { testName: 'Cherrytree Tests' }, diff --git a/karma.conf.js b/karma.conf.js index bb8d623..6307bb1 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -1,4 +1,3 @@ -var _ = require('lodash') var webpackConfig = require('./webpack.config') var config = { @@ -19,12 +18,12 @@ var config = { // this watcher watches when bundled files are updated autoWatch: true, - webpack: _.extend(webpackConfig, { + webpack: Object.assign(webpackConfig, { entry: undefined, // this watcher watches when source files are updated watch: true, devtool: 'inline-source-map', - module: _.extend(webpackConfig.module, { + module: Object.assign(webpackConfig.module, { postLoaders: [{ test: /\.js/, exclude: /(test|node_modules)/, diff --git a/lib/dash.js b/lib/dash.js index a024dc0..94014f9 100644 --- a/lib/dash.js +++ b/lib/dash.js @@ -1,43 +1,28 @@ -// helpers +let toString = Object.prototype.toString let keys = Object.keys -let apply = (fn, args) => fn.apply(null, args) -let identity = x => x -let append = (item, list) => { list.push(item); return list } let assoc = (obj, attr, val) => { obj[attr] = val; return obj } +let isArray = obj => toString.call(obj) === '[object Array]' -// exports -export let reduce = (list = [], iterator = identity, ...rest) => { - let i = rest.length ? 0 : 1 - let acc = rest.length ? rest[0] : list[0] - let keyList = keys(list) - for (let len = keyList.length; i < len; i++) { - let key = keyList[i] - acc = apply(iterator, [acc, list[key], key, list]) - } - return acc -} - -export let map = (list, iterator) => - reduce(list, (acc, value, i) => - append(apply(iterator, [value, i]), acc), []) - -export let each = (...args) => { apply(map, args) } - -export let pluck = (list, attr) => map(list, item => item[attr]) - -export let toArray = args => Array.prototype.slice.call(args) - -export let isArray = obj => Object.prototype.toString.call(obj) === '[object Array]' - -export let clone = obj => isArray(obj) ? obj.slice(0) : extend({}, obj) +export let clone = obj => + isArray(obj) + ? obj.slice(0) + : extend({}, obj) export let pick = (obj, attrs) => - reduce(attrs, (acc, attr) => + attrs.reduce((acc, attr) => assoc(acc, attr, obj[attr]), {}) -export let extend = (obj1, obj2) => - reduce(obj2 || {}, (__, value, key) => assoc(obj1, key, value), obj1 || {}) - export let isEqual = (obj1, obj2) => keys(obj1).length === keys(obj2).length && - reduce(obj1, (acc, value, key) => acc && obj2[key] === value, true) + keys(obj1).reduce((acc, key) => acc && obj2[key] === obj1[key], true) + +export let extend = (obj, ...rest) => { + rest.forEach(source => { + if (source) { + for (var prop in source) { + obj[prop] = source[prop] + } + } + }) + return obj +} diff --git a/lib/path.js b/lib/path.js index be48d30..49b87ac 100644 --- a/lib/path.js +++ b/lib/path.js @@ -1,4 +1,3 @@ -var _ = require('./dash') var invariant = require('./invariant') var merge = require('qs/lib/utils').merge var qs = require('qs') @@ -17,7 +16,7 @@ function compilePattern (pattern) { _compiledPatterns[pattern] = { matcher: re, - paramNames: _.pluck(paramNames, 'name') + paramNames: paramNames.map(p => p.name) } } diff --git a/lib/router.js b/lib/router.js index 7c8bbc9..f2fcf1b 100644 --- a/lib/router.js +++ b/lib/router.js @@ -74,7 +74,7 @@ Cherrytree.prototype.map = function (routes) { eachBranch({routes: this.routes}, [], function (routes) { // concatenate the paths of the list of routes - var path = _.reduce(routes, function (memo, r) { + var path = routes.reduce(function (memo, r) { // reset if there's a leading slash, otherwise concat // and keep resetting the trailing slash return (r.path[0] === '/' ? r.path : memo + '/' + r.path).replace(/\/$/, '') @@ -92,7 +92,7 @@ Cherrytree.prototype.map = function (routes) { }) function eachBranch (node, memo, fn) { - _.each(node.routes, function (route) { + node.routes.forEach(function (route) { if (!route.routes || route.routes.length === 0) { fn.call(null, memo.concat(route)) } else { @@ -132,11 +132,11 @@ Cherrytree.prototype.listen = function (location) { * * @api public */ -Cherrytree.prototype.transitionTo = function () { +Cherrytree.prototype.transitionTo = function (...args) { if (this.state.activeTransition) { - return this.replaceWith.apply(this, arguments) + return this.replaceWith.apply(this, args) } - return this.doTransition('setURL', _.toArray(arguments)) + return this.doTransition('setURL', args) } /** @@ -149,8 +149,8 @@ Cherrytree.prototype.transitionTo = function () { * * @api public */ -Cherrytree.prototype.replaceWith = function () { - return this.doTransition('replaceURL', _.toArray(arguments)) +Cherrytree.prototype.replaceWith = function (...args) { + return this.doTransition('replaceURL', args) } /** @@ -169,7 +169,7 @@ Cherrytree.prototype.generate = function (name, params, query) { params = params || {} query = query || {} - _.each(this.matchers, function (m) { + this.matchers.forEach(function (m) { if (m.name === name) { matcher = m } @@ -264,7 +264,7 @@ Cherrytree.prototype.match = function (path) { var query var routes = [] var pathWithoutQuery = Path.withoutQuery(path) - _.each(this.matchers, function (matcher) { + this.matchers.forEach(function (matcher) { if (!found) { params = Path.extractParams(matcher.path, pathWithoutQuery) if (params) { @@ -275,7 +275,7 @@ Cherrytree.prototype.match = function (path) { } }) return { - routes: _.map(routes, descriptor), + routes: routes.map(descriptor), params: params || {}, query: query || {} } diff --git a/lib/transition.js b/lib/transition.js index 9313dd4..c49f762 100644 --- a/lib/transition.js +++ b/lib/transition.js @@ -19,7 +19,7 @@ module.exports = function transition (options, Promise) { let startTime = Date.now() log('---') log('Transition #' + id, 'to', path) - log('Transition #' + id, 'routes:', _.pluck(routes, 'name')) + log('Transition #' + id, 'routes:', routes.map(r => r.name)) log('Transition #' + id, 'params:', params) log('Transition #' + id, 'query:', query) diff --git a/package.json b/package.json index 651d3cc..e857e3d 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,6 @@ "karma-sourcemap-loader": "^0.3.4", "karma-webpack": "^1.7.0", "kn-release": "^1.0.1", - "lodash": "^3.3.0", "mocha": "^2.2.0", "prompt": "^0.2.14", "referee": "^1.1.1", diff --git a/tasks/build.sh b/tasks/build.sh index 9fd5380..c45d69c 100755 --- a/tasks/build.sh +++ b/tasks/build.sh @@ -11,5 +11,5 @@ cp package.json build webpack index.js build/standalone.js echo "\nnpm build including deps is\n `bro-size build`" -echo "\nnpm build excluding deps is\n `bro-size build -u location-bar -u lodash/** -u qs -u path-to-regexp`" +echo "\nnpm build excluding deps is\n `bro-size build -u location-bar -u qs -u path-to-regexp`" echo "\nstandalone build including deps is\n `bro-size build/standalone.js`" diff --git a/tests/routerTest.js b/tests/routerTest.js index d28c165..2e24672 100644 --- a/tests/routerTest.js +++ b/tests/routerTest.js @@ -1,9 +1,9 @@ -let _ = require('lodash') let Promise = require('es6-promise').Promise let co = require('co') let {assert} = require('referee') let {suite, test, beforeEach, afterEach} = window let cherrytree = require('..') +let extend = require('../lib/dash').extend let delay = (t) => new Promise((resolve) => setTimeout(resolve, t)) @@ -40,7 +40,8 @@ test('#use registers middleware', () => { test('#use middleware gets passed a transition object', (done) => { let m = (transition) => { - let t = _.omit(transition, ['catch', 'then', 'redirectTo', 'cancel', 'retry', 'followRedirects']) + let t = extend({}, transition) + ;['catch', 'then', 'redirectTo', 'cancel', 'retry', 'followRedirects'].forEach(attr => delete t[attr]) let et = { id: 3, prev: { @@ -113,7 +114,7 @@ test('#use middleware gets passed a transition object', (done) => { test('#map registers the routes', () => { router.map(routes) // check that the internal matchers object is created - assert.equals(_.pluck(router.matchers, 'path'), [ + assert.equals(router.matchers.map(m => m.path), [ '/application', '/application/notifications', '/application/messages', @@ -215,7 +216,7 @@ test('#match matches a path against the routes', () => { user: 'KidkArolis', id: '42' }) - assert.equals(_.pluck(match.routes, 'name'), ['application', 'status']) + assert.equals(match.routes.map(r => r.name), ['application', 'status']) }) test('#match matches a path with query params', () => { @@ -313,7 +314,7 @@ test('routes with name "index" or that end int ".index" default to an empty path route('bar.index') }) }) - assert.equals(_.pluck(router.matchers, 'path'), [ + assert.equals(router.matchers.map(m => m.path), [ '/', '/foo', '/bar' @@ -341,7 +342,7 @@ test('a complex route map', () => { }) }) // check that the internal matchers object is created - assert.equals(_.pluck(router.matchers, 'path'), [ + assert.equals(router.matchers.map(m => m.path), [ '/application', '/application/notifications', '/application/messages/unread/priority', diff --git a/tests/unit/dashTest.js b/tests/unit/dashTest.js index 038ea1e..d10a35b 100644 --- a/tests/unit/dashTest.js +++ b/tests/unit/dashTest.js @@ -1,22 +1,46 @@ -let {assert} = require('referee') +let {assert, refute} = require('referee') let {suite, test} = window -let _ = require('../../lib/dash') +let {clone, pick, isEqual, extend} = require('../../lib/dash') -suite('_') +suite('dash') -test('map', () => { - assert.equals(_.map([1, 2, 3], i => i * 2), [2, 4, 6]) +test('clone arrays', () => { + let a = [1, 2, 3] + let b = clone(a) + b.push(4) + assert.equals(a, [1, 2, 3]) + assert.equals(b, [1, 2, 3, 4]) +}) + +test('clone objects', () => { + let a = {a: 1, b: 2} + let b = clone(a) + b.c = 3 + assert.equals(a, {a: 1, b: 2}) + assert.equals(b, {a: 1, b: 2, c: 3}) }) test('pick', () => { - assert.equals(_.pick({a: 1, b: 2, c: 3}, ['a', 'c']), {a: 1, c: 3}) + assert.equals(pick({a: 1, b: 2, c: 3}, ['a', 'c']), {a: 1, c: 3}) }) -test('pluck', () => { - assert.equals(_.pluck([{a: 1, b: 2}, {a: 3, b: 4}], 'a'), [1, 3]) +test('isEqual', () => { + let arr = [] + assert(isEqual({a: 1, b: 2}, {a: 1, b: 2})) + assert(isEqual({a: 1, b: arr}, {a: 1, b: arr})) + refute(isEqual({a: 1, b: 2}, {a: 1, b: '2'})) + refute(isEqual({a: 1, b: 2}, {a: 1})) + refute(isEqual({a: 1, b: {c: 3}}, {a: 1, b: {c: 3}})) }) -test('isArray', () => { - assert.equals(_.isArray([]), true) - assert.equals(_.isArray({}), false) +test('extend', () => { + assert.equals(extend({}, {a: 1, b: 2}, null, {c: 3}), {a: 1, b: 2, c: 3}) + + let obj = {d: 4} + let target = {} + extend(target, obj) + target.a = 1 + obj.b = 2 + assert.equals(obj, {b: 2, d: 4}) + assert.equals(target, {a: 1, d: 4}) }) From d40ff83e025519b9cddf4276a1bc2037e0c76c56 Mon Sep 17 00:00:00 2001 From: Karolis Narkevicius Date: Mon, 31 Aug 2015 11:31:51 +0100 Subject: [PATCH 4/4] Add more sauce browsers, switch sauce user --- .travis.yml | 5 +++- CHANGELOG.md | 2 +- README.md | 8 +++--- karma.conf-ci.js | 69 +++++++++++++++++++++++------------------------- package.json | 8 +++--- 5 files changed, 48 insertions(+), 44 deletions(-) diff --git a/.travis.yml b/.travis.yml index c2c8b1e..02b1ac3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,4 +5,7 @@ node_js: before_install: - "export DISPLAY=:99.0" - "sh -e /etc/init.d/xvfb start" -script: "npm test && karma start karma.conf-ci.js" \ No newline at end of file +script: "npm test" +env: + global: + - SAUCE_USERNAME=cherrytree diff --git a/CHANGELOG.md b/CHANGELOG.md index 7123994..9ba043d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ * Make params, query and route array immutable between transitions, i.e. modifying those directly on the transition only affects that transition * Replace `paramNames` with `params` in the route descriptor * Drop the `ancestors` attribute from the route descriptor -* Drop support for es3 environments (IE8), to use Cherrytree - es5 polyfills for native `map`, `reduce` and `forEach` needs to be used now +* Drop out of the box support for ES3 environments (IE8), to use Cherrytree - es5 polyfills for native `map`, `reduce` and `forEach` need to be used now. This was possible always the case since usage of babel requires an es5 environment. ### v2.0.0-alpha.12 diff --git a/README.md b/README.md index 61a41bb..49f259d 100644 --- a/README.md +++ b/README.md @@ -22,16 +22,18 @@ In an AMD environment, require the standalone UMD build - this version has all o require('cherrytree/standalone') -# Environment +# Browser Support -Cherrytree requires es5 environment and es6 promises. If you have to support older browsers, you will have to use polyfills, e.g.: +[![Sauce Test Status](https://saucelabs.com/browser-matrix/cherrytree.svg)](https://saucelabs.com/u/cherrytree) + +Cherrytree works in all modern browsers. It requires es5 environment and es6 promises. Use polyfills for those if you have to support older browsers, e.g.: * https://github.com/es-shims/es5-shim * https://github.com/jakearchibald/es6-promise # Size -The size excluding all deps is ~10.96 kB gzipped and the standalone build with all deps is ~12.82 kB gzipped. +The size excluding all deps is ~4.9kB gzipped and the standalone build with all deps is ~8.7kB gzipped. # Usage diff --git a/karma.conf-ci.js b/karma.conf-ci.js index 61574e9..5160677 100644 --- a/karma.conf-ci.js +++ b/karma.conf-ci.js @@ -1,5 +1,8 @@ var fs = require('fs') var config = require('./karma.conf').config +var yargs = require('yargs') + +var browsers = (yargs.argv.b || '').split(',') // Use ENV vars on CI and sauce.json locally to get credentials if (!process.env.SAUCE_USERNAME) { @@ -13,45 +16,39 @@ if (!process.env.SAUCE_USERNAME) { } } -var customLaunchers = { - 'SL_Chrome': { - base: 'SauceLabs', - browserName: 'chrome' - }, - 'SL_Firefox': { - base: 'SauceLabs', - browserName: 'firefox' - }, - 'SL_Safari': { - base: 'SauceLabs', - browserName: 'safari', - platform: 'OS X 10.9', - version: '7' - }, - 'SL_IE_9': { - base: 'SauceLabs', - browserName: 'internet explorer', - platform: 'Windows 2008', - version: '9' - }, - 'SL_IE_10': { - base: 'SauceLabs', - browserName: 'internet explorer', - platform: 'Windows 2012', - version: '10' - }, - 'SL_IE_11': { - base: 'SauceLabs', - browserName: 'internet explorer', - platform: 'Windows 8.1', - version: '11' +var platforms = [ + ['android', '5.1', 'Linux'], + ['chrome', '32', 'Windows 8.1'], + ['chrome', '43', 'Linux'], + ['chrome', 'beta', 'OS X 10.11'], + ['firefox', '26', 'Windows 8.1'], + ['firefox', '40', 'Windows 8.1'], + ['safari', '6', 'OS X 10.8'], + ['safari', '7', 'OS X 10.9'], + ['internet explorer', '9', 'Windows 7'], + ['internet explorer', '10', 'Windows 8'], + ['internet explorer', '11', 'Windows 8.1'] +] + +var customLaunchers = platforms.reduce(function (memo, platform, i) { + if (!browsers || browsers.indexOf(platform[0]) > -1) { + memo['SL_' + i + '_' + platform[0] + platform[1]] = { + base: 'SauceLabs', + platform: platform[2], + browserName: platform[0], + version: platform[1] + } } -} + return memo +}, {}) module.exports = function (c) { c.set(Object.assign(config, { sauceLabs: { - testName: 'Cherrytree Tests' + testName: 'Cherrytree', + build: process.env.CI_BUILD_NUMBER, + recordVideo: false, + recordScreenshots: false }, customLaunchers: customLaunchers, browsers: Object.keys(customLaunchers), @@ -59,7 +56,7 @@ module.exports = function (c) { singleRun: true, browserDisconnectTimeout: 10000, // default 2000 browserDisconnectTolerance: 1, // default 0 - browserNoActivityTimeout: 4 * 60 * 1000, // default 10000 - captureTimeout: 4 * 60 * 1000 // default 60000 + browserNoActivityTimeout: 3 * 60 * 1000, // default 10000 + captureTimeout: 3 * 60 * 1000 // default 60000 })) } diff --git a/package.json b/package.json index e857e3d..e43e613 100644 --- a/package.json +++ b/package.json @@ -39,10 +39,11 @@ "bro-size": "^1.0.0", "cli-color": "^0.3.3", "co": "^4.5.1", + "es5-shim": "^4.1.11", "es6-promise": "^2.0.1", "istanbul-instrumenter-loader": "^0.1.3", "jquery": "^2.1.3", - "karma": "^0.13.3", + "karma": "^0.13.9", "karma-chrome-launcher": "~0.1.0", "karma-cli": "0.0.4", "karma-coverage": "^0.5.0", @@ -60,7 +61,8 @@ "standard": "^4.5.4", "underscore": "^1.7.0", "webpack": "^1.4.13", - "webpack-dev-server": "^1.6.6" + "webpack-dev-server": "^1.6.6", + "yargs": "^3.23.0" }, "standard": { "ignore": [ @@ -69,4 +71,4 @@ "build/**" ] } -} \ No newline at end of file +}