<commit_before>var expect = require("expect.js");
var JsonDB = require("../JsonDB.js");
var DatabaseError = require("../lib/Errors").DatabaseError;
var DataError = require("../lib/Errors").DataError;

var fs = require('fs');

var testFile1 = "test_file1";
var testFile2 = "dirCreation/test_file2";
var faulty = "test/faulty.json";
var testFile3 = "test_file3";
var testFile4 = "array_file";
describe('JsonDB', function () {
    describe('Exception/Error', function () {
        it('should create create a DataError', function () {
            var error = new DataError("Test", 5);
            expect(error).to.have.property("message", "Test");
            expect(error).to.have.property("id", 5);
            expect(error).to.have.property("inner");
            expect(error.toString()).to.eql("DataError: Test");
        })

        it('should create create a DatabaseError', function () {
            var nested = new Error("don't work");
            var error = new DatabaseError("Test", 5, nested);
            expect(error).to.have.property("message", "Test");
            expect(error).to.have.property("id", 5);
            expect(error).to.have.property("inner", nested);
            expect(error.toString()).to.eql("DatabaseError: Test:\nError: don't work");
        })

    });
    describe('Initialisation', function () {
        var db = new JsonDB(testFile1, true, true);

        it('should create the JSON File', function (done) {
            fs.exists(testFile1 + ".json", function (exists) {
                expect(exists).to.be.ok();
                done();
            });

        })

        it('should set en empty root', function () {
            expect(JSON.stringify(db.getData("/"))).to.eql("{}");
        })

        it('should return a DatabaseError when loading faulty file', function () {
            db = new JsonDB(faulty, true);
            expect(function (args) {
                db.getData(args);
            }).withArgs("/").to.throwException(function (e) {
                    expect(e).to.be.a(DatabaseError);
                });

        })
        it('should return a DatabaseError when saving without successful loading.', function () {
            expect(db.save).to.throwException(function (e) {
                expect(e).to.be.a(DatabaseError);
            });
        })

    })
    describe('Data Management', function () {

        var db = new JsonDB(testFile2, true);

        it('should store the data at the root', function () {
            var object = {test: {test: "test"}};
            db.push("/", object);
            expect(db.getData("/")).to.be(object);
        })
        it('should override the data at the root', function () {
            var object = {test: "test"};
            db.push("/", object);
            expect(db.getData("/")).to.be(object);
        })
        it('should merge the data at the root', function () {
            var object = {test: {test: ['Okay']}};
            db.push("/", object);
            var data = db.getData("/");
            expect(data).to.be(object);
            object = {test: {test: ['Perfect'], okay: "test"}}
            db.push("/", object, false);
            expect(JSON.stringify(db.getData("/"))).to.eql('{\"test\":{\"test\":[\"Okay\",\"Perfect\"],\"okay\":\"test\"}}');
        })
        it('should return right data for datapath', function () {
            db = new JsonDB(testFile2, true);
            expect(JSON.stringify(db.getData("/test"))).to.eql('{\"test\":[\"Okay\",\"Perfect\"],\"okay\":\"test\"}');
        })

        it('should override only the data at datapath', function () {
            var object = ['overriden'];
            db.push("/test/test", object);
            expect(db.getData("/test/test")).to.be(object);
        })
        it('should merge the data at datapath', function () {
            var object = ['test2'];
            db.push("/test/test", object, false);
            expect(JSON.stringify(db.getData("/test/test"))).to.eql('[\"overriden\",\"test2\"]');
        })

        it('should create the tree to reach datapath', function () {
            var object = ['test2'];
            db.push("/my/tree/is/awesome", object, false);
            expect(JSON.stringify(db.getData("/my/tree/is/awesome"))).to.eql('[\"test2\"]');
        })
        it('should throw an Error when merging Object with Array', function () {
            expect(function (path, data, override) {
                db.push(path, data, override);
            }).withArgs("/test/test", {myTest: "test"}, false).to.throwException(function (e) {
                    expect(e).to.be.a(DataError);
                });
        })

        it('should throw an Error when merging Array with Object', function () {
            expect(function (path, data, override) {
                db.push(path, data, override);
            }).withArgs("/test", ['test'], false).to.throwException(function (e) {
                    expect(e).to.be.a(DataError);
                });
        })

        it('should throw an Error when asking for empty datapath', function () {
            expect(function (args) {
                db.getData(args);
            }).withArgs("").to.throwException(function (e) {
                    expect(e).to.be.a(DataError);
                });

        })

        it('should delete the data', function () {
            db.delete("/test/test");
            expect(function (args) {
                db.getData(args);
            }).withArgs("/test/test").to.throwException(function (e) {
                    expect(e).to.be.a(DataError);
                });

        })

        it('should reload the file', function () {
            var data = JSON.stringify({test: "Okay", perfect: 1});
            fs.writeFileSync(testFile2 + ".json", data, 'utf8');
            db.reload();
            expect(db.getData("/test")).to.be("Okay");
            expect(db.getData("/perfect")).to.be(1);
        })
    });

    describe('Human Readable', function () {
        var db = new JsonDB(testFile3, true, true);
        it('should save the data in an human readable format', function (done) {
            var object = {test: {readable: "test"}};
            db.push("/", object);
            fs.readFile(testFile3 + ".json", "utf8", function (err, data) {
                if (err) {
                    done(err);
                    return;
                }
                expect(data).to.be(JSON.stringify(object, null, 4));
                done();
            });
        })

    });
    describe('Array Support', function () {
        var db = new JsonDB(testFile4, true);
        it('should create an array with a string at index 0', function () {
            db.push('/arraytest/myarray[0]', "test", true);
            var myarray = db.getData('/arraytest/myarray');
            expect(myarray).to.be.an('array');
            expect(myarray[0]).to.be('test');
        });
        it('should add an object at index 1', function () {
            var obj = {property: "perfect"};
            db.push('/arraytest/myarray[1]', obj, true);
            var myarray = db.getData('/arraytest/myarray');
            expect(myarray).to.be.an('array');
            expect(myarray[1]).to.be(obj);
        });

        it('should create a nested array with an object at index 0', function () {
            var data = {test: "works"};
            db.push('/arraytest/nested[0]/obj', data, true);
            var obj = db.getData('/arraytest/nested[0]');
            expect(obj).to.be.an('object');
            expect(obj).to.have.property('obj', data);
        });

        it('should access the object at index 1', function () {
            var obj = db.getData('/arraytest/myarray[1]');
            expect(obj).to.be.an('object');
            expect(obj).to.have.property('property', 'perfect');

        });
        it('should access the object property at index 1', function () {
            var property = db.getData('/arraytest/myarray[1]/property');
            expect(property).to.be.a('string');
            expect(property).to.be('perfect');
        });

        it('should throw an error when accessing non-present index', function () {
            var obj = {property: "perfect"};
            db.push('/arraytest/arrayTesting[0]', obj, true);
            expect(function (args) {
                db.getData(args);
            }).withArgs("/arraytest/arrayTesting[1]").to.throwException(function (e) {
                    expect(e).to.be.a(DataError);
                    expect(e).to.have.property('id', 10);
                });
        });

        it('should delete the object at index 1', function () {
            db.delete('/arraytest/myarray[1]');
            expect(function (args) {
                db.getData(args);
            }).withArgs("/arraytest/myarray[1]").to.throwException(function (e) {
                    expect(e).to.be.a(DataError);
                    expect(e).to.have.property('id', 10);
                });
        });

        it('should throw an error when deleting non-present index', function () {
            expect(function (args) {
                db.delete(args);
            }).withArgs("/arraytest/myarray[10]").to.throwException(function (e) {
                    expect(e).to.be.a(DataError);
                    expect(e).to.have.property('id', 10);
                });
        });

        it('should throw an error when trying to set an object as an array', function () {
            db.push('/arraytest/fakearray', {fake: "fake"}, true);
            expect(function (args) {
                db.push(args, {test: 'test'}, true);
            }).withArgs("/arraytest/fakearray[1]").to.throwException(function (e) {
                    expect(e).to.be.a(DataError);
                    expect(e).to.have.property('id', 11);
                });
        });

        it('should throw an error when trying to access an object as an array', function () {
            db.push('/arraytest/fakearray', {fake: "fake"}, true);
            expect(function (args) {
                db.getData(args);
            }).withArgs("/arraytest/fakearray[1]").to.throwException(function (e) {
                    expect(e).to.be.a(DataError);
                    expect(e).to.have.property('id', 11);
                });
        });
        it('should throw an error when trying to set an object as an array (2)', function () {
            db.push('/arraytest/fakearray', {fake: "fake"}, true);
            expect(function (args) {
                db.push(args, {test: 'test'}, true);
            }).withArgs("/arraytest/fakearray[1]/fake").to.throwException(function (e) {
                    expect(e).to.be.a(DataError);
                    expect(e).to.have.property('id', 11);
                });
        });

    });
    describe('Cleanup', function () {
        it('should remove the test files', function () {
            fs.unlinkSync(testFile1 + ".json");
            fs.unlinkSync(testFile2 + ".json");
            fs.unlinkSync(testFile3 + ".json");
            fs.unlinkSync(testFile4 + ".json");
            fs.rmdirSync("dirCreation");
        });
    });

});<commit_msg>[MOD] Using test dir for test files<commit_after>var expect = require("expect.js");
var JsonDB = require("../JsonDB.js");
var DatabaseError = require("../lib/Errors").DatabaseError;
var DataError = require("../lib/Errors").DataError;

var fs = require('fs');

