UNPKG

react-ab

Version:

Simple declarative and universal A/B testing component for React.

176 lines (133 loc) 6.69 kB
var getRandomValues = require("get-random-values"); global.document = require("jsdom").jsdom(""); global.window = document.parentWindow; global.navigator = window.navigator; var defineGetRandomValues = function () { global.window.crypto = { getRandomValues: getRandomValues }; }; var assert = require("assert"); var React = require("react/addons") , TestUtils = React.addons.TestUtils; var Experiment = require("../react-ab").Experiment , Variant = require("../react-ab").Variant; describe("Experiment", function () { var createExperiment = function (name, choice, variants, factory) { factory = factory || function (variant) { return React.createElement("span", null, variant); }; var variantNodes = variants.map(function (variant) { return React.createElement(Variant, { key: variant, name: variant }, factory(variant)); }); return TestUtils.renderIntoDocument(React.createElement(Experiment, { name: name, onChoice: choice }, variantNodes)); }; it("should choose a variant", function (done) { var variants = ["one", "two", "three"]; var count1 = 3; var choice1 = function (experiment, variant, index, ret) { count1 -= 1; assert.equal(variants[index], variant); assert.ok(variants.indexOf(variant) !== -1); assert.equal(count1 == 1, ret); }; var ex1 = createExperiment("test1", choice1, variants) , span1 = TestUtils.findRenderedDOMComponentWithTag(ex1, "span") , variant1 = span1.getDOMNode().textContent; assert.ok(variants.indexOf(variant1) !== -1); var ex2 = createExperiment("test1", choice1, variants) , span2 = TestUtils.findRenderedDOMComponentWithTag(ex2, "span") , variant2 = span2.getDOMNode().textContent; assert.equal(variant1, variant2); // variants should be the same as the cookie was not cleared assert.equal(ex1.getVariant(), ex2.getVariant()); // get variant should also work as intended. defineGetRandomValues(); // define random values here to test it ex1.clearCookie(); var ex3 = createExperiment("test1", choice1, variants) , span3 = TestUtils.findRenderedDOMComponentWithTag(ex3, "span") , variant3 = span3.getDOMNode().textContent; assert.ok(variants.indexOf(variant3) !== -1); // test another cookie var count2 = 2; var choice2 = function (experiment, variant, index, ret) { count2 -= 1; assert.equal(experiment, " test2"); assert.equal(variants[index], variant); assert.ok(variants.indexOf(variant) !== -1); if (count2 === 0) { done(); } }; var ex4 = createExperiment(" test2", choice2, variants) , span4 = TestUtils.findRenderedDOMComponentWithTag(ex4, "span") , variant4 = span4.getDOMNode().textContent; assert.ok(variants.indexOf(variant4) !== -1); var ex5 = createExperiment(" test2", choice2, variants) , span5 = TestUtils.findRenderedDOMComponentWithTag(ex5, "span") , variant5 = span5.getDOMNode().textContent; assert.ok(variants.indexOf(variant5) !== -1); assert.equal(variant4, variant5); assert.equal(ex4.getVariant(), ex5.getVariant()); }); it("should work when variants have multiple children", function () { var variant1 = React.createElement(Variant, { name: "one" }, React.createElement("span", null, ""), React.createElement("span", null, "")); var variant2 = React.createElement(Variant, { name: "two" }, React.createElement("span", null, ""), React.createElement("span", null, "")); var ex = TestUtils.renderIntoDocument(React.createElement(Experiment, { name: "test", onChoice: function () { }}, variant1, variant2)); assert.ok(ex); }); it("should work universal", function () { var variant1 = React.createElement(Variant, { name: "one" }, React.createElement("span", null, "one")); var variant2 = React.createElement(Variant, { name: "two" }, React.createElement("span", null, "two")); var cookie = {}; var html = React.renderToString(React.createElement(Experiment, { name: "test" , get: function (x) { return cookie[x]; } , set: function (x, y) { cookie[x] = y; } , clear: function (x) { delete cookie[x] } , onChoice: function () { } }, variant1, variant2)); assert.ok(/(one|two)/.test(html), "one or two should be in html"); assert.equal(Object.keys(cookie).length, 1, "there should be one key"); }); it("should work with universal context", function () { var cookie = {}; var App = React.createClass({ childContextTypes: { getExperiment: React.PropTypes.func , setExperiment: React.PropTypes.func , clearExperiment: React.PropTypes.func } , getChildContext: function () { return { getExperiment: function (x) { return cookie[x]; } , setExperiment: function (x, y) { cookie[x] = y; } , clearExperiment: function (x) { delete cookie[x] } }; } , render: function () { var variant1 = React.createElement(Variant, { name: "one" }, React.createElement("span", null, "one")); var variant2 = React.createElement(Variant, { name: "two" }, React.createElement("span", null, "two")); return React.createElement(Experiment, { name: "test" , onChoice: function () { } }, variant1, variant2); } }); var html = React.renderToString(React.createElement(App)); assert.ok(/(one|two)/.test(html), "one or two should be in html"); assert.equal(Object.keys(cookie).length, 1, "there should be one key"); }); it("should work with text nodes", function () { var variant1 = React.createElement(Variant, { name: "one" }, "one"); var variant2 = React.createElement(Variant, { name: "two" }, "two"); var ex = TestUtils.renderIntoDocument(React.createElement(Experiment, { name: "test", onChoice: function () { }}, variant1, variant2)); assert.ok(ex); }); it("should test choose variant", function () { var variant1 = React.createElement(Variant, { name: "one" }, "one"); var variant2 = React.createElement(Variant, { name: "two" }, "two"); var ex = TestUtils.renderIntoDocument(React.createElement(Experiment, { name: "test", onChoice: function () { }}, variant1, variant2)); ex.chooseVariant(); assert.ok(ex); }); it("should work with null nodes", function () { var variant1 = React.createElement(Variant, { name: "one" }, null); var variant2 = React.createElement(Variant, { name: "two" }, null); var ex = TestUtils.renderIntoDocument(React.createElement(Experiment, { name: "test", onChoice: function () { }}, variant1, variant2)); assert.ok(ex); }); });