diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..e449353 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,2 @@ +*.min.js +test/browser/coverage \ No newline at end of file diff --git a/.eslintrc b/.eslintrc index cc39618..ee856fb 100644 --- a/.eslintrc +++ b/.eslintrc @@ -4,7 +4,7 @@ "browser": true, "mocha": true, "node": true, - "es6": true, + "es6": true }, "globals": { "assert": true @@ -15,10 +15,11 @@ "promise" ], "rules": { - "camelcase": 0, - "no-sequences": 0, - "no-extra-parens": 2, - "no-loop-func": 2, - "require-yield": 2 + "camelcase": "off", + "no-sequences": "off", + "no-extra-parens": "error", + "no-loop-func": "error", + "require-yield": "error", + "space-before-blocks": "error" } } diff --git a/.gitignore b/.gitignore index d89076d..ddfdfef 100644 --- a/.gitignore +++ b/.gitignore @@ -28,4 +28,6 @@ node_modules run-browserstack-tests.sh -bundle.js \ No newline at end of file +bundle.js + +.idea \ No newline at end of file diff --git a/examples/isomorphic/Component.jsx b/examples/isomorphic/Component.jsx index 4c041cf..9bf6769 100644 --- a/examples/isomorphic/Component.jsx +++ b/examples/isomorphic/Component.jsx @@ -6,7 +6,7 @@ module.exports = React.createClass({ propTypes: { userIdentifier: React.PropTypes.string.isRequired }, - render: function(){ + render: function() { return
diff --git a/package.json b/package.json index 3e7cadf..03802c2 100644 --- a/package.json +++ b/package.json @@ -70,8 +70,8 @@ "scripts": { "test": "./node_modules/karma/bin/karma start test/browser/karma.conf.js; mocha --require babel-core/register --require babel-polyfill test/isomorphic/*.jsx", "build": "./node_modules/.bin/doctoc . --github --title '

Table of Contents

'; ./node_modules/babel-cli/bin/babel.js --presets es2015,stage-1,react --plugins add-module-exports ./src --out-dir ./lib; ./node_modules/webpack/bin/webpack.js --config webpack.standalone.config.js", - "lint": "eslint .", - "lint:fix": "eslint --fix ." + "lint": "eslint --ext js,jsx .", + "lint:fix": "npm run lint -- --fix" }, "repository": { "type": "git", diff --git a/src/Experiment.jsx b/src/Experiment.jsx index 05d26a8..59c9269 100644 --- a/src/Experiment.jsx +++ b/src/Experiment.jsx @@ -7,8 +7,8 @@ import crc32 from "fbjs/lib/crc32"; let store; const noopStore = { - getItem: function(){}, - setItem: function(){} + getItem: function() {}, + setItem: function() {} }; if (typeof window !== 'undefined' && 'localStorage' in window && window['localStorage'] !== null) { diff --git a/src/debugger.jsx b/src/debugger.jsx index ffc00ab..d620fe9 100644 --- a/src/debugger.jsx +++ b/src/debugger.jsx @@ -73,14 +73,14 @@ if(process.env.NODE_ENV === "production" || !canUseDOM) { addCSSRule("#pushtell-debugger .pushtell-close, #pushtell-debugger label", "transition: all .25s"); } function removeStyleSheet() { - if(style !== null){ + if(style !== null) { document.head.removeChild(style); style = null; } } const Debugger = React.createClass({ displayName: "Pushtell.Debugger", - getInitialState(){ + getInitialState() { return { experiments: emitter.getActiveExperiments(), visible: false @@ -91,7 +91,7 @@ if(process.env.NODE_ENV === "production" || !canUseDOM) { visible: !this.state.visible }); }, - updateExperiments(){ + updateExperiments() { this.setState({ experiments: emitter.getActiveExperiments() }); @@ -99,15 +99,15 @@ if(process.env.NODE_ENV === "production" || !canUseDOM) { setActiveVariant(experimentName, variantName) { emitter.setActiveVariant(experimentName, variantName); }, - componentWillMount(){ + componentWillMount() { this.activeSubscription = emitter.addListener("active", this.updateExperiments); this.inactiveSubscription = emitter.addListener("inactive", this.updateExperiments); }, - componentWillUnmount(){ + componentWillUnmount() { this.activeSubscription.remove(); this.inactiveSubscription.remove(); }, - render(){ + render() { var experimentNames = Object.keys(this.state.experiments); if(this.state.visible) { return
@@ -133,7 +133,7 @@ if(process.env.NODE_ENV === "production" || !canUseDOM) { })}
This panel is hidden on production builds.
; - } else if(experimentNames.length > 0){ + } else if(experimentNames.length > 0) { return
{experimentNames.length} Active Experiment{experimentNames.length > 1 ? "s" : ""}
; diff --git a/src/emitter.jsx b/src/emitter.jsx index 286c0b8..1865e42 100644 --- a/src/emitter.jsx +++ b/src/emitter.jsx @@ -11,14 +11,14 @@ const emitter = new EventEmitter(); const PushtellEventEmitter = function() {}; -PushtellEventEmitter.prototype.emitWin = function(experimentName){ +PushtellEventEmitter.prototype.emitWin = function(experimentName) { if(typeof experimentName !== 'string') { throw new Error("Required argument 'experimentName' should have type 'string'"); } emitter.emit("win", experimentName, values[experimentName]); }; -PushtellEventEmitter.prototype._emitPlay = function(experimentName, variantName){ +PushtellEventEmitter.prototype._emitPlay = function(experimentName, variantName) { if(typeof experimentName !== 'string') { throw new Error("Required argument 'experimentName' should have type 'string'"); } @@ -31,12 +31,12 @@ PushtellEventEmitter.prototype._emitPlay = function(experimentName, variantName) } }; -PushtellEventEmitter.prototype._resetPlayedExperiments = function(){ +PushtellEventEmitter.prototype._resetPlayedExperiments = function() { values = {}; playedExperiments = {}; } -PushtellEventEmitter.prototype._reset = function(){ +PushtellEventEmitter.prototype._reset = function() { values = {}; experiments = {}; experimentWeights = {}; @@ -115,7 +115,7 @@ PushtellEventEmitter.prototype.addWinListener = function(experimentName, callbac }); }; -PushtellEventEmitter.prototype.defineVariants = function(experimentName, variantNames, variantWeights){ +PushtellEventEmitter.prototype.defineVariants = function(experimentName, variantNames, variantWeights) { const variantsNamesMap = {}; const variantWeightsMap = {}; variantNames.forEach(variantName => { @@ -148,12 +148,12 @@ PushtellEventEmitter.prototype.getSortedVariants = function(experimentName) { }; PushtellEventEmitter.prototype.getSortedVariantWeights = function(experimentName) { - return this.getSortedVariants(experimentName).map(function(variantName){ + return this.getSortedVariants(experimentName).map(function(variantName) { return experimentWeights[experimentName][variantName]; }); }; -PushtellEventEmitter.prototype.getActiveExperiments = function(){ +PushtellEventEmitter.prototype.getActiveExperiments = function() { const response = {}; Object.keys(activeExperiments).forEach(experimentName => { if(activeExperiments[experimentName] === 0) { @@ -167,16 +167,16 @@ PushtellEventEmitter.prototype.getActiveExperiments = function(){ return response; } -PushtellEventEmitter.prototype.getActiveVariant = function(experimentName){ +PushtellEventEmitter.prototype.getActiveVariant = function(experimentName) { return values[experimentName]; } -PushtellEventEmitter.prototype.setActiveVariant = function(experimentName, variantName, passthrough){ +PushtellEventEmitter.prototype.setActiveVariant = function(experimentName, variantName, passthrough) { values[experimentName] = variantName; emitter.emit("active-variant", experimentName, variantName, passthrough); } -PushtellEventEmitter.prototype.addExperimentVariant = function(experimentName, variantName){ +PushtellEventEmitter.prototype.addExperimentVariant = function(experimentName, variantName) { experiments[experimentName] = experiments[experimentName] || {}; experimentWeights[experimentName] = experimentWeights[experimentName] || {}; if(experiments[experimentName][variantName] !== true) { diff --git a/src/helpers/mixpanel.jsx b/src/helpers/mixpanel.jsx index 8552540..acb4122 100644 --- a/src/helpers/mixpanel.jsx +++ b/src/helpers/mixpanel.jsx @@ -4,32 +4,32 @@ import {canUseDOM} from 'fbjs/lib/ExecutionEnvironment'; let playSubscription, winSubscription; export default { - enable(){ + enable() { if(canUseDOM) { if(typeof mixpanel === "undefined") { const error = new Error("React A/B Test Mixpanel Helper: 'mixpanel' global is not defined."); error.type = "PUSHTELL_HELPER_MISSING_GLOBAL"; throw error; } - playSubscription = emitter.addPlayListener(function(experimentName, variantName){ + playSubscription = emitter.addPlayListener(function(experimentName, variantName) { mixpanel.track("Experiment Play", { "Experiment": experimentName, "Variant": variantName - }, function(){ + }, function() { emitter.emit("mixpanel-play", experimentName, variantName); }); }); - winSubscription = emitter.addWinListener(function(experimentName, variantName){ + winSubscription = emitter.addWinListener(function(experimentName, variantName) { mixpanel.track("Experiment Win", { "Experiment": experimentName, "Variant": variantName - }, function(){ + }, function() { emitter.emit("mixpanel-win", experimentName, variantName); }); }); } }, - disable(){ + disable() { if(canUseDOM) { if(!playSubscription || !winSubscription) { const error = new Error("React A/B Test Mixpanel Helper: Helper was not enabled."); diff --git a/src/helpers/segment.jsx b/src/helpers/segment.jsx index fae76b8..2e27791 100644 --- a/src/helpers/segment.jsx +++ b/src/helpers/segment.jsx @@ -4,32 +4,32 @@ import {canUseDOM} from 'fbjs/lib/ExecutionEnvironment'; let playSubscription, winSubscription; export default { - enable(){ + enable() { if(canUseDOM) { if(typeof analytics === "undefined") { const error = new Error("React A/B Test Segment Helper: 'analytics' global is not defined."); error.type = "PUSHTELL_HELPER_MISSING_GLOBAL"; throw error; } - playSubscription = emitter.addPlayListener(function(experimentName, variantName){ + playSubscription = emitter.addPlayListener(function(experimentName, variantName) { analytics.track("Experiment Viewed", { "experimentName": experimentName, "variationName": variantName - }, function(){ + }, function() { emitter.emit("segment-play", experimentName, variantName); }); }); - winSubscription = emitter.addWinListener(function(experimentName, variantName){ + winSubscription = emitter.addWinListener(function(experimentName, variantName) { analytics.track("Experiment Won", { "experimentName": experimentName, "variationName": variantName - }, function(){ + }, function() { emitter.emit("segment-win", experimentName, variantName); }); }); } }, - disable(){ + disable() { if(canUseDOM) { if(!playSubscription || !winSubscription) { const error = new Error("React A/B Test Segment Helper: Helper was not enabled."); diff --git a/test/browser/core.test.jsx b/test/browser/core.test.jsx index 6515120..362e7ba 100644 --- a/test/browser/core.test.jsx +++ b/test/browser/core.test.jsx @@ -11,26 +11,26 @@ ES6Promise.polyfill(); describe("Core Experiment", function() { let container; - before(function(){ + before(function() { container = document.createElement("div"); container.id = "react"; document.getElementsByTagName('body')[0].appendChild(container); }); - after(function(){ + after(function() { document.getElementsByTagName('body')[0].removeChild(container); emitter._reset(); }); - it("should render the correct variant.", co.wrap(function *(){ + it("should render the correct variant.", co.wrap(function *() { let experimentName = UUID.v4(); let App = React.createClass({ - render: function(){ + render: function() { return
; } }); - yield new Promise(function(resolve, reject){ + yield new Promise(function(resolve, reject) { ReactDOM.render(, container, resolve); }); let elementA = document.getElementById('variant-a'); @@ -39,10 +39,10 @@ describe("Core Experiment", function() { assert.equal(elementB, null); ReactDOM.unmountComponentAtNode(container); })); - it("should error if invalid children exist.", co.wrap(function *(){ + it("should error if invalid children exist.", co.wrap(function *() { let experimentName = UUID.v4(); let App = React.createClass({ - render: function(){ + render: function() { return
@@ -50,7 +50,7 @@ describe("Core Experiment", function() { } }); try { - yield new Promise(function(resolve, reject){ + yield new Promise(function(resolve, reject) { ReactDOM.render(, container, resolve); }); } catch(error) { @@ -62,32 +62,32 @@ describe("Core Experiment", function() { } throw new Error("Experiment has invalid children."); })); - it("should update on componentWillReceiveProps.", co.wrap(function *(){ + it("should update on componentWillReceiveProps.", co.wrap(function *() { let experimentName = UUID.v4(); let setState; - let getValueA = function(){ + let getValueA = function() { return "A"; } let getValueB = function() { return "B"; } let App = React.createClass({ - getInitialState: function(){ + getInitialState: function() { return { value: getValueA } }, - componentWillMount: function(){ + componentWillMount: function() { setState = this.setState.bind(this); }, - render: function(){ + render: function() { return
; } }); - yield new Promise(function(resolve, reject){ + yield new Promise(function(resolve, reject) { ReactDOM.render(, container, resolve); }); let elementA = document.getElementById('variant-a'); @@ -103,10 +103,10 @@ describe("Core Experiment", function() { assert.notEqual(elementB, null); ReactDOM.unmountComponentAtNode(container); })); - it("should update the children when props change.", co.wrap(function *(){ + it("should update the children when props change.", co.wrap(function *() { let experimentName = UUID.v4(); let SubComponent = React.createClass({ - render(){ + render() { return (
{this.props.text} @@ -115,19 +115,19 @@ describe("Core Experiment", function() { } }); let App = React.createClass({ - render: function(){ + render: function() { return
; } }); - yield new Promise(function(resolve, reject){ + yield new Promise(function(resolve, reject) { let component = ReactDOM.render(,container, resolve); }); let elementAText = document.getElementById('variant-a-text'); assert.equal(elementAText.textContent, "original text"); - yield new Promise(function(resolve, reject){ + yield new Promise(function(resolve, reject) { component = ReactDOM.render(,container, resolve); }); elementAText = document.getElementById('variant-a-text'); diff --git a/test/browser/debugger.test.jsx b/test/browser/debugger.test.jsx index fdd5d21..7d9f2e4 100644 --- a/test/browser/debugger.test.jsx +++ b/test/browser/debugger.test.jsx @@ -13,7 +13,7 @@ ES6Promise.polyfill(); // See http://stackoverflow.com/a/985070 -function hasCSSSelector(s){ +function hasCSSSelector(s) { if(!document.styleSheets) { return ''; } @@ -22,7 +22,7 @@ function hasCSSSelector(s){ for(let i = 0; i < document.styleSheets.length; i++) { let sheet = document.styleSheets[i]; let rules = sheet.rules ? sheet.rules : sheet.cssRules; - for(let j = 0; j < rules.length; j++){ + for(let j = 0; j < rules.length; j++) { let selector = rules[j].selectorText ? rules[j].selectorText : rules[j].toString(); if(selector.toLowerCase() === s) { return true; @@ -34,26 +34,26 @@ function hasCSSSelector(s){ describe("Debugger", function() { let container; - before(function(){ + before(function() { container = document.createElement("div"); container.id = "react"; document.getElementsByTagName('body')[0].appendChild(container); }); - after(function(){ + after(function() { document.getElementsByTagName('body')[0].removeChild(container); emitter._reset(); }); - it("should enable and disable.", co.wrap(function *(){ + it("should enable and disable.", co.wrap(function *() { let experimentName = UUID.v4(); let App = React.createClass({ - render: function(){ + render: function() { return
; } }); - yield new Promise(function(resolve, reject){ + yield new Promise(function(resolve, reject) { ReactDOM.render(, container, resolve); }); experimentDebugger.enable(); @@ -70,17 +70,17 @@ describe("Debugger", function() { experimentDebugger.disable(); assert.equal(hasCSSSelector("#pushtell-debugger"), false); }); - it("should change an experiment's value.", co.wrap(function *(){ + it("should change an experiment's value.", co.wrap(function *() { let experimentName = UUID.v4(); let App = React.createClass({ - render: function(){ + render: function() { return
; } }); - yield new Promise(function(resolve, reject){ + yield new Promise(function(resolve, reject) { ReactDOM.render(, container, resolve); }); experimentDebugger.enable(); diff --git a/test/browser/emitter.test.jsx b/test/browser/emitter.test.jsx index 814e912..37b5e12 100644 --- a/test/browser/emitter.test.jsx +++ b/test/browser/emitter.test.jsx @@ -12,41 +12,41 @@ ES6Promise.polyfill(); describe("Emitter", function() { let container; - before(function(){ + before(function() { container = document.createElement("div"); container.id = "react"; document.getElementsByTagName('body')[0].appendChild(container); }); - after(function(){ + after(function() { document.getElementsByTagName('body')[0].removeChild(container); emitter._reset(); }); - it("should throw an error when passed an invalid name argument.", function (){ - assert.throws(function(){emitter.emitWin(1)}, /type \'string\'/); + it("should throw an error when passed an invalid name argument.", function () { + assert.throws(function() {emitter.emitWin(1)}, /type \'string\'/); }); - it("should emit when a variant is played.", co.wrap(function *(){ + it("should emit when a variant is played.", co.wrap(function *() { let experimentName = UUID.v4(); let playedVariantName = null; - let playCallback = function(experimentName, variantName){ + let playCallback = function(experimentName, variantName) { playedVariantName = variantName; }; let experimentNameGlobal = null; let playedVariantNameGlobal = null; - let playCallbackGlobal = function(experimentName, variantName){ + let playCallbackGlobal = function(experimentName, variantName) { experimentNameGlobal = experimentName; playedVariantNameGlobal = variantName; }; let playSubscription = emitter.addPlayListener(experimentName, playCallback); let playSubscriptionGlobal = emitter.addPlayListener(playCallbackGlobal); let App = React.createClass({ - render: function(){ + render: function() { return
; } }); - yield new Promise(function(resolve, reject){ + yield new Promise(function(resolve, reject) { ReactDOM.render(, container, resolve); }); assert.equal(playedVariantName, "A"); @@ -56,29 +56,29 @@ describe("Emitter", function() { playSubscriptionGlobal.remove(); ReactDOM.unmountComponentAtNode(container); })); - it("should emit when a variant wins.", co.wrap(function *(){ + it("should emit when a variant wins.", co.wrap(function *() { let experimentName = UUID.v4(); let winningVariantName = null; - let winCallback = function(experimentName, variantName){ + let winCallback = function(experimentName, variantName) { winningVariantName = variantName; }; let experimentNameGlobal = null; let winningVariantNameGlobal = null; - let winCallbackGlobal = function(experimentName, variantName){ + let winCallbackGlobal = function(experimentName, variantName) { experimentNameGlobal = experimentName; winningVariantNameGlobal = variantName; }; let winSubscription = emitter.addWinListener(experimentName, winCallback); let winSubscriptionGlobal = emitter.addWinListener(winCallbackGlobal); let App = React.createClass({ - render: function(){ + render: function() { return
; } }); - yield new Promise(function(resolve, reject){ + yield new Promise(function(resolve, reject) { ReactDOM.render(, container, resolve); }); emitter.emitWin(experimentName); @@ -89,32 +89,32 @@ describe("Emitter", function() { winSubscriptionGlobal.remove(); ReactDOM.unmountComponentAtNode(container); })); - it("should emit when a variant is clicked.", co.wrap(function *(){ + it("should emit when a variant is clicked.", co.wrap(function *() { let experimentName = UUID.v4(); let winningVariantName = null; - let winCallback = function(experimentName, variantName){ + let winCallback = function(experimentName, variantName) { winningVariantName = variantName; }; let experimentNameGlobal = null; let winningVariantNameGlobal = null; - let winCallbackGlobal = function(experimentName, variantName){ + let winCallbackGlobal = function(experimentName, variantName) { experimentNameGlobal = experimentName; winningVariantNameGlobal = variantName; }; let winSubscription = emitter.addWinListener(experimentName, winCallback); let winSubscriptionGlobal = emitter.addWinListener(winCallbackGlobal); let App = React.createClass({ - onClickVariant: function(e){ + onClickVariant: function(e) { this.refs.experiment.win(); }, - render: function(){ + render: function() { return A B ; } }); - yield new Promise(function(resolve, reject){ + yield new Promise(function(resolve, reject) { ReactDOM.render(, container, resolve); }); let elementA = document.getElementById('variant-a'); @@ -126,29 +126,29 @@ describe("Emitter", function() { winSubscriptionGlobal.remove(); ReactDOM.unmountComponentAtNode(container); })); - it("should emit when a variant is chosen.", co.wrap(function *(){ + it("should emit when a variant is chosen.", co.wrap(function *() { let experimentName = UUID.v4(); let activeVariantName = null; - let activeVariantCallback = function(experimentName, variantName){ + let activeVariantCallback = function(experimentName, variantName) { activeVariantName = variantName; }; let experimentNameGlobal = null; let activeVariantNameGlobal = null; - let activeVariantCallbackGlobal = function(experimentName, variantName){ + let activeVariantCallbackGlobal = function(experimentName, variantName) { experimentNameGlobal = experimentName; activeVariantNameGlobal = variantName; }; let activeVariantSubscription = emitter.addActiveVariantListener(experimentName, activeVariantCallback); let activeVariantSubscriptionGlobal = emitter.addActiveVariantListener(activeVariantCallbackGlobal); let App = React.createClass({ - render: function(){ + render: function() { return A B ; } }); - yield new Promise(function(resolve, reject){ + yield new Promise(function(resolve, reject) { ReactDOM.render(, container, resolve); }); assert.equal(activeVariantName, "A"); @@ -158,33 +158,33 @@ describe("Emitter", function() { activeVariantSubscriptionGlobal.remove(); ReactDOM.unmountComponentAtNode(container); })); - it("should get the experiment value.", co.wrap(function *(){ + it("should get the experiment value.", co.wrap(function *() { let experimentName = UUID.v4(); let App = React.createClass({ - render: function(){ + render: function() { return A B ; } }); - yield new Promise(function(resolve, reject){ + yield new Promise(function(resolve, reject) { ReactDOM.render(, container, resolve); }); assert.equal(emitter.getActiveVariant(experimentName), "A"); ReactDOM.unmountComponentAtNode(container); })); - it("should update the rendered component.", co.wrap(function *(){ + it("should update the rendered component.", co.wrap(function *() { let experimentName = UUID.v4(); let App = React.createClass({ - render: function(){ + render: function() { return
; } }); - yield new Promise(function(resolve, reject){ + yield new Promise(function(resolve, reject) { ReactDOM.render(, container, resolve); }); let elementA = document.getElementById('variant-a'); @@ -198,11 +198,11 @@ describe("Emitter", function() { assert.notEqual(elementB, null); ReactDOM.unmountComponentAtNode(container); })); - it("should report active components.", co.wrap(function *(){ + it("should report active components.", co.wrap(function *() { let experimentNameA = UUID.v4(); let experimentNameB = UUID.v4(); let AppA = React.createClass({ - render: function(){ + render: function() { return
@@ -210,7 +210,7 @@ describe("Emitter", function() { } }); let AppB = React.createClass({ - render: function(){ + render: function() { return
@@ -218,14 +218,14 @@ describe("Emitter", function() { } }); let AppCombined = React.createClass({ - render: function(){ + render: function() { return
; } }); - yield new Promise(function(resolve, reject){ + yield new Promise(function(resolve, reject) { ReactDOM.render(, container, resolve); }); let activeExperiments = {}; @@ -235,7 +235,7 @@ describe("Emitter", function() { }; assert.deepEqual(emitter.getActiveExperiments(), activeExperiments); ReactDOM.unmountComponentAtNode(container); - yield new Promise(function(resolve, reject){ + yield new Promise(function(resolve, reject) { ReactDOM.render(, container, resolve); }); activeExperiments = {}; @@ -245,7 +245,7 @@ describe("Emitter", function() { }; assert.deepEqual(emitter.getActiveExperiments(), activeExperiments); ReactDOM.unmountComponentAtNode(container); - yield new Promise(function(resolve, reject){ + yield new Promise(function(resolve, reject) { ReactDOM.render(, container, resolve); }); activeExperiments = {}; diff --git a/test/browser/experiment.test.jsx b/test/browser/experiment.test.jsx index e17b6c6..f2765bb 100644 --- a/test/browser/experiment.test.jsx +++ b/test/browser/experiment.test.jsx @@ -13,9 +13,9 @@ ES6Promise.polyfill(); let store; let noopStore = { - getItem: function(){}, - setItem: function(){}, - clear: function(){} + getItem: function() {}, + setItem: function() {}, + clear: function() {} }; if(typeof window !== 'undefined' && 'localStorage' in window && window['localStorage'] !== null) { @@ -37,23 +37,23 @@ if(typeof window !== 'undefined' && 'localStorage' in window && window['localSto describe("Experiment", function() { let container; - before(function(){ + before(function() { container = document.createElement("div"); container.id = "react"; document.getElementsByTagName('body')[0].appendChild(container); }); - after(function(){ + after(function() { document.getElementsByTagName('body')[0].removeChild(container); emitter._reset(); }); - it("should choose a version.", co.wrap(function *(){ + it("should choose a version.", co.wrap(function *() { let experimentName = UUID.v4(); let variantNames = []; for(let i = 0; i < 100; i++) { variantNames.push(UUID.v4()); } let App = React.createClass({ - render: function(){ + render: function() { return {variantNames.map(name => { return
@@ -61,12 +61,12 @@ describe("Experiment", function() {
; } }); - yield new Promise(function(resolve, reject){ + yield new Promise(function(resolve, reject) { ReactDOM.render(, container, resolve); }); ReactDOM.unmountComponentAtNode(container); })); - it("should render the correct variant.", co.wrap(function *(){ + it("should render the correct variant.", co.wrap(function *() { let experimentName = UUID.v4(); let variantNames = []; for(let i = 0; i < 100; i++) { @@ -74,7 +74,7 @@ describe("Experiment", function() { } let defaultVariantName = variantNames[Math.floor(Math.random() * variantNames.length)]; let AppWithdefaultVariantName = React.createClass({ - render: function(){ + render: function() { return {variantNames.map(name => { return
@@ -83,7 +83,7 @@ describe("Experiment", function() { } }); let AppWithoutdefaultVariantName = React.createClass({ - render: function(){ + render: function() { return {variantNames.map(name => { return
@@ -91,26 +91,26 @@ describe("Experiment", function() {
; } }); - yield new Promise(function(resolve, reject){ + yield new Promise(function(resolve, reject) { ReactDOM.render(, container, resolve); }); let elementWithdefaultVariantName = document.getElementById('variant-' + defaultVariantName); assert.notEqual(elementWithdefaultVariantName, null); ReactDOM.unmountComponentAtNode(container); - yield new Promise(function(resolve, reject){ + yield new Promise(function(resolve, reject) { ReactDOM.render(, container, resolve); }); let elementWithoutdefaultVariantName = document.getElementById('variant-' + defaultVariantName); assert.notEqual(elementWithoutdefaultVariantName, null); ReactDOM.unmountComponentAtNode(container); })); - it("should error if variants are added to a experiment after a variant was selected.", co.wrap(function *(){ + it("should error if variants are added to a experiment after a variant was selected.", co.wrap(function *() { let experimentName = UUID.v4(); let AppPart1 = React.createClass({ - onClickVariant: function(e){ + onClickVariant: function(e) { this.refs.experiment.win(); }, - render: function(){ + render: function() { return A B @@ -118,22 +118,22 @@ describe("Experiment", function() { } }); let AppPart2 = React.createClass({ - onClickVariant: function(e){ + onClickVariant: function(e) { this.refs.experiment.win(); }, - render: function(){ + render: function() { return C D ; } }); - yield new Promise(function(resolve, reject){ + yield new Promise(function(resolve, reject) { ReactDOM.render(, container, resolve); }); ReactDOM.unmountComponentAtNode(container); try { - yield new Promise(function(resolve, reject){ + yield new Promise(function(resolve, reject) { ReactDOM.render(, container, resolve); }); } catch(error) { @@ -145,14 +145,14 @@ describe("Experiment", function() { } throw new Error("New variant was added after variant was selected."); })); - it("should not error if variants are added to a experiment after a variant was selected if variants were defined.", co.wrap(function *(){ + it("should not error if variants are added to a experiment after a variant was selected if variants were defined.", co.wrap(function *() { let experimentName = UUID.v4(); emitter.defineVariants(experimentName, ["A", "B", "C", "D"]); let AppPart1 = React.createClass({ - onClickVariant: function(e){ + onClickVariant: function(e) { this.refs.experiment.win(); }, - render: function(){ + render: function() { return A B @@ -160,33 +160,33 @@ describe("Experiment", function() { } }); let AppPart2 = React.createClass({ - onClickVariant: function(e){ + onClickVariant: function(e) { this.refs.experiment.win(); }, - render: function(){ + render: function() { return C D ; } }); - yield new Promise(function(resolve, reject){ + yield new Promise(function(resolve, reject) { ReactDOM.render(, container, resolve); }); ReactDOM.unmountComponentAtNode(container); - yield new Promise(function(resolve, reject){ + yield new Promise(function(resolve, reject) { ReactDOM.render(, container, resolve); }); ReactDOM.unmountComponentAtNode(container); })); - it("should error if a variant is added to an experiment after variants were defined.", co.wrap(function *(){ + it("should error if a variant is added to an experiment after variants were defined.", co.wrap(function *() { let experimentName = UUID.v4(); emitter.defineVariants(experimentName, ["A", "B", "C"]); let AppPart1 = React.createClass({ - onClickVariant: function(e){ + onClickVariant: function(e) { this.refs.experiment.win(); }, - render: function(){ + render: function() { return A B @@ -194,22 +194,22 @@ describe("Experiment", function() { } }); let AppPart2 = React.createClass({ - onClickVariant: function(e){ + onClickVariant: function(e) { this.refs.experiment.win(); }, - render: function(){ + render: function() { return C D ; } }); - yield new Promise(function(resolve, reject){ + yield new Promise(function(resolve, reject) { ReactDOM.render(, container, resolve); }); ReactDOM.unmountComponentAtNode(container); try { - yield new Promise(function(resolve, reject){ + yield new Promise(function(resolve, reject) { ReactDOM.render(, container, resolve); }); } catch(error) { @@ -221,48 +221,48 @@ describe("Experiment", function() { } throw new Error("New variant was added after variants were defined."); })); - it("should not error if an older test variant is set.", co.wrap(function *(){ + it("should not error if an older test variant is set.", co.wrap(function *() { let experimentName = UUID.v4(); localStorage.setItem("PUSHTELL-" + experimentName, "C"); let App = React.createClass({ - render: function(){ + render: function() { return A B ; } }); - yield new Promise(function(resolve, reject){ + yield new Promise(function(resolve, reject) { ReactDOM.render(, container, resolve); }); ReactDOM.unmountComponentAtNode(container); })); - it("should emit when a variant is clicked.", co.wrap(function *(){ + it("should emit when a variant is clicked.", co.wrap(function *() { let experimentName = UUID.v4(); let winningVariantName = null; - let winCallback = function(experimentName, variantName){ + let winCallback = function(experimentName, variantName) { winningVariantName = variantName; }; let experimentNameGlobal = null; let winningVariantNameGlobal = null; - let winCallbackGlobal = function(experimentName, variantName){ + let winCallbackGlobal = function(experimentName, variantName) { experimentNameGlobal = experimentName; winningVariantNameGlobal = variantName; }; let winSubscription = emitter.addWinListener(experimentName, winCallback); let winSubscriptionGlobal = emitter.addWinListener(winCallbackGlobal); let App = React.createClass({ - onClickVariant: function(e){ + onClickVariant: function(e) { this.refs.experiment.win(); }, - render: function(){ + render: function() { return A B ; } }); - yield new Promise(function(resolve, reject){ + yield new Promise(function(resolve, reject) { ReactDOM.render(, container, resolve); }); let elementA = document.getElementById('variant-a'); @@ -274,7 +274,7 @@ describe("Experiment", function() { winSubscriptionGlobal.remove(); ReactDOM.unmountComponentAtNode(container); })); - it("should choose the same variant when a user identifier is defined.", co.wrap(function *(){ + it("should choose the same variant when a user identifier is defined.", co.wrap(function *() { let userIdentifier = UUID.v4(); let experimentName = UUID.v4(); let variantNames = []; @@ -282,7 +282,7 @@ describe("Experiment", function() { variantNames.push(UUID.v4()); } let App = React.createClass({ - render: function(){ + render: function() { return {variantNames.map(name => { return
@@ -291,10 +291,10 @@ describe("Experiment", function() { } }); let chosenVariant; - emitter.once("play", function(experimentName, variantName){ + emitter.once("play", function(experimentName, variantName) { chosenVariant = variantName; }); - yield new Promise(function(resolve, reject){ + yield new Promise(function(resolve, reject) { ReactDOM.render(, container, resolve); }); ReactDOM.unmountComponentAtNode(container); @@ -302,7 +302,7 @@ describe("Experiment", function() { for(let i = 0; i < 100; i++) { emitter._reset(); store.clear(); - yield new Promise(function(resolve, reject){ + yield new Promise(function(resolve, reject) { // eslint-disable-line no-loop-func ReactDOM.render(, container, resolve); }); let element = document.getElementById('variant-' + chosenVariant); diff --git a/test/browser/helpers.mixpanel.test.jsx b/test/browser/helpers.mixpanel.test.jsx index 9ffb853..6bd474e 100644 --- a/test/browser/helpers.mixpanel.test.jsx +++ b/test/browser/helpers.mixpanel.test.jsx @@ -14,16 +14,16 @@ ES6Promise.polyfill(); describe("Mixpanel Helper", function() { this.timeout(10000); let container; - before(co.wrap(function *(){ + before(function () { container = document.createElement("div"); container.id = "react"; document.getElementsByTagName('body')[0].appendChild(container); - })); - after(function(){ + }); + after(function() { document.getElementsByTagName('body')[0].removeChild(container); emitter._reset(); }); - it("should error if Mixpanel global is not set.", function (){ + it("should error if Mixpanel global is not set.", function () { assert.throws( function() { mixpanelHelper.enable(); @@ -32,7 +32,7 @@ describe("Mixpanel Helper", function() { } ); }); - it("should error if Mixpanel is disabled before it is enabled.", function (){ + it("should error if Mixpanel is disabled before it is enabled.", function () { assert.throws( function() { mixpanelHelper.disable(); @@ -41,25 +41,25 @@ describe("Mixpanel Helper", function() { } ); }); - it("should report results to Mixpanel.", co.wrap(function *(){ + it("should report results to Mixpanel.", co.wrap(function *() { let playPromise, winPromise; if(canUseDOM) { // Mixpanel embed code wrapped in a promise. - yield new Promise(function(resolve, reject){ - (function(e,b){if(!b.__SV){var a,f,i,g;window.mixpanel=b;b._i=[];b.init=function(a,e,d){function f(b,h){var a=h.split(".");2==a.length&&(b=b[a[0]],h=a[1]);b[h]=function(){b.push([h].concat(Array.prototype.slice.call(arguments,0)))}}var c=b;"undefined"!==typeof d?c=b[d]=[]:d="mixpanel";c.people=c.people||[];c.toString=function(b){var a="mixpanel";"mixpanel"!==d&&(a+="."+d);b||(a+=" (stub)");return a};c.people.toString=function(){return c.toString(1)+".people (stub)"};i="disable time_event track track_pageview track_links track_forms register register_once alias unregister identify name_tag set_config people.set people.set_once people.increment people.append people.union people.track_charge people.clear_charges people.delete_user".split(" "); + yield new Promise(function(resolve, reject) { + (function(e,b) {if(!b.__SV) {var a,f,i,g;window.mixpanel=b;b._i=[];b.init=function(a,e,d) {function f(b,h) {var a=h.split(".");2==a.length&&(b=b[a[0]],h=a[1]);b[h]=function() {b.push([h].concat(Array.prototype.slice.call(arguments,0)))}}var c=b;"undefined"!==typeof d?c=b[d]=[]:d="mixpanel";c.people=c.people||[];c.toString=function(b) {var a="mixpanel";"mixpanel"!==d&&(a+="."+d);b||(a+=" (stub)");return a};c.people.toString=function() {return c.toString(1)+".people (stub)"};i="disable time_event track track_pageview track_links track_forms register register_once alias unregister identify name_tag set_config people.set people.set_once people.increment people.append people.union people.track_charge people.clear_charges people.delete_user".split(" "); for(g=0;g
; } }); - yield new Promise(function(resolve, reject){ + yield new Promise(function(resolve, reject) { ReactDOM.render(, container, resolve); }); yield playPromise; diff --git a/test/browser/helpers.segment.test.jsx b/test/browser/helpers.segment.test.jsx index 87ee484..7d4f3fa 100644 --- a/test/browser/helpers.segment.test.jsx +++ b/test/browser/helpers.segment.test.jsx @@ -14,16 +14,16 @@ ES6Promise.polyfill(); describe("Segment Helper", function() { this.timeout(10000); let container; - before(co.wrap(function *(){ + before(function () { container = document.createElement("div"); container.id = "react"; document.getElementsByTagName('body')[0].appendChild(container); - })); - after(function(){ + }); + after(function() { document.getElementsByTagName('body')[0].removeChild(container); emitter._reset(); }); - it("should error if Segment global is not set.", function (){ + it("should error if Segment global is not set.", function () { assert.throws( function() { segmentHelper.enable(); @@ -32,7 +32,7 @@ describe("Segment Helper", function() { } ); }); - it("should error if Segment is disabled before it is enabled.", function (){ + it("should error if Segment is disabled before it is enabled.", function () { assert.throws( function() { segmentHelper.disable(); @@ -41,26 +41,26 @@ describe("Segment Helper", function() { } ); }); - it("should report results to Segment.", co.wrap(function *(){ + it("should report results to Segment.", co.wrap(function *() { let playPromise, winPromise; if(canUseDOM) { // Segment Analytics.js embed code wrapped in a promise. - yield new Promise(function(resolve, reject){ - !function(){var analytics=window.analytics=window.analytics||[];if(!analytics.initialize)if(analytics.invoked)window.console&&console.error&&console.error("Segment snippet included twice.");else{analytics.invoked=!0;analytics.methods=["trackSubmit","trackClick","trackLink","trackForm","pageview","identify","reset","group","track","ready","alias","page","once","off","on"];analytics.factory=function(t){return function(){var e=Array.prototype.slice.call(arguments);e.unshift(t);analytics.push(e);return analytics}};for(var t=0;t
; } }); - yield new Promise(function(resolve, reject){ + yield new Promise(function(resolve, reject) { ReactDOM.render(, container, resolve); }); yield playPromise; diff --git a/test/browser/karma.conf.js b/test/browser/karma.conf.js index 462127a..d284ac5 100644 --- a/test/browser/karma.conf.js +++ b/test/browser/karma.conf.js @@ -135,7 +135,7 @@ module.exports = function (karma) { accessKey: process.env.BROWSERSTACK_ACCESS_KEY, pollingTimeout: 10000 }; - options.browsers = Object.keys(options.customLaunchers).filter(function(key){ + options.browsers = Object.keys(options.customLaunchers).filter(function(key) { return key.indexOf("bs_") !== -1; }); } else { diff --git a/test/browser/variant.test.jsx b/test/browser/variant.test.jsx index f9d1d08..052dd11 100644 --- a/test/browser/variant.test.jsx +++ b/test/browser/variant.test.jsx @@ -11,43 +11,43 @@ ES6Promise.polyfill(); describe("Variant", function() { let container; - before(function(){ + before(function() { container = document.createElement("div"); container.id = "react"; document.getElementsByTagName('body')[0].appendChild(container); }); - after(function(){ + after(function() { document.getElementsByTagName('body')[0].removeChild(container); emitter._reset(); }); - it("should render text nodes.", co.wrap(function *(){ + it("should render text nodes.", co.wrap(function *() { let experimentName = UUID.v4(); let variantTextA = UUID.v4(); let variantTextB = UUID.v4(); let App = React.createClass({ - render: function(){ + render: function() { return {variantTextA} {variantTextB} ; } }); - yield new Promise(function(resolve, reject){ + yield new Promise(function(resolve, reject) { ReactDOM.render(, container, resolve); }); assert.notEqual(container.innerHTML.indexOf(variantTextA), null); })); - it("should render components.", co.wrap(function *(){ + it("should render components.", co.wrap(function *() { let experimentName = UUID.v4(); let App = React.createClass({ - render: function(){ + render: function() { return
; } }); - yield new Promise(function(resolve, reject){ + yield new Promise(function(resolve, reject) { ReactDOM.render(, container, resolve); }); let elementA = document.getElementById('variant-a'); @@ -56,10 +56,10 @@ describe("Variant", function() { assert.equal(elementB, null); ReactDOM.unmountComponentAtNode(container); })); - it("should render arrays of components.", co.wrap(function *(){ + it("should render arrays of components.", co.wrap(function *() { let experimentName = UUID.v4(); let App = React.createClass({ - render: function(){ + render: function() { return
@@ -72,7 +72,7 @@ describe("Variant", function() { ; } }); - yield new Promise(function(resolve, reject){ + yield new Promise(function(resolve, reject) { ReactDOM.render(, container, resolve); }); let elementA = document.getElementById('variant-a'); diff --git a/test/browser/weighted.test.jsx b/test/browser/weighted.test.jsx index 00d2703..fd417be 100644 --- a/test/browser/weighted.test.jsx +++ b/test/browser/weighted.test.jsx @@ -13,9 +13,9 @@ ES6Promise.polyfill(); let store; let noopStore = { - getItem: function(){}, - setItem: function(){}, - clear: function(){} + getItem: function() {}, + setItem: function() {}, + clear: function() {} }; if(typeof window !== 'undefined' && 'localStorage' in window && window['localStorage'] !== null) { @@ -42,16 +42,16 @@ function add(a, b) { describe("Weighted Experiment", function() { this.timeout(10000); let container; - before(function(){ + before(function() { container = document.createElement("div"); container.id = "react"; document.getElementsByTagName('body')[0].appendChild(container); }); - after(function(){ + after(function() { document.getElementsByTagName('body')[0].removeChild(container); emitter._reset(); }); - it("should choose a weighted variants.", co.wrap(function *(){ + it("should choose a weighted variants.", co.wrap(function *() { const experimentName = UUID.v4(); const variantNames = []; const variantWeights = []; @@ -64,7 +64,7 @@ describe("Weighted Experiment", function() { emitter.defineVariants(experimentName, variantNames, variantWeights); assert.equal(emitter.getSortedVariantWeights(experimentName).reduce(add, 0), weightSum); let App = React.createClass({ - render: function(){ + render: function() { return {variantNames.map(name => { return
@@ -73,26 +73,26 @@ describe("Weighted Experiment", function() { } }); let chosenVariant; - emitter.addListener("play", function(experimentName, variantName){ + emitter.addListener("play", function(experimentName, variantName) { playCount[variantName] = playCount[variantName] || 0; playCount[variantName] += 1; }); for(let i = 0; i < 1000; i++) { - yield new Promise(function(resolve, reject){ + yield new Promise(function(resolve, reject) { // eslint-disable-line no-loop-func ReactDOM.render(, container, resolve); }); ReactDOM.unmountComponentAtNode(container); store.clear(); emitter._resetPlayedExperiments(); } - const playSum = Object.keys(playCount).map(function(variantName){ + const playSum = Object.keys(playCount).map(function(variantName) { return playCount[variantName] || 0; }).reduce(add, 0); - const playCountToWeightRatios = variantNames.map(function(variantName, index){ - return (playCount[variantName] / playSum) / (variantWeights[index] / weightSum) + const playCountToWeightRatios = variantNames.map(function(variantName, index) { + return playCount[variantName] / playSum / (variantWeights[index] / weightSum) }); const ratioMean = playCountToWeightRatios.reduce(add, 0) / playCountToWeightRatios.length; - const ratioVariance = playCountToWeightRatios.map(function(ratio){ + const ratioVariance = playCountToWeightRatios.map(function(ratio) { return Math.pow(ratioMean - ratio, 2); }).reduce(add, 0); const ratioStandardDeviation = Math.sqrt(ratioVariance);