var testFile1 = "test/test_file1";
var testFile2 = "test/dirCreation/test_file2";
var faulty = "test/faulty.json";
var testFile3 = "test/test_file3";
var testFile4 = "test/array_file";
describe('JsonDB', function () {
    describe('Exception/Error', function () {
        it('should create create a DataError', function () {
            var error = new DataError("Test", 5);
            expect(error).to.have.property("message", "Test");
            expect(error).to.have.property("id", 5);
            expect(error).to.have.property("inner");
            expect(error.toString()).to.eql("DataError: Test");
        })

        it('should create create a DatabaseError', function () {
            var nested = new Error("don't work");
            var error = new DatabaseError("Test", 5, nested);
            expect(error).to.have.property("message", "Test");
            expect(error).to.have.property("id", 5);
            expect(error).to.have.property("inner", nested);
            expect(error.toString()).to.eql("DatabaseError: Test:\nError: don't work");
        })

    });
    describe('Initialisation', function () {
        var db = new JsonDB(testFile1, true, true);

        it('should create the JSON File', function (done) {
            fs.exists(testFile1 + ".json", function (exists) {
                expect(exists).to.be.ok();
                done();
            });

        })

        it('should set en empty root', function () {
            expect(JSON.stringify(db.getData("/"))).to.eql("{}");
        })

        it('should return a DatabaseError when loading faulty file', function () {
            db = new JsonDB(faulty, true);
            expect(function (args) {
                db.getData(args);
            }).withArgs("/").to.throwException(function (e) {
                    expect(e).to.be.a(DatabaseError);
                });

        })
        it('should return a DatabaseError when saving without successful loading.', function () {
            expect(db.save).to.throwException(function (e) {
                expect(e).to.be.a(DatabaseError);
            });
        })

    })
    describe('Data Management', function () {

        var db = new JsonDB(testFile2, true);

        it('should store the data at the root', function () {
            var object = {test: {test: "test"}};
            db.push("/", object);
            expect(db.getData("/")).to.be(object);
        })
        it('should override the data at the root', function () {
            var object = {test: "test"};
            db.push("/", object);
            expect(db.getData("/")).to.be(object);
        })
        it('should merge the data at the root', function () {
            var object = {test: {test: ['Okay']}};
            db.push("/", object);
            var data = db.getData("/");
            expect(data).to.be(object);
            object = {test: {test: ['Perfect'], okay: "test"}}
            db.push("/", object, false);
            expect(JSON.stringify(db.getData("/"))).to.eql('{\"test\":{\"test\":[\"Okay\",\"Perfect\"],\"okay\":\"test\"}}');
        })
        it('should return right data for datapath', function () {
            db = new JsonDB(testFile2, true);
            expect(JSON.stringify(db.getData("/test"))).to.eql('{\"test\":[\"Okay\",\"Perfect\"],\"okay\":\"test\"}');
        })

        it('should override only the data at datapath', function () {
            var object = ['overriden'];
            db.push("/test/test", object);
            expect(db.getData("/test/test")).to.be(object);
        })
        it('should merge the data at datapath', function () {
            var object = ['test2'];
            db.push("/test/test", object, false);
            expect(JSON.stringify(db.getData("/test/test"))).to.eql('[\"overriden\",\"test2\"]');
        })

        it('should create the tree to reach datapath', function () {
            var object = ['test2'];
            db.push("/my/tree/is/awesome", object, false);
            expect(JSON.stringify(db.getData("/my/tree/is/awesome"))).to.eql('[\"test2\"]');
        })
        it('should throw an Error when merging Object with Array', function () {
            expect(function (path, data, override) {
                db.push(path, data, override);
            }).withArgs("/test/test", {myTest: "test"}, false).to.throwException(function (e) {
                    expect(e).to.be.a(DataError);
                });
        })

        it('should throw an Error when merging Array with Object', function () {
            expect(function (path, data, override) {
                db.push(path, data, override);
            }).withArgs("/test", ['test'], false).to.throwException(function (e) {
                    expect(e).to.be.a(DataError);
                });
        })

        it('should throw an Error when asking for empty datapath', function () {
            expect(function (args) {
                db.getData(args);
            }).withArgs("").to.throwException(function (e) {
                    expect(e).to.be.a(DataError);
                });

        })

        it('should delete the data', function () {
            db.delete("/test/test");
            expect(function (args) {
                db.getData(args);
            }).withArgs("/test/test").to.throwException(function (e) {
                    expect(e).to.be.a(DataError);
                });

        })

        it('should reload the file', function () {
            var data = JSON.stringify({test: "Okay", perfect: 1});
            fs.writeFileSync(testFile2 + ".json", data, 'utf8');
            db.reload();
            expect(db.getData("/test")).to.be("Okay");
            expect(db.getData("/perfect")).to.be(1);
        })
    });

    describe('Human Readable', function () {
        var db = new JsonDB(testFile3, true, true);
        it('should save the data in an human readable format', function (done) {
            var object = {test: {readable: "test"}};
            db.push("/", object);
            fs.readFile(testFile3 + ".json", "utf8", function (err, data) {
                if (err) {
                    done(err);
                    return;
                }
                expect(data).to.be(JSON.stringify(object, null, 4));
                done();
            });
        })

    });
    describe('Array Support', function () {
        var db = new JsonDB(testFile4, true);
        it('should create an array with a string at index 0', function () {
            db.push('/arraytest/myarray[0]', "test", true);
            var myarray = db.getData('/arraytest/myarray');
            expect(myarray).to.be.an('array');
            expect(myarray[0]).to.be('test');
        });
        it('should add an object at index 1', function () {
            var obj = {property: "perfect"};
            db.push('/arraytest/myarray[1]', obj, true);
            var myarray = db.getData('/arraytest/myarray');
            expect(myarray).to.be.an('array');
            expect(myarray[1]).to.be(obj);
        });

        it('should create a nested array with an object at index 0', function () {
            var data = {test: "works"};
            db.push('/arraytest/nested[0]/obj', data, true);
            var obj = db.getData('/arraytest/nested[0]');
            expect(obj).to.be.an('object');
            expect(obj).to.have.property('obj', data);
        });

        it('should access the object at index 1', function () {
            var obj = db.getData('/arraytest/myarray[1]');
            expect(obj).to.be.an('object');
            expect(obj).to.have.property('property', 'perfect');

        });
        it('should access the object property at index 1', function () {
            var property = db.getData('/arraytest/myarray[1]/property');
            expect(property).to.be.a('string');
            expect(property).to.be('perfect');
        });

        it('should throw an error when accessing non-present index', function () {
            var obj = {property: "perfect"};
            db.push('/arraytest/arrayTesting[0]', obj, true);
            expect(function (args) {
                db.getData(args);
            }).withArgs("/arraytest/arrayTesting[1]").to.throwException(function (e) {
                    expect(e).to.be.a(DataError);
                    expect(e).to.have.property('id', 10);
                });
        });

        it('should delete the object at index 1', function () {
            db.delete('/arraytest/myarray[1]');
            expect(function (args) {
                db.getData(args);
            }).withArgs("/arraytest/myarray[1]").to.throwException(function (e) {
                    expect(e).to.be.a(DataError);
                    expect(e).to.have.property('id', 10);
                });
        });

        it('should throw an error when deleting non-present index', function () {
            expect(function (args) {
                db.delete(args);
            }).withArgs("/arraytest/myarray[10]").to.throwException(function (e) {
                    expect(e).to.be.a(DataError);
                    expect(e).to.have.property('id', 10);
                });
        });

        it('should throw an error when trying to set an object as an array', function () {
            db.push('/arraytest/fakearray', {fake: "fake"}, true);
            expect(function (args) {
                db.push(args, {test: 'test'}, true);
            }).withArgs("/arraytest/fakearray[1]").to.throwException(function (e) {
                    expect(e).to.be.a(DataError);
                    expect(e).to.have.property('id', 11);
                });
        });

        it('should throw an error when trying to access an object as an array', function () {
            db.push('/arraytest/fakearray', {fake: "fake"}, true);
            expect(function (args) {
                db.getData(args);
            }).withArgs("/arraytest/fakearray[1]").to.throwException(function (e) {
                    expect(e).to.be.a(DataError);
                    expect(e).to.have.property('id', 11);
                });
        });
        it('should throw an error when trying to set an object as an array (2)', function () {
            db.push('/arraytest/fakearray', {fake: "fake"}, true);
            expect(function (args) {
                db.push(args, {test: 'test'}, true);
            }).withArgs("/arraytest/fakearray[1]/fake").to.throwException(function (e) {
                    expect(e).to.be.a(DataError);
                    expect(e).to.have.property('id', 11);
                });
        });

    });
    describe('Cleanup', function () {
        it('should remove the test files', function () {
            fs.unlinkSync(testFile1 + ".json");
            fs.unlinkSync(testFile2 + ".json");
            fs.unlinkSync(testFile3 + ".json");
            fs.unlinkSync(testFile4 + ".json");
            fs.rmdirSync("test/dirCreation");
        });
    });

});<|endoftext|>


<commit_before>var demand = require('must');
var wm = require('..');

function describeNodes(node) {

  it("should be frozen", function() {
    var a = node();
    demand(Object.isFrozen(a)).be.truthy();
  });

  it("should be linked symmetrically", function() {
    var a = node(), b = node();
    a.set(b, 'x');
    demand(a.has(b)).be.true();
    demand(b.has(a)).be.true();
    demand(a.get(b)).equal('x');
    demand(b.get(a)).equal('x');
  });

  it("should be unlinked symmetrically", function() {
    var a = node(), b = node();
    a.set(b, 'x');
    b.remove(a);
    demand(a.has(b)).be.false();
    demand(b.has(a)).be.false();
  });

  describe(".set()", function() {

    it("should throw when called with a non-node", function() {
      var a = node();
      demand(function() { a.set({}); }).to.throw(/non-node/i);
    });

    it("should return true if there's a change", function() {
      var a = node(), b = node();
      demand(a.set(b)).be.true();
      demand(a.set(b, 'x')).be.true();
      demand(a.set(b)).be.true();
    });

    it("should return false otherwise", function() {
      var a = node(), b = node();
      a.set(b);
      demand(a.set(b)).be.false();
      a.set(b, 'x');
      demand(a.set(b, 'x')).be.false();
    });

  });

  describe(".remove()", function() {

    it("should return true if there's a change", function() {
      var a = node(), b = node();
      a.set(b);
      demand(a.remove(b)).be.true();
      a.set(b, 'x');
      demand(a.remove(b)).be.true();
    });

    it("should return false otherwise", function() {
      var a = node(), b = node();
      demand(a.remove(b)).be.false();
      a.set(b, 'x');
      a.remove(b);
      demand(a.remove(b)).be.false();
    });

  });

  describe(".has()", function() {

    it("should return true if the nodes are linked", function() {
      var a = node(), b = node();
      a.set(b);
      demand(a.has(b)).be.true();
    });

    it("should return false otherwise", function() {
      var a = node(), b = node();
      demand(a.has(b)).be.false();
      a.set(b);
      a.remove(b);
      demand(a.has(b)).be.false();
    });

  });

  describe(".get()", function() {

    it("should return the nodes' link value", function() {
      var a = node(), b = node();
      a.set(b, 'x');
      demand(a.get(b)).equal('x');
    });

    it("should return undefined if the nodes aren't linked", function() {
      var a = node(), b = node();
      demand(a.get(b)).be.undefined();
      a.set(b, 'x');
      a.remove(b);
      demand(a.get(b)).be.undefined();
    });

    it("should return undefined if the nodes' link value is undefined", function() {
      var a = node(), b = node();
      a.set(b);
      demand(a.get(b)).be.undefined();
    });

  });

  describe(".getNodes()", function() {

    it("should return an array of linked nodes", function() {
      var a = node(), b = node(), c = node();
      demand(a.getNodes()).be.empty();
      a.set(b);
      demand(a.getNodes()).eql([b]);
      a.set(c);
      demand(a.getNodes()).have.length(2);
      demand(a.getNodes()).include(b);
      demand(a.getNodes()).include(c);
      a.remove(b);
      demand(a.getNodes()).eql([c]);
      a.remove(c);
      demand(a.getNodes()).be.empty();
    });

    it("should return a new array on each invocation by default", function() {
      var a = node(), b = node();
      demand(a.getNodes()).not.equal(a.getNodes());
      a.set(b);
      demand(a.getNodes()).not.equal(a.getNodes());
    });

    it("should return a new array on each invocation when passed a truthy value", function() {
      var a = node(), b = node();
      demand(a.getNodes(false)).not.equal(a.getNodes(1));
      a.set(b);
      demand(a.getNodes(false)).not.equal(a.getNodes(true));
    });

    // there's no test for the inverse because that behavior is undefined.

  });

  describe(".name", function() {

    it("should be equal to the passed-in name", function() {
      var a = node('a'), b = node('b');
      demand(a.name).equal('a');
      demand(b.name).equal('b');
    });

    it("should be undefined if no name is given", function() {
      var a = node();
      demand(a.name).be.undefined();
    });

  });

  describe(".nodes", function() {

    it("should be an array of linked nodes", function() {
      var a = node(), b = node(), c = node();
      demand(a.nodes).be.empty();
      a.set(b);
      demand(a.nodes).eql([b]);
      a.set(c);
      demand(a.nodes).have.length(2);
      demand(a.nodes).include(b);
      demand(a.nodes).include(c);
      a.remove(b);
      demand(a.nodes).eql([c]);
      a.remove(c);
      demand(a.nodes).be.empty();
    });

  });

}

describe("Nodes", function() {

  describeNodes(wm.node);

});

describe("Supernodes", function() {

  describeNodes(wm.supernode);

});
<commit_msg>Added some more tests<commit_after>var demand = require('must');
var wm = require('..');

function describeNodes(node) {

  it("should be frozen", function() {
    var a = node();
    demand(Object.isFrozen(a)).be.truthy();
  });

  it("should be linked symmetrically", function() {
    var a = node(), b = node();
    a.set(b, 'x');
    demand(a.has(b)).be.true();
    demand(b.has(a)).be.true();
    demand(a.get(b)).equal('x');
    demand(b.get(a)).equal('x');
  });

  it("should be unlinked symmetrically", function() {
    var a = node(), b = node();
    a.set(b, 'x');
    b.remove(a);
    demand(a.has(b)).be.false();
    demand(b.has(a)).be.false();
  });

  it("should be allowed to link to itself", function() {
    var a = node();
    demand(a.set(a)).be.true();
    demand(a.has(a)).be.true();
    demand(a.set(a, 'x')).be.true();
    demand(a.get(a)).equal('x');
    demand(a.remove(a)).be.true();
    demand(a.has(a)).be.false();
  });

  describe(".set()", function() {

    it("should throw when called with a non-node", function() {
      var a = node();
      demand(function() { a.set({}); }).to.throw(/non-node/i);
    });

    it("should return true if there's a change", function() {
      var a = node(), b = node();
      demand(a.set(b)).be.true();
      demand(a.set(b, 'x')).be.true();
      demand(a.set(b)).be.true();
    });

    it("should return false otherwise", function() {
      var a = node(), b = node();
      a.set(b);
      demand(a.set(b)).be.false();
      a.set(b, 'x');
      demand(a.set(b, 'x')).be.false();
    });

  });

  describe(".remove()", function() {

    it("should return true if there's a change", function() {
      var a = node(), b = node();
      a.set(b);
      demand(a.remove(b)).be.true();
      a.set(b, 'x');
      demand(a.remove(b)).be.true();
    });

    it("should return false otherwise", function() {
      var a = node(), b = node();
      demand(a.remove(b)).be.false();
      a.set(b, 'x');
      a.remove(b);
      demand(a.remove(b)).be.false();
    });

  });

  describe(".has()", function() {

    it("should return true if the nodes are linked", function() {
      var a = node(), b = node();
      a.set(b);
      demand(a.has(b)).be.true();
    });

    it("should return false otherwise", function() {
      var a = node(), b = node();
      demand(a.has(b)).be.false();
      a.set(b);
      a.remove(b);
      demand(a.has(b)).be.false();
    });

  });

  describe(".get()", function() {

    it("should return the nodes' link value", function() {
      var a = node(), b = node();
      a.set(b, 'x');
      demand(a.get(b)).equal('x');
    });

    it("should return undefined if the nodes aren't linked", function() {
      var a = node(), b = node();
      demand(a.get(b)).be.undefined();
      a.set(b, 'x');
      a.remove(b);
      demand(a.get(b)).be.undefined();
    });

    it("should return undefined if the nodes' link value is undefined", function() {
      var a = node(), b = node();
      a.set(b);
      demand(a.get(b)).be.undefined();
    });

  });

  describe(".getNodes()", function() {

    it("should return an array of linked nodes", function() {
      var a = node(), b = node(), c = node();
      demand(a.getNodes()).be.empty();
      a.set(b);
      demand(a.getNodes()).eql([b]);
      a.set(c);
      demand(a.getNodes()).have.length(2);
      demand(a.getNodes()).include(b);
      demand(a.getNodes()).include(c);
      a.remove(b);
      demand(a.getNodes()).eql([c]);
      a.remove(c);
      demand(a.getNodes()).be.empty();
    });

    it("should return a new array on each invocation by default", function() {
      var a = node(), b = node();
      demand(a.getNodes()).not.equal(a.getNodes());
      a.set(b);
      demand(a.getNodes()).not.equal(a.getNodes());
    });

    it("should return a new array on each invocation when passed a truthy value", function() {
      var a = node(), b = node();
      demand(a.getNodes(false)).not.equal(a.getNodes(1));
      a.set(b);
      demand(a.getNodes(false)).not.equal(a.getNodes(true));
    });

    // there's no test for the inverse because that behavior is undefined.

  });

  describe(".name", function() {

    it("should be equal to the passed-in name", function() {
      var a = node('a'), b = node('b');
      demand(a.name).equal('a');
      demand(b.name).equal('b');
    });

    it("should be undefined if no name is given", function() {
      var a = node();
      demand(a.name).be.undefined();
    });

  });

  describe(".nodes", function() {

    it("should be an array of linked nodes", function() {
      var a = node(), b = node(), c = node();
      demand(a.nodes).be.empty();
      a.set(b);
      demand(a.nodes).eql([b]);
      a.set(c);
      demand(a.nodes).have.length(2);
      demand(a.nodes).include(b);
      demand(a.nodes).include(c);
      a.remove(b);
      demand(a.nodes).eql([c]);
      a.remove(c);
      demand(a.nodes).be.empty();
    });

  });

}

describe("Nodes", function() {

  describeNodes(wm.node);

});

describe("Supernodes", function() {

  describeNodes(wm.supernode);

  describe(".on()", function() {

    it("should allow listening for 'add'", function() {
      var x = wm.supernode(), called;
      x.on('add', function() {
        called = true;
      });
      x.set(x);
      demand(called).be.true();
    });

    it("should allow listening for 'update'", function() {
      var x = wm.supernode(), called;
      x.on('update', function() {
        called = true;
      });
      x.set(x);
      x.set(x, 'x');
      demand(called).be.true();
    });

    it("should allow listening for 'remove'", function() {
      var x = wm.supernode(), called;
      x.on('remove', function() {
        called = true;
      });
      x.set(x);
      x.remove(x);
      demand(called).be.true();
    });

    it("should not notify 'update' when a node is first linked", function() {
      var x = wm.supernode(), called;
      x.on('update', function() {
        called = true;
      });
      x.set(x, 'x');
      demand(called).be.undefined();
    });

    it("should not notify 'add' when a node is updated", function() {
      var x = wm.supernode(), called;
      x.set(x);
      x.on('add', function() {
        called = true;
      });
      x.set(x, 'x');
      demand(called).be.undefined();
    });

    it("should not notify 'add' and not 'update' when a node is re-added", function() {
      var x = wm.supernode(), added, updated;
      x.set(x);
      x.remove(x);
      x.on('add', function() {
        added = true;
      });
      x.on('update', function() {
        added = true;
      });
      x.set(x, 'x');
      demand(added).be.true();
      demand(updated).be.undefined();
    });

    it("should accept multiple alert types", function() {
      var x = wm.supernode('x'), a = wm.node('a'), calls = 0;
      x.on('add', 'remove', function() {
        ++calls;
      });
      demand(calls).equal(0);
      x.set(a);
      demand(calls).equal(1);
      x.set(a, 'x');
      demand(calls).equal(1);
      x.remove(a);
      demand(calls).equal(2);
    });

  });

});
<|endoftext|>


<commit_before>describe('Array', function(){
  describe('#indexOf()', function(){
    it('should return -1 when the value is not present', function(){
      array = [1, 2, 3];
      expect(array.indexOf(5)).to.equal(-1);
      expect(array.indexOf(0)).to.equal(-1);
    });
  });
});

// font size * line height + top/bottom padding + top/bottom border
// (16 * 1.4) + (6 * 2) + 2

function getLineHeight(textarea) {
  return parseInt(textarea.css('line-height'));
}

function spacingHeight(textarea) {
  return parseInt(textarea.css('paddingBottom')) +
    parseInt(textarea.css('paddingTop')) +
    parseInt(textarea.css('borderBottomWidth')) +
    parseInt(textarea.css('borderTopWidth'));
}

describe("DOM Tests", function () {
  var el, myEl;

  before(function(){
    el = document.createElement("div");
    el.id = "myDiv";
    el.innerHTML = "Hi there!";
    el.style.background = "#ccc";
    document.body.appendChild(el);

    myEl = document.getElementById('myDiv');
  });

  it('has a rendered height of one line with no text', function() {
    var textarea = $("#js-single-line-textarea").textareaAutoSize();

    expect(textarea.val()).to.equal('');
    expect(textarea.outerHeight()).to.equal(36);
  });

  it('has a rendered height of 2 lines when large enough text entered', function() {
    var textarea = $("#js-single-line-textarea").textareaAutoSize();
    textarea.val('this is a test with a really long entry').trigger('input');

    expect(textarea.outerHeight()).to.equal(58);
  });

  it('resizes to one line when deleting all text', function() {
    var textarea = $("#js-single-line-textarea").textareaAutoSize();
    textarea.val('').trigger('input');

    expect(textarea.outerHeight()).to.equal(36);
    expect(textarea.val()).to.equal('');
  });

  it("is in the DOM", function () {
    expect(myEl).to.not.equal(null);
  });

  it("is a child of the body", function () {
    expect(myEl.parentElement).to.equal(document.body);
  });

  it("has the right text", function () {
    expect(myEl.innerHTML).to.equal("Hi there!");
  });

  it("has the right background", function () {
    expect(myEl.style.background).to.equal("rgb(204, 204, 204)");
  });
});
<commit_msg>Remove unrelated tests now that suite is working<commit_after>// font size * line height + top/bottom padding + top/bottom border
// (16 * 1.4) + (6 * 2) + 2

function getLineHeight(textarea) {
  return parseInt(textarea.css('line-height'));
}

function spacingHeight(textarea) {
  return parseInt(textarea.css('paddingBottom')) +
    parseInt(textarea.css('paddingTop')) +
    parseInt(textarea.css('borderBottomWidth')) +
    parseInt(textarea.css('borderTopWidth'));
}

describe("TextArea", function () {
  var textarea;

  before(function(){
    textarea = $("#js-single-line-textarea").textareaAutoSize();
  });

  it('has a rendered height of one line with no text', function() {
    expect(textarea.val()).to.equal('');
    expect(textarea.outerHeight()).to.equal(36);
  });

  it('has a rendered height of 2 lines when large enough text entered', function() {
    textarea.val('this is a test with a really long entry').trigger('input');

    expect(textarea.outerHeight()).to.equal(58);
  });

  it('resizes to one line when deleting all text', function() {
    textarea.val('').trigger('input');

    expect(textarea.outerHeight()).to.equal(36);
    expect(textarea.val()).to.equal('');
  });
});
<|endoftext|>


<commit_before>'use strict';

// Assertion Library Docs:  https://github.com/hapijs/code
// Testing framework Docs:  https://github.com/hapijs/lab

exports.lab = require('./helpers/test-helper').lab;
var describe = require('./helpers/test-helper').describe;
var it = require('./helpers/test-helper').it;
var expect = require('./helpers/test-helper').expect;

var gulp = require('gulp');
var PluginError = require('gulp-util').PluginError;
var task = require('../');
var through = require('through2');
var path = require('path');
var fs = require('fs');
var objectAssign = require('object-assign');
var handlbarsTemplateCompiler = require('ember-template-compiler');

var Vinyl = require('vinyl');
var Readable = require('stream').Readable;

// Local Tests depends on `bower install ember`, so it could retrieve
// `ember-template-compiler.js` from the ember release bundle
var htmlBarsCompiler = require('../bower_components/ember/ember-template-compiler');

var filename = path.join(__dirname, './fixtures/template.hbs');
var componentFilename = path.join(__dirname, './fixtures/component-template.hbs');

function expectStream (options, done) {
  options = objectAssign({}, options);
  var wrapper;
  var compiler;

  if (options.isHTMLBars) {
    wrapper = 'export default Ember.HTMLBars.template(';
    // Compile handlebars template via Bundled compiler which comes with
    // each release of Ember core version (beta or stable)
    compiler = options.templateCompiler.precompile;
  } else {
    wrapper = 'export default Ember.Handlebars.template(';
    // Compile handlebars template via default `require('ember-template-compiler')`
    compiler = handlbarsTemplateCompiler.precompile;
  }

  return through.obj(function (file, enc, cb) {
    options.contents = fs.readFileSync(file.path, 'utf-8');
    var results = String(file.contents);
    var originalContent = (options.filepath) ?
      fs.readFileSync(options.filepath) :
      fs.readFileSync(filename);
    var expected = wrapper + compiler(String(originalContent), false) + ');';
    expect(results).to.deep.equal(expected);
    done();
    cb();
  });
}

function stringStream () {
  var stream = new Readable();

  stream._read = function () {
    this.push('mattma');
    this.push(null);
  };

  return stream;
}

describe('gulp-htmlbars', function () {
  // By default, isHTMLBars is false
  describe('htmlbars', function () {
    it('precompiles templates into htmlbars', function (done) {
      var opts = {
        isHTMLBars:       true,
        templateCompiler: htmlBarsCompiler
      };
      gulp.src(filename)
        .pipe(task(opts))
        .pipe(expectStream(opts, done));
    });

    it('precompiles component based template into htmlbars', function (done) {
      var opts = {
        isHTMLBars:       true,
        templateCompiler: htmlBarsCompiler,
        // this is convenient property ONLY for testing purpose
        filepath:         componentFilename
      };
      gulp.src(componentFilename)
        .pipe(task(opts))
        .pipe(expectStream(opts, done));
    });
  });

  describe('handlebars', function () {
    it('precompiles templates into handlebars', function (done) {
      var opts = {
        isHTMLBars: false
      };
      gulp.src(filename)
        .pipe(task(opts))
        .pipe(expectStream(opts, done));
    });

    it('precompiles component based template into handlebars', function (done) {
      var opts = {
        isHTMLBars: false,
        // this is convenient property ONLY for testing purpose
        filepath:   componentFilename
      };
      gulp.src(componentFilename)
        .pipe(task(opts))
        .pipe(expectStream(opts, done));
    });
  });

  describe('error', function () {
    var testNull = new Vinyl({
      cwd:      "/home/mattma/broken-promises/",
      base:     "/home/mattma/broken-promises/test",
      path:     "/home/mattma/broken-promises/test/test1.hbs",
      contents: null
    });

    var testStream = new Vinyl({
      cwd:      "/home/mattma/broken-promises/",
      base:     "/home/mattma/broken-promises/test",
      path:     "/home/mattma/broken-promises/test/test1.js",
      contents: stringStream()
    });

    var testError = new Vinyl({
      cwd:      "/home/mattma/broken-promises/",
      base:     "/home/mattma/broken-promises/test",
      path:     "/home/mattma/broken-promises/test/testError1.js",
      contents: new Buffer("<div> {invalidBracket} </div>")
    });

    function NoOps () { }
    NoOps.prototype.precompile = function() { };

    it('test null case when file.isNull() is true', function (done) {
      var stream = task();

      stream.on('data', function (newFile) {
        expect(newFile).to.be.exist();          // 'emits a file'
        expect(newFile.path).to.be.exist();     // 'file has a path'
        expect(newFile.relative).to.be.exist(); // 'file has relative path information'
        expect(newFile.contents).to.not.be.exist(); // 'file does not have contents'
        expect(newFile).to.be.an.instanceof(Vinyl); // 'file is Vinyl'

        expect(newFile.contents).to.be.null();
        done();
      });

      stream.write(testNull);
      stream.end();
    });

    it('test stream case when file.isStream() is true', function (done) {
      var stream = task();

      stream.on('error', function (e) {
        expect(e).to.be.an.instanceof(PluginError); // 'error is a PluginError'
        expect(e.plugin).to.equal('gulp-htmlbars'); // 'error is from gulp-htmlbars'
        expect(e.fileName).to.equal(testStream.path); // 'error reports the correct file name'
        expect(e.message).to.equal('Streaming not supported'); // 'error reports the correct file'
        expect(e.showStack).to.be.false(); // 'error is configured to not print stack'
        expect(e.showProperties).to.be.true(); // 'error is configured to show showProperties'
        done();
      });

      stream.write(testStream);
      stream.end();
    });

    it('test buffer(pass through) case and should report files in error', function (done) {
      var noOps = new NoOps();
      var stream = task({
        isHTMLBars:       true,
        // `templateCompiler` is a no-op, it does not have `precompile` method
        templateCompiler: noOps.precompile
      });

      stream.on('error', function (e) {
        expect(e).to.be.an.instanceof(Error); // 'argument should be of type error'
        expect(e.plugin).to.equal('gulp-htmlbars'); // 'error is from gulp-htmlbars'
        expect(e.fileName).to.equal(testError.path); // 'error reports the correct file name'
        expect(e.name).to.equal('TypeError');
        expect(e.message).to.equal('undefined is not a function');
        expect(e.stack).to.be.exist();     // 'error reports the correct file'
        expect(e.showStack).to.be.false(); // 'error is configured to not print stack'
        expect(e.showProperties).to.be.true(); // 'error is configured to show showProperties'
        done();
      });

      stream.write(testError);
      stream.end();
    });
  });
});
<commit_msg>send up the function call<commit_after>'use strict';

// Assertion Library Docs:  https://github.com/hapijs/code
// Testing framework Docs:  https://github.com/hapijs/lab

exports.lab = require('./helpers/test-helper').lab;
var describe = require('./helpers/test-helper').describe;
var it = require('./helpers/test-helper').it;
var expect = require('./helpers/test-helper').expect;

var gulp = require('gulp');
var PluginError = require('gulp-util').PluginError;
var task = require('../');
var through = require('through2');
var path = require('path');
var fs = require('fs');
var objectAssign = require('object-assign');
var handlbarsTemplateCompiler = require('ember-template-compiler');

var Vinyl = require('vinyl');
var Readable = require('stream').Readable;

// Local Tests depends on `bower install ember`, so it could retrieve
// `ember-template-compiler.js` from the ember release bundle
var htmlBarsCompiler = require('../bower_components/ember/ember-template-compiler');

var filename = path.join(__dirname, './fixtures/template.hbs');
var componentFilename = path.join(__dirname, './fixtures/component-template.hbs');

function expectStream (options, done) {
  options = objectAssign({}, options);
  var wrapper;
  var compiler;

  if (options.isHTMLBars) {
    wrapper = 'export default Ember.HTMLBars.template(';
    // Compile handlebars template via Bundled compiler which comes with
    // each release of Ember core version (beta or stable)
    compiler = options.templateCompiler.precompile;
  } else {
    wrapper = 'export default Ember.Handlebars.template(';
    // Compile handlebars template via default `require('ember-template-compiler')`
    compiler = handlbarsTemplateCompiler.precompile;
  }

  return through.obj(function (file, enc, cb) {
    options.contents = fs.readFileSync(file.path, 'utf-8');
    var results = String(file.contents);
    var originalContent = (options.filepath) ?
      fs.readFileSync(options.filepath) :
      fs.readFileSync(filename);
    var expected = wrapper + compiler(String(originalContent), false) + ');';
    expect(results).to.deep.equal(expected);
    done();
    cb();
  });
}

function stringStream () {
  var stream = new Readable();

  stream._read = function () {
    this.push('mattma');
    this.push(null);
  };

  return stream;
}

describe('gulp-htmlbars', function () {
  // By default, isHTMLBars is false
  describe('htmlbars', function () {
    it('precompiles templates into htmlbars', function (done) {
      var opts = {
        isHTMLBars:       true,
        templateCompiler: htmlBarsCompiler
      };
      gulp.src(filename)
        .pipe(task(opts))
        .pipe(expectStream(opts, done));
    });

    it('precompiles component based template into htmlbars', function (done) {
      var opts = {
        isHTMLBars:       true,
        templateCompiler: htmlBarsCompiler,
        // this is convenient property ONLY for testing purpose
        filepath:         componentFilename
      };
      gulp.src(componentFilename)
        .pipe(task(opts))
        .pipe(expectStream(opts, done));
    });
  });

  describe('handlebars', function () {
    it('precompiles templates into handlebars', function (done) {
      var opts = {
        isHTMLBars: false
      };
      gulp.src(filename)
        .pipe(task(opts))
        .pipe(expectStream(opts, done));
    });

    it('precompiles component based template into handlebars', function (done) {
      var opts = {
        isHTMLBars: false,
        // this is convenient property ONLY for testing purpose
        filepath:   componentFilename
      };
      gulp.src(componentFilename)
        .pipe(task(opts))
        .pipe(expectStream(opts, done));
    });
  });

  describe('error', function () {
    var testNull = new Vinyl({
      cwd:      "/home/mattma/broken-promises/",
      base:     "/home/mattma/broken-promises/test",
      path:     "/home/mattma/broken-promises/test/test1.hbs",
      contents: null
    });

    var testStream = new Vinyl({
      cwd:      "/home/mattma/broken-promises/",
      base:     "/home/mattma/broken-promises/test",
      path:     "/home/mattma/broken-promises/test/test1.js",
      contents: stringStream()
    });

    var testError = new Vinyl({
      cwd:      "/home/mattma/broken-promises/",
      base:     "/home/mattma/broken-promises/test",
      path:     "/home/mattma/broken-promises/test/testError1.js",
      contents: new Buffer("<div> {invalidBracket} </div>")
    });

    function NoOps () { }
    NoOps.prototype.precompile = function() { };

    it('test null case when file.isNull() is true', function (done) {
      var stream = task();

      stream.on('data', function (newFile) {
        expect(newFile).to.be.exist();          // 'emits a file'
        expect(newFile.path).to.be.exist();     // 'file has a path'
        expect(newFile.relative).to.be.exist(); // 'file has relative path information'
        expect(newFile.contents).to.not.be.exist(); // 'file does not have contents'
        expect(newFile).to.be.an.instanceof(Vinyl); // 'file is Vinyl'

        expect(newFile.contents).to.be.null();
        done();
      });

      stream.write(testNull);
      stream.end();
    });

    it('test stream case when file.isStream() is true', function (done) {
      var stream = task();

      stream.on('error', function (e) {
        expect(e).to.be.an.instanceof(PluginError); // 'error is a PluginError'
        expect(e.plugin).to.equal('gulp-htmlbars'); // 'error is from gulp-htmlbars'
        expect(e.fileName).to.equal(testStream.path); // 'error reports the correct file name'
        expect(e.message).to.equal('Streaming not supported'); // 'error reports the correct file'
        expect(e.showStack).to.be.false(); // 'error is configured to not print stack'
        expect(e.showProperties).to.be.true(); // 'error is configured to show showProperties'
        done();
      });

      stream.write(testStream);
      stream.end();
    });

    it('test buffer(pass through) case and should report files in error', function (done) {
      var noOps = new NoOps();
      console.log('typeof noOps.precompile: ', typeof noOps.precompile);
      var stream = task({
        isHTMLBars:       true,
        // `templateCompiler` is a no-op, it does not have `precompile` method
        templateCompiler: noOps.precompile
      });

      stream.on('error', function (e) {
        expect(e).to.be.an.instanceof(Error); // 'argument should be of type error'
        expect(e.plugin).to.equal('gulp-htmlbars'); // 'error is from gulp-htmlbars'
        expect(e.fileName).to.equal(testError.path); // 'error reports the correct file name'
        expect(e.name).to.equal('TypeError');
        expect(e.message).to.equal('undefined is not a function');
        expect(e.stack).to.be.exist();     // 'error reports the correct file'
        expect(e.showStack).to.be.false(); // 'error is configured to not print stack'
        expect(e.showProperties).to.be.true(); // 'error is configured to show showProperties'
        done();
      });

      stream.write(testError);
      stream.end();
    });
  });
});
<|endoftext|>


<commit_before>'use strict';

let pregex = require('../lib/regex.js');

exports['pregex:match'] = function(test) {
	test.expect(13);

	// match 1
	test.equal(pregex.match('Hello World !!!', /\w+ \w+ !{3}/), true);
	test.equal(pregex.match('Hello World !!!', /^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$/), false);
	test.equal(pregex.match('Hello World !!!', '\\w+ \\w+ !{3}'), true);
	test.equal(pregex.match('Hello World !!!', '^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$'), false);

	// match 2
	test.equal(pregex.match('test@example.com', /\w+ \w+ !{3}/), false);
	test.equal(pregex.match('test@example.com', /^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$/), true);
	test.equal(pregex.match('test@example.com', '\\w+ \\w+ !{3}'), false);
	test.equal(pregex.match('test@example.com', '^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$'), true);

	// match 3
	let multiLines=`Multi
		foo
		bar`;
	test.equal(pregex.match(multiLines, '[a-zA-Z]*?\\n(.*)', 'i'), true);

	// options
	test.equal(pregex.match('HellohelloHELLO', /(?:hello){3}/i), true);
	test.equal(pregex.match('HellohelloHELLO', '(?:hello){3}', 'i'), true);

	// error handling
	test.equal(pregex.match('test', '(test'), false);
	test.equal(pregex.match('test', 'test', 'e'), false);

	test.done();
};

exports['pregex:exec'] = function(test) {
	test.expect(18);

	// exec 1
	test.deepEqual(pregex.exec('Hello World !!!', /\d+/), null);
	test.deepEqual(pregex.exec('Hello World !!!', /\w+/), ['Hello']);
	test.deepEqual(pregex.exec('Hello World !!!', /\w+ (\w+)/), ['Hello World', 'World']);
	test.deepEqual(pregex.exec('Hello World !!!', '\\d+'), null);
	test.deepEqual(pregex.exec('Hello World !!!', '\\w+'), ['Hello']);
	test.deepEqual(pregex.exec('Hello World !!!', '\\w+ (\\w+)'), ['Hello World', 'World']);

	// exec 2
	test.deepEqual(pregex.exec('My email is testexample.com ^_^', /[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+/), null);
	test.deepEqual(pregex.exec('My email is test@example.com ^_^', /[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+/), ['test@example.com']);
	test.deepEqual(pregex.exec('My email is test@example.com ^_^', /([a-zA-Z0-9_.+-]+)@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+/), ['test@example.com', 'test']);
	test.deepEqual(pregex.exec('My email is testexample.com ^_^', '[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+'), null);
	test.deepEqual(pregex.exec('My email is test@example.com ^_^', '[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+'), ['test@example.com']);
	test.deepEqual(pregex.exec('My email is test@example.com ^_^', '([a-zA-Z0-9_.+-]+)@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+'), ['test@example.com', 'test']);

	// match 3
	let multiLines=`Multi
		foo
		bar`;
	test.deepEqual(pregex.exec(multiLines, '[a-zA-Z]*?\\n(.*)', 'i'), ["Multi\n\t\tfoo\n\t\tbar", "\t\tfoo\n\t\tbar"]);

	// options 1
	test.deepEqual(pregex.exec('Hello World !!!', /\w+/g), ['World', 'Hello', 'World']);
	test.deepEqual(pregex.exec('Hello World !!!', '\\w+', 'g'), ['World', 'Hello', 'World']);

	// options 2
	test.deepEqual(pregex.exec("tag list:\n\tabc\n\tdef", '^tag[^\\n]*\\n(.*)', 'ms'), ["tag list:\n\tabc\n\tdef", "\tabc\n\tdef"]);

	// error handling
	test.equal(pregex.exec('test', '(test'), null);
	test.equal(pregex.exec('test', 'test', 'e'), null);

	test.done();
};
<commit_msg>- Add js regex test cases<commit_after>'use strict';

let pregex = require('../lib/regex.js');

exports['pregex:match'] = function(test) {
	test.expect(22);

	// match 1
	test.equal(pregex.match('Hello World !!!', /\w+ \w+ !{3}/), true);
	test.equal(pregex.match('Hello World !!!', /^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$/), false);
	test.equal(pregex.match('Hello World !!!', '\\w+ \\w+ !{3}'), true);
	test.equal(pregex.match('Hello World !!!', '^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$'), false);

	// match 2
	test.equal(pregex.match('test@example.com', /\w+ \w+ !{3}/), false);
	test.equal(pregex.match('test@example.com', /^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$/), true);
	test.equal(pregex.match('test@example.com', '\\w+ \\w+ !{3}'), false);
	test.equal(pregex.match('test@example.com', '^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$'), true);

	// match 3
	let multiLines=`Multi
		foo
		bar`;
	test.equal(pregex.match(multiLines, /[a-zA-Z]*?\n(.*)/, 'i'), true);
	test.equal(pregex.match(multiLines, '[a-zA-Z]*?\\n(.*)', 'i'), true);

	// match 4
	test.equal(pregex.match('192.168.0.1', /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/), true);
	test.equal(pregex.match('127.0.0.1', /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/), true);
	test.equal(pregex.match('256.0.0.1', /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/), false);
	test.equal(pregex.match('255.0.0.y', /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/), false);
	test.equal(pregex.match('192.168.0.1', '^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'), true);
	test.equal(pregex.match('127.0.0.1', '^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'), true);
	test.equal(pregex.match('256.0.0.1', '^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'), false);
	test.equal(pregex.match('255.0.0.y', '^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'), false);

	// options
	test.equal(pregex.match('HellohelloHELLO', /(?:hello){3}/i), true);
	test.equal(pregex.match('HellohelloHELLO', '(?:hello){3}', 'i'), true);

	// error handling
	test.equal(pregex.match('test', '(test'), false);
	test.equal(pregex.match('test', 'test', 'e'), false);

	test.done();
};

exports['pregex:exec'] = function(test) {
	test.expect(27);

	// exec 1
	test.deepEqual(pregex.exec('Hello World !!!', /\d+/), null);
	test.deepEqual(pregex.exec('Hello World !!!', /\w+/), ['Hello']);
	test.deepEqual(pregex.exec('Hello World !!!', /\w+ (\w+)/), ['Hello World', 'World']);
	test.deepEqual(pregex.exec('Hello World !!!', '\\d+'), null);
	test.deepEqual(pregex.exec('Hello World !!!', '\\w+'), ['Hello']);
	test.deepEqual(pregex.exec('Hello World !!!', '\\w+ (\\w+)'), ['Hello World', 'World']);

	// exec 2
	test.deepEqual(pregex.exec('My email is testexample.com ^_^', /[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+/), null);
	test.deepEqual(pregex.exec('My email is test@example.com ^_^', /[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+/), ['test@example.com']);
	test.deepEqual(pregex.exec('My email is test@example.com ^_^', /([a-zA-Z0-9_.+-]+)@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+/), ['test@example.com', 'test']);
	test.deepEqual(pregex.exec('My email is testexample.com ^_^', '[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+'), null);
	test.deepEqual(pregex.exec('My email is test@example.com ^_^', '[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+'), ['test@example.com']);
	test.deepEqual(pregex.exec('My email is test@example.com ^_^', '([a-zA-Z0-9_.+-]+)@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+'), ['test@example.com', 'test']);

	// exec 3
	let multiLines=`Multi
		foo
		bar`;
	test.deepEqual(pregex.exec(multiLines, /[a-zA-Z]*?\n(.*)/, 'i'), ["Multi\n\t\tfoo\n\t\tbar", "\t\tfoo\n\t\tbar"]);
	test.deepEqual(pregex.exec(multiLines, '[a-zA-Z]*?\\n(.*)', 'i'), ["Multi\n\t\tfoo\n\t\tbar", "\t\tfoo\n\t\tbar"]);

	// exec 4
	test.deepEqual(pregex.exec('192.168.0.1', /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/), ['192.168.0.1', '192', '168', '0', '1']);
	test.deepEqual(pregex.exec('127.0.0.1', /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/), ['127.0.0.1', '127', '0', '0', '1']);
	test.deepEqual(pregex.exec('256.0.0.1', /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/), null);
	test.deepEqual(pregex.exec('255.0.0.y', /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/), null);
	test.deepEqual(pregex.exec('192.168.0.1', '^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'), ['192.168.0.1', '192', '168', '0', '1']);
	test.deepEqual(pregex.exec('127.0.0.1', '^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'), ['127.0.0.1', '127', '0', '0', '1']);
	test.deepEqual(pregex.exec('256.0.0.1', '^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'), null);
	test.deepEqual(pregex.exec('255.0.0.y', '^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'), null);

	// options 1
	test.deepEqual(pregex.exec('Hello World !!!', /\w+/g), ['World', 'Hello', 'World']);
	test.deepEqual(pregex.exec('Hello World !!!', '\\w+', 'g'), ['World', 'Hello', 'World']);

	// options 2
	test.deepEqual(pregex.exec("tag list:\n\tabc\n\tdef", '^tag[^\\n]*\\n(.*)', 'ms'), ["tag list:\n\tabc\n\tdef", "\tabc\n\tdef"]);

	// error handling
	test.equal(pregex.exec('test', '(test'), null);
	test.equal(pregex.exec('test', 'test', 'e'), null);

	test.done();
};
<|endoftext|>


<commit_before>// install dependencies:
// `npm install -g mocha`
// `npm install -g assert`
// start testing:
// `mocha`

var assert = require("assert");
d3 = require("d3");
_ = require("underscore");
var bd = require("../binnedData.js");
//var d3 = require("../d3/d3.js");
describe('Array', function(){
    describe('#inexOf()', function(){
        it('should return -1 when the value is not present', function(){
            assert.equal(-1, [1, 2, 3].indexOf(5));
            assert.equal(-1, [1, 2, 3].indexOf(0));
        });
        it('should return the index when the value is present', function(){
            assert.equal(0, [1, 2, 3].indexOf(1));
            assert.equal(1, [1, 2, 3].indexOf(2));
            assert.equal(2, [1, 2, 3].indexOf(3));
        });
    });
});

var d = [[{ms: 0, val: 1}, {ms: 5, val: 2}, {ms: 10, val: 4}]];
var allKeys = ['average', 'rawData', 'q1', 'q3', 'mins', 'maxes'];

describe('binnedData', function(){

    describe('write-read', function(){
        it('should return whatever is inserted', function(){
            var bd = binnedData();
            bd.addRawData(d[0]);
            assert.deepEqual(d[0], bd.getDateRange(['average'], 0, [-1000, 1000]));
        })
    })

    //NOT necessary, because getAllInRange just uses getDateRange anyway...
    //describe('write-readAll', function(){
    //    it('should return whatever is inserted, two ways', function(){
    //        console.log("asdfasdf")
    //        var bd = binnedData();
    //        bd.addRawData(d[0]);
    //        console.log( bd.getAllInRange(0, [-1000, 1000]));
    //        assert.equal(d[0], bd.getAllInRange(0, [-1000, 1000]));
    //        console.log( bd.getAllInRange(1, [-1000, 1000]).toString());
    //        assert.equal(d[0], bd.getAllInRange(1, [-1000, 1000]));

    //    })
    //})
})
<commit_msg>removed unused test example<commit_after>// install dependencies:
// `npm install -g mocha`
// `npm install -g assert`
// start testing:
// `mocha`

var assert = require("assert");
d3 = require("d3");
_ = require("underscore");
var bd = require("../binnedData.js");
//var d3 = require("../d3/d3.js");
describe('Array', function(){
    describe('#inexOf()', function(){
        it('should return -1 when the value is not present', function(){
            assert.equal(-1, [1, 2, 3].indexOf(5));
            assert.equal(-1, [1, 2, 3].indexOf(0));
        });
        it('should return the index when the value is present', function(){
            assert.equal(0, [1, 2, 3].indexOf(1));
            assert.equal(1, [1, 2, 3].indexOf(2));
            assert.equal(2, [1, 2, 3].indexOf(3));
        });
    });
});

var d = [[{ms: 0, val: 1}, {ms: 5, val: 2}, {ms: 10, val: 4}]];
var allKeys = ['average', 'rawData', 'q1', 'q3', 'mins', 'maxes'];

describe('binnedData', function(){
    describe('write-read', function(){
        it('should return whatever is inserted', function(){
            var bd = binnedData();
            bd.addRawData(d[0]);
            assert.deepEqual(d[0], bd.getDateRange(['average'], 0, [-1000, 1000]));
        })
    })
})
<|endoftext|>


<commit_before>/**
 * core/user Data store: Authentication info tests.
 *
 * Site Kit by Google, Copyright 2020 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * WordPress dependencies
 */
import apiFetch from '@wordpress/api-fetch';

/**
 * Internal dependencies
 */
import API from 'googlesitekit-api';
import {
	createTestRegistry,
	muteConsole,
	subscribeUntil,
	unsubscribeFromAll,
} from '../../../../../tests/js/utils';
import { STORE_NAME } from './constants';

describe( 'core/user authentication', () => {
	const coreUserDataExpectedResponse = {
		authenticated: true,
		requiredScopes: [],
		grantedScopes: [],
		unsatisfiedScopes: [],
	};
	const coreUserDataEndpointRegExp = /^\/google-site-kit\/v1\/core\/user\/data\/authentication/;
	let apiFetchSpy;
	let registry;
	let store;

	beforeAll( () => {
		API.setUsingCache( false );
	} );

	beforeEach( () => {
		registry = createTestRegistry();
		store = registry.stores[ STORE_NAME ].store;

		apiFetchSpy = jest.spyOn( { apiFetch }, 'apiFetch' );
	} );

	afterAll( () => {
		API.setUsingCache( true );
	} );

	afterEach( () => {
		unsubscribeFromAll( registry );
		apiFetchSpy.mockRestore();
	} );

	describe( 'actions', () => {
		describe( 'fetchAuthentication', () => {
			it( 'does not require any params', () => {
				// Create a mock to avoid triggering a network request error.
				// The return value is irrelevant to the test.
				fetch
					.doMockOnceIf( coreUserDataEndpointRegExp )
					.mockResponseOnce(
						JSON.stringify( {} ),
						{ status: 200 }
					);
				expect( () => {
					registry.dispatch( STORE_NAME ).fetchAuthentication();
				} ).not.toThrow();
			} );
		} );
		describe( 'receiveAuthentication', () => {
			it( 'requires the authentication param', () => {
				expect( () => {
					registry.dispatch( STORE_NAME ).receiveAuthentication();
				} ).toThrow( 'authentication is required.' );
			} );
		} );
	} );

	describe( 'selectors', () => {
		describe( 'getAuthentication', () => {
			it( 'uses a resolver to make a network request', async () => {
				fetch
					.doMockOnceIf( coreUserDataEndpointRegExp )
					.mockResponseOnce(
						JSON.stringify( coreUserDataExpectedResponse ),
						{ status: 200 }
					);

				const initialAuthentication = registry.select( STORE_NAME ).getAuthentication();
				// The authentication info will be its initial value while the authentication
				// info is fetched.
				expect( initialAuthentication ).toEqual( undefined );
				await subscribeUntil( registry,
					() => (
						registry.select( STORE_NAME ).getAuthentication() !== undefined
					),
				);

				const authentication = registry.select( STORE_NAME ).getAuthentication();

				expect( fetch ).toHaveBeenCalledTimes( 1 );
				expect( authentication ).toEqual( coreUserDataExpectedResponse );

				const authenticationSelect = registry.select( STORE_NAME ).getAuthentication();
				expect( fetch ).toHaveBeenCalledTimes( 1 );
				expect( authenticationSelect ).toEqual( authentication );
			} );

			it( 'does not make a network request if data is already in state', async () => {
				registry.dispatch( STORE_NAME ).receiveAuthentication( coreUserDataExpectedResponse );

				const authentication = registry.select( STORE_NAME ).getAuthentication();

				await subscribeUntil( registry, () => registry
					.select( STORE_NAME )
					.hasFinishedResolution( 'getAuthentication' )
				);

				expect( fetch ).not.toHaveBeenCalled();
				expect( authentication ).toEqual( coreUserDataExpectedResponse );
			} );

			it( 'dispatches an error if the request fails', async () => {
				const response = {
					code: 'internal_server_error',
					message: 'Internal server error',
					data: { status: 500 },
				};
				fetch
					.doMockOnceIf( coreUserDataEndpointRegExp )
					.mockResponseOnce(
						JSON.stringify( response ),
						{ status: 500 }
					);

				muteConsole( 'error' );
				registry.select( STORE_NAME ).getAuthentication();
				await subscribeUntil( registry, () => registry
					.select( STORE_NAME )
					.hasFinishedResolution( 'getAuthentication' )
				);

				const authentication = registry.select( STORE_NAME ).getAuthentication();

				expect( fetch ).toHaveBeenCalledTimes( 1 );
				expect( authentication ).toEqual( undefined );
			} );
		} );

		describe( 'isAuthenticated', () => {
			it( 'uses a resolver to to load the authenticated value if not yet set.', async () => {
				fetch
					.doMockOnceIf( coreUserDataEndpointRegExp )
					.mockResponseOnce(
						JSON.stringify( coreUserDataExpectedResponse ),
						{ status: 200 }
					);

				const initialIsAuthenticated = registry.select( STORE_NAME ).isAuthenticated();
				// The autentication info will be its initial value while the authentication
				// info is fetched.
				expect( initialIsAuthenticated ).toEqual( undefined );
				await subscribeUntil( registry,
					() => (
						registry.select( STORE_NAME ).isAuthenticated() !== undefined
					),
				);

				const isAuthenticated = registry.select( STORE_NAME ).isAuthenticated();

				expect( fetch ).toHaveBeenCalledTimes( 1 );
				expect( isAuthenticated ).toEqual( coreUserDataExpectedResponse.authenticated );
			} );

			it( 'dispatches an error if the request fails', async () => {
				const response = {
					code: 'internal_server_error',
					message: 'Internal server error',
					data: { status: 500 },
				};
				fetch
					.doMockOnceIf( coreUserDataEndpointRegExp )
					.mockResponseOnce(
						JSON.stringify( response ),
						{ status: 500 }
					);

				muteConsole( 'error' );
				registry.select( STORE_NAME ).isAuthenticated();
				await subscribeUntil( registry,
					// TODO: We may want a selector for this, but for now this is fine
					// because it's internal-only.
					() => store.getState().isFetchingAuthentication === false,
				);

				const isAuthenticated = registry.select( STORE_NAME ).isAuthenticated();
				const error = registry.select( STORE_NAME ).getError();

				expect( fetch ).toHaveBeenCalledTimes( 1 );
				expect( isAuthenticated ).toEqual( undefined );
				expect( error ).toEqual( response );
			} );

			it( 'returns undefined if authentication info is not available', async () => {
				// Create a mock to avoid triggering a network request error.
				// The return value is irrelevant to the test.
				fetch
					.doMockOnceIf( coreUserDataEndpointRegExp )
					.mockResponseOnce(
						JSON.stringify( {} ),
						{ status: 200 }
					);
				const isAuthenticated = registry.select( STORE_NAME ).isAuthenticated();

				expect( isAuthenticated ).toEqual( undefined );
			} );
		} );

		describe( 'getGrantedScopes', () => {
			it( 'uses a resolver get all authentication info', async () => {
				fetch
					.doMockOnceIf( coreUserDataEndpointRegExp )
					.mockResponseOnce(
						JSON.stringify( coreUserDataExpectedResponse ),
						{ status: 200 }
					);

				const initialGrantedScopes = registry.select( STORE_NAME ).getGrantedScopes();
				// The granted scope info will be its initial value while the granted scope
				// info is fetched.
				expect( initialGrantedScopes ).toEqual( undefined );
				await subscribeUntil( registry,
					() => (
						registry.select( STORE_NAME ).getGrantedScopes() !== undefined
					),
				);

				const grantedScopes = registry.select( STORE_NAME ).getGrantedScopes();

				expect( fetch ).toHaveBeenCalledTimes( 1 );
				expect( grantedScopes ).toEqual( coreUserDataExpectedResponse.grantedScopes );
			} );

			it( 'dispatches an error if the request fails', async () => {
				const response = {
					code: 'internal_server_error',
					message: 'Internal server error',
					data: { status: 500 },
				};
				fetch
					.doMockOnceIf( coreUserDataEndpointRegExp )
					.mockResponseOnce(
						JSON.stringify( response ),
						{ status: 500 }
					);

				muteConsole( 'error' );
				registry.select( STORE_NAME ).getGrantedScopes();
				await subscribeUntil( registry,
					// TODO: We may want a selector for this, but for now this is fine
					// because it's internal-only.
					() => store.getState().isFetchingAuthentication === false,
				);

				const grantedScopes = registry.select( STORE_NAME ).getGrantedScopes();
				const error = registry.select( STORE_NAME ).getError();

				expect( fetch ).toHaveBeenCalledTimes( 1 );
				expect( grantedScopes ).toEqual( undefined );
				expect( error ).toEqual( response );
			} );

			it( 'returns undefined if authentication info is not available', async () => {
				// Create a mock to avoid triggering a network request error.
				// The return value is irrelevant to the test.
				fetch
					.doMockOnceIf( coreUserDataEndpointRegExp )
					.mockResponseOnce(
						JSON.stringify( {} ),
						{ status: 200 }
					);
				const grantedScopes = registry.select( STORE_NAME ).getGrantedScopes();

				expect( grantedScopes ).toEqual( undefined );
			} );
		} );

		describe( 'getRequiredScopes', () => {
			it( 'uses a resolver get all authentication info', async () => {
				fetch
					.doMockOnceIf( coreUserDataEndpointRegExp )
					.mockResponseOnce(
						JSON.stringify( coreUserDataExpectedResponse ),
						{ status: 200 }
					);

				const initialRequiredScopes = registry.select( STORE_NAME ).getRequiredScopes();
				// The required scope info will be its initial value while the required scope
				// info is fetched.
				expect( initialRequiredScopes ).toEqual( undefined );
				await subscribeUntil( registry,
					() => (
						registry.select( STORE_NAME ).getRequiredScopes() !== undefined
					),
				);

				const requiredScopes = registry.select( STORE_NAME ).getRequiredScopes();

				expect( fetch ).toHaveBeenCalledTimes( 1 );
				expect( requiredScopes ).toEqual( coreUserDataExpectedResponse.requiredScopes );
			} );

			it( 'dispatches an error if the request fails', async () => {
				const response = {
					code: 'internal_server_error',
					message: 'Internal server error',
					data: { status: 500 },
				};
				fetch
					.doMockOnceIf( coreUserDataEndpointRegExp )
					.mockResponseOnce(
						JSON.stringify( response ),
						{ status: 500 }
					);

				muteConsole( 'error' );
				registry.select( STORE_NAME ).getRequiredScopes();
				await subscribeUntil( registry,
					// TODO: We may want a selector for this, but for now this is fine
					// because it's internal-only.
					() => store.getState().isFetchingAuthentication === false,
				);

				const requiredScopes = registry.select( STORE_NAME ).getRequiredScopes();
				const error = registry.select( STORE_NAME ).getError();

				expect( fetch ).toHaveBeenCalledTimes( 1 );
				expect( requiredScopes ).toEqual( undefined );
				expect( error ).toEqual( response );
			} );

			it( 'returns undefined if authentication info is not available', async () => {
				// Create a mock to avoid triggering a network request error.
				// The return value is irrelevant to the test.
				fetch
					.doMockOnceIf( coreUserDataEndpointRegExp )
					.mockResponseOnce(
						JSON.stringify( {} ),
						{ status: 200 }
					);
				const requiredScopes = registry.select( STORE_NAME ).getRequiredScopes();

				expect( requiredScopes ).toEqual( undefined );
			} );
		} );

		describe( 'getUnsatisfiedScopes', () => {
			it( 'uses a resolver get all authentication info', async () => {
				fetch
					.doMockOnceIf( coreUserDataEndpointRegExp )
					.mockResponseOnce(
						JSON.stringify( coreUserDataExpectedResponse ),
						{ status: 200 }
					);

				const initialUnsatisfiedScopes = registry.select( STORE_NAME ).getUnsatisfiedScopes();
				// The scopes will be their initial value until the data is resolved.
				expect( initialUnsatisfiedScopes ).toEqual( undefined );
				await subscribeUntil( registry,
					() => registry.select( STORE_NAME ).hasFinishedResolution( 'getAuthentication' )
				);

				const unsatisfiedScopes = registry.select( STORE_NAME ).getUnsatisfiedScopes();

				expect( fetch ).toHaveBeenCalledTimes( 1 );
				expect( unsatisfiedScopes ).toEqual( coreUserDataExpectedResponse.unsatisfiedScopes );
			} );

			it( 'dispatches an error if the request fails', async () => {
				const response = {
					code: 'internal_server_error',
					message: 'Internal server error',
					data: { status: 500 },
				};
				fetch
					.doMockOnceIf( coreUserDataEndpointRegExp )
					.mockResponseOnce(
						JSON.stringify( response ),
						{ status: 500 }
					);

				muteConsole( 'error' );
				registry.select( STORE_NAME ).getUnsatisfiedScopes();
				await subscribeUntil( registry,
					() => registry.select( STORE_NAME ).hasFinishedResolution( 'getAuthentication' )
				);

				const unsatisfiedScopes = registry.select( STORE_NAME ).getUnsatisfiedScopes();
				const error = registry.select( STORE_NAME ).getError();

				expect( fetch ).toHaveBeenCalledTimes( 1 );
				expect( unsatisfiedScopes ).toEqual( undefined );
				expect( error ).toEqual( response );
			} );

			it( 'returns undefined if authentication info is not available', async () => {
				// Create a mock to avoid triggering a network request error.
				// The return value is irrelevant to the test.
				fetch
					.doMockOnceIf( coreUserDataEndpointRegExp )
					.mockResponseOnce(
						JSON.stringify( {} ),
						{ status: 200 }
					);
				const unsatisfiedScopes = registry.select( STORE_NAME ).getUnsatisfiedScopes();

				expect( unsatisfiedScopes ).toEqual( undefined );
			} );
		} );

		describe( 'needsReauthentication', () => {
			it( 'dispatches an error if the request fails', async () => {
				const response = {
					code: 'internal_server_error',
					message: 'Internal server error',
					data: { status: 500 },
				};
				fetch
					.doMockOnceIf( coreUserDataEndpointRegExp )
					.mockResponseOnce(
						JSON.stringify( response ),
						{ status: 500 }
					);

				muteConsole( 'error' );
				registry.select( STORE_NAME ).needsReauthentication();
				await subscribeUntil( registry,
					// TODO: We may want a selector for this, but for now this is fine
					// because it's internal-only.
					() => store.getState().isFetchingAuthentication === false,
				);

				const needsReauthentication = registry.select( STORE_NAME ).needsReauthentication();
				const error = registry.select( STORE_NAME ).getError();

				expect( fetch ).toHaveBeenCalledTimes( 1 );
				expect( needsReauthentication ).toEqual( undefined );
				expect( error ).toEqual( response );
			} );

			it( 'returns undefined if reauthentication info is not available', async () => {
				// Create a mock to avoid triggering a network request error.
				// The return value is irrelevant to the test.
				fetch
					.doMockOnceIf( coreUserDataEndpointRegExp )
					.mockResponseOnce(
						JSON.stringify( {} ),
						{ status: 200 }
					);
				const needsReauthentication = registry.select( STORE_NAME ).needsReauthentication();

				expect( needsReauthentication ).toEqual( undefined );
			} );
		} );
	} );
} );
<commit_msg>Added authentication test for uses a resolver.<commit_after>/**
 * core/user Data store: Authentication info tests.
 *
 * Site Kit by Google, Copyright 2020 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * WordPress dependencies
 */
import apiFetch from '@wordpress/api-fetch';

/**
 * Internal dependencies
 */
import API from 'googlesitekit-api';
import {
	createTestRegistry,
	muteConsole,
	subscribeUntil,
	unsubscribeFromAll,
} from '../../../../../tests/js/utils';
import { STORE_NAME } from './constants';

describe( 'core/user authentication', () => {
	const coreUserDataExpectedResponse = {
		authenticated: true,
		requiredScopes: [],
		grantedScopes: [],
		unsatisfiedScopes: [],
	};
	const coreUserDataEndpointRegExp = /^\/google-site-kit\/v1\/core\/user\/data\/authentication/;
	let apiFetchSpy;
	let registry;
	let store;

	beforeAll( () => {
		API.setUsingCache( false );
	} );

	beforeEach( () => {
		registry = createTestRegistry();
		store = registry.stores[ STORE_NAME ].store;

		apiFetchSpy = jest.spyOn( { apiFetch }, 'apiFetch' );
	} );

	afterAll( () => {
		API.setUsingCache( true );
	} );

	afterEach( () => {
		unsubscribeFromAll( registry );
		apiFetchSpy.mockRestore();
	} );

	describe( 'actions', () => {
		describe( 'fetchAuthentication', () => {
			it( 'does not require any params', () => {
				// Create a mock to avoid triggering a network request error.
				// The return value is irrelevant to the test.
				fetch
					.doMockOnceIf( coreUserDataEndpointRegExp )
					.mockResponseOnce(
						JSON.stringify( {} ),
						{ status: 200 }
					);
				expect( () => {
					registry.dispatch( STORE_NAME ).fetchAuthentication();
				} ).not.toThrow();
			} );
		} );
		describe( 'receiveAuthentication', () => {
			it( 'requires the authentication param', () => {
				expect( () => {
					registry.dispatch( STORE_NAME ).receiveAuthentication();
				} ).toThrow( 'authentication is required.' );
			} );
		} );
	} );

	describe( 'selectors', () => {
		describe( 'getAuthentication', () => {
			it( 'uses a resolver to make a network request', async () => {
				fetch
					.doMockOnceIf( coreUserDataEndpointRegExp )
					.mockResponseOnce(
						JSON.stringify( coreUserDataExpectedResponse ),
						{ status: 200 }
					);

				const initialAuthentication = registry.select( STORE_NAME ).getAuthentication();
				// The authentication info will be its initial value while the authentication
				// info is fetched.
				expect( initialAuthentication ).toEqual( undefined );
				await subscribeUntil( registry,
					() => (
						registry.select( STORE_NAME ).getAuthentication() !== undefined
					),
				);

				const authentication = registry.select( STORE_NAME ).getAuthentication();

				expect( fetch ).toHaveBeenCalledTimes( 1 );
				expect( authentication ).toEqual( coreUserDataExpectedResponse );

				const authenticationSelect = registry.select( STORE_NAME ).getAuthentication();
				expect( fetch ).toHaveBeenCalledTimes( 1 );
				expect( authenticationSelect ).toEqual( authentication );
			} );

			it( 'does not make a network request if data is already in state', async () => {
				registry.dispatch( STORE_NAME ).receiveAuthentication( coreUserDataExpectedResponse );

				const authentication = registry.select( STORE_NAME ).getAuthentication();

				await subscribeUntil( registry, () => registry
					.select( STORE_NAME )
					.hasFinishedResolution( 'getAuthentication' )
				);

				expect( fetch ).not.toHaveBeenCalled();
				expect( authentication ).toEqual( coreUserDataExpectedResponse );
			} );

			it( 'dispatches an error if the request fails', async () => {
				const response = {
					code: 'internal_server_error',
					message: 'Internal server error',
					data: { status: 500 },
				};
				fetch
					.doMockOnceIf( coreUserDataEndpointRegExp )
					.mockResponseOnce(
						JSON.stringify( response ),
						{ status: 500 }
					);

				muteConsole( 'error' );
				registry.select( STORE_NAME ).getAuthentication();
				await subscribeUntil( registry, () => registry
					.select( STORE_NAME )
					.hasFinishedResolution( 'getAuthentication' )
				);

				const authentication = registry.select( STORE_NAME ).getAuthentication();

				expect( fetch ).toHaveBeenCalledTimes( 1 );
				expect( authentication ).toEqual( undefined );
			} );
		} );

		describe( 'isAuthenticated', () => {
			it( 'uses a resolver to to load the authenticated value if not yet set.', async () => {
				fetch
					.doMockOnceIf( coreUserDataEndpointRegExp )
					.mockResponseOnce(
						JSON.stringify( coreUserDataExpectedResponse ),
						{ status: 200 }
					);

				const initialIsAuthenticated = registry.select( STORE_NAME ).isAuthenticated();
				// The autentication info will be its initial value while the authentication
				// info is fetched.
				expect( initialIsAuthenticated ).toEqual( undefined );
				await subscribeUntil( registry,
					() => (
						registry.select( STORE_NAME ).isAuthenticated() !== undefined
					),
				);

				const isAuthenticated = registry.select( STORE_NAME ).isAuthenticated();

				expect( fetch ).toHaveBeenCalledTimes( 1 );
				expect( isAuthenticated ).toEqual( coreUserDataExpectedResponse.authenticated );
			} );

			it( 'dispatches an error if the request fails', async () => {
				const response = {
					code: 'internal_server_error',
					message: 'Internal server error',
					data: { status: 500 },
				};
				fetch
					.doMockOnceIf( coreUserDataEndpointRegExp )
					.mockResponseOnce(
						JSON.stringify( response ),
						{ status: 500 }
					);

				muteConsole( 'error' );
				registry.select( STORE_NAME ).isAuthenticated();
				await subscribeUntil( registry,
					// TODO: We may want a selector for this, but for now this is fine
					// because it's internal-only.
					() => store.getState().isFetchingAuthentication === false,
				);

				const isAuthenticated = registry.select( STORE_NAME ).isAuthenticated();
				const error = registry.select( STORE_NAME ).getError();

				expect( fetch ).toHaveBeenCalledTimes( 1 );
				expect( isAuthenticated ).toEqual( undefined );
				expect( error ).toEqual( response );
			} );

			it( 'returns undefined if authentication info is not available', async () => {
				// Create a mock to avoid triggering a network request error.
				// The return value is irrelevant to the test.
				fetch
					.doMockOnceIf( coreUserDataEndpointRegExp )
					.mockResponseOnce(
						JSON.stringify( {} ),
						{ status: 200 }
					);
				const isAuthenticated = registry.select( STORE_NAME ).isAuthenticated();

				expect( isAuthenticated ).toEqual( undefined );
			} );
		} );

		describe( 'getGrantedScopes', () => {
			it( 'uses a resolver get all authentication info', async () => {
				fetch
					.doMockOnceIf( coreUserDataEndpointRegExp )
					.mockResponseOnce(
						JSON.stringify( coreUserDataExpectedResponse ),
						{ status: 200 }
					);

				const initialGrantedScopes = registry.select( STORE_NAME ).getGrantedScopes();
				// The granted scope info will be its initial value while the granted scope
				// info is fetched.
				expect( initialGrantedScopes ).toEqual( undefined );
				await subscribeUntil( registry,
					() => (
						registry.select( STORE_NAME ).getGrantedScopes() !== undefined
					),
				);

				const grantedScopes = registry.select( STORE_NAME ).getGrantedScopes();

				expect( fetch ).toHaveBeenCalledTimes( 1 );
				expect( grantedScopes ).toEqual( coreUserDataExpectedResponse.grantedScopes );
			} );

			it( 'dispatches an error if the request fails', async () => {
				const response = {
					code: 'internal_server_error',
					message: 'Internal server error',
					data: { status: 500 },
				};
				fetch
					.doMockOnceIf( coreUserDataEndpointRegExp )
					.mockResponseOnce(
						JSON.stringify( response ),
						{ status: 500 }
					);

				muteConsole( 'error' );
				registry.select( STORE_NAME ).getGrantedScopes();
				await subscribeUntil( registry,
					// TODO: We may want a selector for this, but for now this is fine
					// because it's internal-only.
					() => store.getState().isFetchingAuthentication === false,
				);

				const grantedScopes = registry.select( STORE_NAME ).getGrantedScopes();
				const error = registry.select( STORE_NAME ).getError();

				expect( fetch ).toHaveBeenCalledTimes( 1 );
				expect( grantedScopes ).toEqual( undefined );
				expect( error ).toEqual( response );
			} );

			it( 'returns undefined if authentication info is not available', async () => {
				// Create a mock to avoid triggering a network request error.
				// The return value is irrelevant to the test.
				fetch
					.doMockOnceIf( coreUserDataEndpointRegExp )
					.mockResponseOnce(
						JSON.stringify( {} ),
						{ status: 200 }
					);
				const grantedScopes = registry.select( STORE_NAME ).getGrantedScopes();

				expect( grantedScopes ).toEqual( undefined );
			} );
		} );

		describe( 'getRequiredScopes', () => {
			it( 'uses a resolver get all authentication info', async () => {
				fetch
					.doMockOnceIf( coreUserDataEndpointRegExp )
					.mockResponseOnce(
						JSON.stringify( coreUserDataExpectedResponse ),
						{ status: 200 }
					);

				const initialRequiredScopes = registry.select( STORE_NAME ).getRequiredScopes();
				// The required scope info will be its initial value while the required scope
				// info is fetched.
				expect( initialRequiredScopes ).toEqual( undefined );
				await subscribeUntil( registry,
					() => (
						registry.select( STORE_NAME ).getRequiredScopes() !== undefined
					),
				);

				const requiredScopes = registry.select( STORE_NAME ).getRequiredScopes();

				expect( fetch ).toHaveBeenCalledTimes( 1 );
				expect( requiredScopes ).toEqual( coreUserDataExpectedResponse.requiredScopes );
			} );

			it( 'dispatches an error if the request fails', async () => {
				const response = {
					code: 'internal_server_error',
					message: 'Internal server error',
					data: { status: 500 },
				};
				fetch
					.doMockOnceIf( coreUserDataEndpointRegExp )
					.mockResponseOnce(
						JSON.stringify( response ),
						{ status: 500 }
					);

				muteConsole( 'error' );
				registry.select( STORE_NAME ).getRequiredScopes();
				await subscribeUntil( registry,
					// TODO: We may want a selector for this, but for now this is fine
					// because it's internal-only.
					() => store.getState().isFetchingAuthentication === false,
				);

				const requiredScopes = registry.select( STORE_NAME ).getRequiredScopes();
				const error = registry.select( STORE_NAME ).getError();

				expect( fetch ).toHaveBeenCalledTimes( 1 );
				expect( requiredScopes ).toEqual( undefined );
				expect( error ).toEqual( response );
			} );

			it( 'returns undefined if authentication info is not available', async () => {
				// Create a mock to avoid triggering a network request error.
				// The return value is irrelevant to the test.
				fetch
					.doMockOnceIf( coreUserDataEndpointRegExp )
					.mockResponseOnce(
						JSON.stringify( {} ),
						{ status: 200 }
					);
				const requiredScopes = registry.select( STORE_NAME ).getRequiredScopes();

				expect( requiredScopes ).toEqual( undefined );
			} );
		} );

		describe( 'getUnsatisfiedScopes', () => {
			it( 'uses a resolver get all authentication info', async () => {
				fetch
					.doMockOnceIf( coreUserDataEndpointRegExp )
					.mockResponseOnce(
						JSON.stringify( coreUserDataExpectedResponse ),
						{ status: 200 }
					);

				const initialUnsatisfiedScopes = registry.select( STORE_NAME ).getUnsatisfiedScopes();
				// The scopes will be their initial value until the data is resolved.
				expect( initialUnsatisfiedScopes ).toEqual( undefined );
				await subscribeUntil( registry,
					() => registry.select( STORE_NAME ).hasFinishedResolution( 'getAuthentication' )
				);

				const unsatisfiedScopes = registry.select( STORE_NAME ).getUnsatisfiedScopes();

				expect( fetch ).toHaveBeenCalledTimes( 1 );
				expect( unsatisfiedScopes ).toEqual( coreUserDataExpectedResponse.unsatisfiedScopes );
			} );

			it( 'dispatches an error if the request fails', async () => {
				const response = {
					code: 'internal_server_error',
					message: 'Internal server error',
					data: { status: 500 },
				};
				fetch
					.doMockOnceIf( coreUserDataEndpointRegExp )
					.mockResponseOnce(
						JSON.stringify( response ),
						{ status: 500 }
					);

				muteConsole( 'error' );
				registry.select( STORE_NAME ).getUnsatisfiedScopes();
				await subscribeUntil( registry,
					() => registry.select( STORE_NAME ).hasFinishedResolution( 'getAuthentication' )
				);

				const unsatisfiedScopes = registry.select( STORE_NAME ).getUnsatisfiedScopes();
				const error = registry.select( STORE_NAME ).getError();

				expect( fetch ).toHaveBeenCalledTimes( 1 );
				expect( unsatisfiedScopes ).toEqual( undefined );
				expect( error ).toEqual( response );
			} );

			it( 'returns undefined if authentication info is not available', async () => {
				// Create a mock to avoid triggering a network request error.
				// The return value is irrelevant to the test.
				fetch
					.doMockOnceIf( coreUserDataEndpointRegExp )
					.mockResponseOnce(
						JSON.stringify( {} ),
						{ status: 200 }
					);
				const unsatisfiedScopes = registry.select( STORE_NAME ).getUnsatisfiedScopes();

				expect( unsatisfiedScopes ).toEqual( undefined );
			} );
		} );

		describe( 'needsReauthentication', () => {
			it( 'uses a resolver get all reauthentication info', async () => {
				fetch
					.doMockOnceIf( coreUserDataEndpointRegExp )
					.mockResponseOnce(
						JSON.stringify( coreUserDataExpectedResponse ),
						{ status: 200 }
					);

				const initialNeedsReauthentication = registry.select( STORE_NAME ).needsReauthentication();
				// The scopes will be their initial value until the data is resolved.
				expect( initialNeedsReauthentication ).toEqual( undefined );
				await subscribeUntil( registry,
					() => registry.select( STORE_NAME ).hasFinishedResolution( 'getAuthentication' )
				);

				const needsReauthentication = registry.select( STORE_NAME ).needsReauthentication();

				expect( fetch ).toHaveBeenCalledTimes( 1 );
				expect( needsReauthentication ).toEqual( coreUserDataExpectedResponse.needsReauthentication );
			} );

			it( 'dispatches an error if the request fails', async () => {
				const response = {
					code: 'internal_server_error',
					message: 'Internal server error',
					data: { status: 500 },
				};
				fetch
					.doMockOnceIf( coreUserDataEndpointRegExp )
					.mockResponseOnce(
						JSON.stringify( response ),
						{ status: 500 }
					);

				muteConsole( 'error' );
				registry.select( STORE_NAME ).needsReauthentication();
				await subscribeUntil( registry,
					// TODO: We may want a selector for this, but for now this is fine
					// because it's internal-only.
					() => store.getState().isFetchingAuthentication === false,
				);

				const needsReauthentication = registry.select( STORE_NAME ).needsReauthentication();
				const error = registry.select( STORE_NAME ).getError();

				expect( fetch ).toHaveBeenCalledTimes( 1 );
				expect( needsReauthentication ).toEqual( undefined );
				expect( error ).toEqual( response );
			} );

			it( 'returns undefined if reauthentication info is not available', async () => {
				// Create a mock to avoid triggering a network request error.
				// The return value is irrelevant to the test.
				fetch
					.doMockOnceIf( coreUserDataEndpointRegExp )
					.mockResponseOnce(
						JSON.stringify( {} ),
						{ status: 200 }
					);
				const needsReauthentication = registry.select( STORE_NAME ).needsReauthentication();

				expect( needsReauthentication ).toEqual( undefined );
			} );
		} );
	} );
} );
<|endoftext|>