<commit_before>/*eslint quotes: ["off"]*/

import { expect } from "chai";
import sinon from "sinon";
import BitBundler from "../../src/index";
import loggers from "../../loggers";

describe("BitBundler test suite", function() {
  var createBundler, bitbundler;

  beforeEach(function() {
    createBundler = (config) => bitbundler = new BitBundler(Object.assign({ log: { stream: loggers.through() } }, config || {}));
  });

  describe("When creating a bundler with no configuration", function() {
    beforeEach(function() {
      createBundler();
    });

    it("then the bundler is an instance of Bundler", function() {
      expect(bitbundler).to.be.an.instanceof(BitBundler);
    });

    describe("and bundling a module with a couple of dependencies", function() {
      var result;

      beforeEach(function() {
        return bitbundler.bundle("test/sample/X.js").then(function(ctx) {
          result = ctx;
        });
      });

      it("then result contains the dependencies", function() {
        expect(trimResult(result.bundle.content)).to.be.equal(`require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){/*eslint no-console: ["off"]*/var Y = require("./Y");function X() {  console.log("Say X");  this._y = new Y();}module.exports = new X();},{"./Y":2}],2:[function(require,module,exports){/*eslint no-console: ["off"]*/var z = require("./z");var X = require("./X");function Y() {  console.log(X, typeof X);  console.log("Say Y");  z.potatoes();}module.exports = Y;},{"./X":1,"./z":3}],3:[function(require,module,exports){/*eslint no-console: ["off"]*/module.exports = {  roast: "this",  potatoes: function() {    console.log("Say potatoes");  }};},{}]},{},[1])`);
      });
    });
  });

  describe("When creating a bundler with the JS plugin and spitting bundles", function() {
    beforeEach(function() {
      createBundler({
        bundler: [
          ["bit-bundler-splitter", [
            { dest: "test/dest/Y.js", match: { fileName: "Y.js" }},
            { dest: "test/dest/Z.js", match: { fileName: "z.js" }}]
          ]
        ]
      });
    });

    it("then the bundler is an instance of Bundler", function() {
      expect(bitbundler).to.be.an.instanceof(BitBundler);
    });

    describe("and bundling a module with a couple of dependencies", function() {
      var result;

      beforeEach(function() {
        return bitbundler.bundle("test/sample/X.js").then(function(ctx) {
          result = ctx;
        });
      });

      it("then the result has one root module", function() {
        expect(result.modules).to.have.lengthOf(1);
      });

      it("then the result root module is X.js", function() {
        expect(result.modules[0].fileName).to.be.equal("X.js");
      });

      it("then result contains the dependencies", function() {
        expect(trimResult(result.bundle.content)).to.be.equal(`require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){/*eslint no-console: ["off"]*/var Y = require("./Y");function X() {  console.log("Say X");  this._y = new Y();}module.exports = new X();},{"./Y":2}]},{},[1])`);
      });

      it("then splitter created a shard for 'test/dest/Y.js'", function() {
        expect(result.shards).to.have.property("test/dest/Y.js");
      });

      it("then splitter created a shard for 'test/dest/Y.js' with the correct bundle result", function() {
        expect(trimResult(result.shards["test/dest/Y.js"].content)).to.be.equal(`require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({2:[function(require,module,exports){/*eslint no-console: ["off"]*/var z = require("./z");var X = require("./X");function Y() {  console.log(X, typeof X);  console.log("Say Y");  z.potatoes();}module.exports = Y;},{"./X":1,"./z":3}],3:[function(require,module,exports){/*eslint no-console: ["off"]*/module.exports = {  roast: "this",  potatoes: function() {    console.log("Say potatoes");  }};},{}],1:[function(require,module,exports){/*eslint no-console: ["off"]*/var Y = require("./Y");function X() {  console.log("Say X");  this._y = new Y();}module.exports = new X();},{"./Y":2}]},{},[2])`);
      });

      it("then splitter created a shard for 'test/dest/Z.js'", function() {
        expect(result.shards).to.have.property("test/dest/Z.js");
      });

      it("then splitter created a shard for 'test/dest/Z.js' with the correct bundle result", function() {
        expect(trimResult(result.shards["test/dest/Z.js"].content)).to.be.equal(`require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({3:[function(require,module,exports){/*eslint no-console: ["off"]*/module.exports = {  roast: "this",  potatoes: function() {    console.log("Say potatoes");  }};},{}]},{},[3])`);
      });
    });
  });

  describe("Given a bundler", function() {
    var context, buildInit, buildStart, buildEnd;

    beforeEach(function() {
      createBundler();
      context = createMockContext();
      bitbundler.context = context;

      sinon.spy(bitbundler, "emit");
      bitbundler.buildBundles = sinon.stub().resolves(context);
      bitbundler.loader.hasModule = sinon.stub();
      bitbundler.loader.getModule = sinon.stub();
      bitbundler.loader.deleteModule = sinon.stub();

      buildInit = sinon.stub();
      buildStart = sinon.stub();
      buildEnd = sinon.stub();

      bitbundler
        .on("build-init", buildInit)
        .on("build-start", buildStart)
        .on("build-end", buildEnd);
    });

    describe("And creating a bundle with one files", function() {
      beforeEach(function() {
        return bitbundler.bundle(["test/sample/X.js"]);
      });

      it("then emit is called with `build-init`", function() {
        sinon.assert.calledWith(bitbundler.emit, "build-init");
      });

      it("then emit is called with `build-start`", function() {
        sinon.assert.calledWith(bitbundler.emit, "build-start");
      });

      it("then initBuild event handler is called", function() {
        sinon.assert.called(buildInit);
      });

      it("then preBuild event handler is called", function() {
        sinon.assert.called(buildStart);
      });

      it("then postBuild event handler is called", function() {
        sinon.assert.called(buildEnd);
      });

      it("then loader.hasModule is called", function() {
        sinon.assert.called(bitbundler.loader.hasModule);
      });

      it("then loader.getModule is not called", function() {
        sinon.assert.notCalled(bitbundler.loader.getModule);
      });

      it("then loader.deleteModule is not called", function() {
        sinon.assert.notCalled(bitbundler.loader.deleteModule);
      });

      it("then buildBundles is called with the corresponding file names", function() {
        sinon.assert.calledWith(bitbundler.buildBundles, sinon.match.has("src", sinon.match(arrayItemContains("test/sample/X.js"))));
      });

      it("then visitBundles is called", function() {
        sinon.assert.called(context.visitBundles);
      });
    });

    describe("And updating a bundle with one files", function() {
      var file;

      beforeEach(function() {
        file = new BitBundler.File("test/sample/X.js");
        file.src.forEach((filePath) => bitbundler.loader.hasModule.withArgs(filePath).returns(true));
        return bitbundler.update(file.src);
      });

      it("then emit is called with `build-init`", function() {
        sinon.assert.neverCalledWith(bitbundler.emit, "build-init");
      });

      it("then emit is called with `build-start`", function() {
        sinon.assert.calledWith(bitbundler.emit, "build-start");
      });

      it("then initBuild event handler is NOT called", function() {
        sinon.assert.notCalled(buildInit);
      });

      it("then preBuild event handler is called", function() {
        sinon.assert.called(buildStart);
      });

      it("then postBuild event handler is called", function() {
        sinon.assert.called(buildEnd);
      });

      it("then loader.hasModule is called", function() {
        sinon.assert.called(bitbundler.loader.hasModule);
      });

      it("then loader.getModule is called", function() {
        sinon.assert.called(bitbundler.loader.getModule);
      });

      it("then loader.deleteModule is called", function() {
        sinon.assert.called(bitbundler.loader.deleteModule);
      });

      it("then buildBundles is called with the corresponding file names", function() {
        sinon.assert.calledWith(bitbundler.buildBundles, sinon.match.has("src", sinon.match(arrayItemContains("test/sample/X.js"))));
      });

      it("then visitBundles is called", function() {
        sinon.assert.called(context.visitBundles);
      });
    });

    describe("And bundling fails", function() {
      beforeEach(function() {
        bitbundler.buildBundles = sinon.stub().rejects("bad");
        return bitbundler.bundle(["test/sample/X.js"]).catch(function() {});
      });

      it("then emit is called with `build-init`", function() {
        sinon.assert.calledWith(bitbundler.emit, "build-init");
      });

      it("then emit is called with `build-start`", function() {
        sinon.assert.calledWith(bitbundler.emit, "build-start");
      });

      it("then initBuild event handler is called", function() {
        sinon.assert.called(buildInit);
      });

      it("then preBuild event handler is called", function() {
        sinon.assert.called(buildStart);
      });

      it("then postBuild event handler is called", function() {
        sinon.assert.called(buildEnd);
      });
    });
  });

  describe("Given a bundler with a single function notifications configured", function() {
    var notificationStub, initBuildStub, context;

    beforeEach(function() {
      initBuildStub = sinon.stub();
      notificationStub = sinon.stub().returns({ "build-init": initBuildStub });
      createBundler({ notifications: notificationStub });

      sinon.spy(bitbundler, "emit");
      context = createMockContext();
      bitbundler.buildBundles = sinon.stub().resolves(context);

      return bitbundler.bundle(["test/sample/X.js"]);
    });

    it("then the notification function is called", function() {
      sinon.assert.called(notificationStub);
    });

    it("then the registered build-init callback is called", function() {
      sinon.assert.called(initBuildStub);
    });
  });

  describe("Given a bundler with multiple function notifications configured", function() {
    var notificationStub1, notificationStub2, buildInitStub1, buildInitStub2, context;

    beforeEach(function() {
      buildInitStub1 = sinon.stub();
      buildInitStub2 = sinon.stub();
      notificationStub1 = sinon.stub().returns({ "build-init": buildInitStub1 });
      notificationStub2 = sinon.stub().returns({ "build-init": buildInitStub2 });
      createBundler({ notifications: [notificationStub1, notificationStub2] });

      sinon.spy(bitbundler, "emit");
      context = createMockContext();
      bitbundler.buildBundles = sinon.stub().resolves(context);

      return bitbundler.bundle(["test/sample/X.js"]);
    });

    it("then the first notification function is called", function() {
      sinon.assert.called(notificationStub1);
    });

    it("then the second notification function is called", function() {
      sinon.assert.called(notificationStub2);
    });

    it("then the first registered build-init callback is called", function() {
      sinon.assert.called(buildInitStub1);
    });

    it("then the second registered build-init callback is called", function() {
      sinon.assert.called(buildInitStub2);
    });
  });

  describe("Given a bundler with a single notification configured", function() {
    var context, initBuildStub;

    beforeEach(function() {
      initBuildStub = sinon.stub();

      createBundler({
        notifications: {
          "build-init": initBuildStub
        }
      });

      sinon.spy(bitbundler, "emit");
      context = createMockContext();
      bitbundler.buildBundles = sinon.stub().resolves(context);

      return bitbundler.bundle(["test/sample/X.js"]);
    });

    it("then build-init callback is called", function() {
      sinon.assert.called(initBuildStub);
    });
  });
});

function createMockContext() {
  var context = {
    cache: {},
    visitBundles: sinon.stub().returns(context)
  };

  return context;
}

function trimResult(data) {
  return data
    .toString()
    .replace(/\n/g, "")
    .replace(/\/\/# sourceMappingURL=.*/, "");
}

function arrayItemContains(value) {
  return function(array) {
    return array.find(function(str) {
      return str.indexOf(value) !== -1;
    });
  };
}
<commit_msg>updated test spec to use dist instead of dest<commit_after>/*eslint quotes: ["off"]*/

import { expect } from "chai";
import sinon from "sinon";
import BitBundler from "../../src/index";
import loggers from "../../loggers";

describe("BitBundler test suite", function() {
  var createBundler, bitbundler;

  beforeEach(function() {
    createBundler = (config) => bitbundler = new BitBundler(Object.assign({ log: { stream: loggers.through() } }, config || {}));
  });

  describe("When creating a bundler with no configuration", function() {
    beforeEach(function() {
      createBundler();
    });

    it("then the bundler is an instance of Bundler", function() {
      expect(bitbundler).to.be.an.instanceof(BitBundler);
    });

    describe("and bundling a module with a couple of dependencies", function() {
      var result;

      beforeEach(function() {
        return bitbundler.bundle("test/sample/X.js").then(function(ctx) {
          result = ctx;
        });
      });

      it("then result contains the dependencies", function() {
        expect(trimResult(result.bundle.content)).to.be.equal(`require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){/*eslint no-console: ["off"]*/var Y = require("./Y");function X() {  console.log("Say X");  this._y = new Y();}module.exports = new X();},{"./Y":2}],2:[function(require,module,exports){/*eslint no-console: ["off"]*/var z = require("./z");var X = require("./X");function Y() {  console.log(X, typeof X);  console.log("Say Y");  z.potatoes();}module.exports = Y;},{"./X":1,"./z":3}],3:[function(require,module,exports){/*eslint no-console: ["off"]*/module.exports = {  roast: "this",  potatoes: function() {    console.log("Say potatoes");  }};},{}]},{},[1])`);
      });
    });
  });

  describe("When creating a bundler with the JS plugin and spitting bundles", function() {
    beforeEach(function() {
      createBundler({
        bundler: [
          ["bit-bundler-splitter", [
            { dest: "test/dist/Y.js", match: { fileName: "Y.js" }},
            { dest: "test/dist/Z.js", match: { fileName: "z.js" }}]
          ]
        ]
      });
    });

    it("then the bundler is an instance of Bundler", function() {
      expect(bitbundler).to.be.an.instanceof(BitBundler);
    });

    describe("and bundling a module with a couple of dependencies", function() {
      var result;

      beforeEach(function() {
        return bitbundler.bundle("test/sample/X.js").then(function(ctx) {
          result = ctx;
        });
      });

      it("then the result has one root module", function() {
        expect(result.modules).to.have.lengthOf(1);
      });

      it("then the result root module is X.js", function() {
        expect(result.modules[0].fileName).to.be.equal("X.js");
      });

      it("then result contains the dependencies", function() {
        expect(trimResult(result.bundle.content)).to.be.equal(`require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){/*eslint no-console: ["off"]*/var Y = require("./Y");function X() {  console.log("Say X");  this._y = new Y();}module.exports = new X();},{"./Y":2}]},{},[1])`);
      });

      it("then splitter created a shard for 'test/dist/Y.js'", function() {
        expect(result.shards).to.have.property("test/dist/Y.js");
      });

      it("then splitter created a shard for 'test/dist/Y.js' with the correct bundle result", function() {
        expect(trimResult(result.shards["test/dist/Y.js"].content)).to.be.equal(`require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({2:[function(require,module,exports){/*eslint no-console: ["off"]*/var z = require("./z");var X = require("./X");function Y() {  console.log(X, typeof X);  console.log("Say Y");  z.potatoes();}module.exports = Y;},{"./X":1,"./z":3}],3:[function(require,module,exports){/*eslint no-console: ["off"]*/module.exports = {  roast: "this",  potatoes: function() {    console.log("Say potatoes");  }};},{}],1:[function(require,module,exports){/*eslint no-console: ["off"]*/var Y = require("./Y");function X() {  console.log("Say X");  this._y = new Y();}module.exports = new X();},{"./Y":2}]},{},[2])`);
      });

      it("then splitter created a shard for 'test/dist/Z.js'", function() {
        expect(result.shards).to.have.property("test/dist/Z.js");
      });

      it("then splitter created a shard for 'test/dist/Z.js' with the correct bundle result", function() {
        expect(trimResult(result.shards["test/dist/Z.js"].content)).to.be.equal(`require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({3:[function(require,module,exports){/*eslint no-console: ["off"]*/module.exports = {  roast: "this",  potatoes: function() {    console.log("Say potatoes");  }};},{}]},{},[3])`);
      });
    });
  });

  describe("Given a bundler", function() {
    var context, buildInit, buildStart, buildEnd;

    beforeEach(function() {
      createBundler();
      context = createMockContext();
      bitbundler.context = context;

      sinon.spy(bitbundler, "emit");
      bitbundler.buildBundles = sinon.stub().resolves(context);
      bitbundler.loader.hasModule = sinon.stub();
      bitbundler.loader.getModule = sinon.stub();
      bitbundler.loader.deleteModule = sinon.stub();

      buildInit = sinon.stub();
      buildStart = sinon.stub();
      buildEnd = sinon.stub();

      bitbundler
        .on("build-init", buildInit)
        .on("build-start", buildStart)
        .on("build-end", buildEnd);
    });

    describe("And creating a bundle with one files", function() {
      beforeEach(function() {
        return bitbundler.bundle(["test/sample/X.js"]);
      });

      it("then emit is called with `build-init`", function() {
        sinon.assert.calledWith(bitbundler.emit, "build-init");
      });

      it("then emit is called with `build-start`", function() {
        sinon.assert.calledWith(bitbundler.emit, "build-start");
      });

      it("then initBuild event handler is called", function() {
        sinon.assert.called(buildInit);
      });

      it("then preBuild event handler is called", function() {
        sinon.assert.called(buildStart);
      });

      it("then postBuild event handler is called", function() {
        sinon.assert.called(buildEnd);
      });

      it("then loader.hasModule is called", function() {
        sinon.assert.called(bitbundler.loader.hasModule);
      });

      it("then loader.getModule is not called", function() {
        sinon.assert.notCalled(bitbundler.loader.getModule);
      });

      it("then loader.deleteModule is not called", function() {
        sinon.assert.notCalled(bitbundler.loader.deleteModule);
      });

      it("then buildBundles is called with the corresponding file names", function() {
        sinon.assert.calledWith(bitbundler.buildBundles, sinon.match.has("src", sinon.match(arrayItemContains("test/sample/X.js"))));
      });

      it("then visitBundles is called", function() {
        sinon.assert.called(context.visitBundles);
      });
    });

    describe("And updating a bundle with one files", function() {
      var file;

      beforeEach(function() {
        file = new BitBundler.File("test/sample/X.js");
        file.src.forEach((filePath) => bitbundler.loader.hasModule.withArgs(filePath).returns(true));
        return bitbundler.update(file.src);
      });

      it("then emit is called with `build-init`", function() {
        sinon.assert.neverCalledWith(bitbundler.emit, "build-init");
      });

      it("then emit is called with `build-start`", function() {
        sinon.assert.calledWith(bitbundler.emit, "build-start");
      });

      it("then initBuild event handler is NOT called", function() {
        sinon.assert.notCalled(buildInit);
      });

      it("then preBuild event handler is called", function() {
        sinon.assert.called(buildStart);
      });

      it("then postBuild event handler is called", function() {
        sinon.assert.called(buildEnd);
      });

      it("then loader.hasModule is called", function() {
        sinon.assert.called(bitbundler.loader.hasModule);
      });

      it("then loader.getModule is called", function() {
        sinon.assert.called(bitbundler.loader.getModule);
      });

      it("then loader.deleteModule is called", function() {
        sinon.assert.called(bitbundler.loader.deleteModule);
      });

      it("then buildBundles is called with the corresponding file names", function() {
        sinon.assert.calledWith(bitbundler.buildBundles, sinon.match.has("src", sinon.match(arrayItemContains("test/sample/X.js"))));
      });

      it("then visitBundles is called", function() {
        sinon.assert.called(context.visitBundles);
      });
    });

    describe("And bundling fails", function() {
      beforeEach(function() {
        bitbundler.buildBundles = sinon.stub().rejects("bad");
        return bitbundler.bundle(["test/sample/X.js"]).catch(function() {});
      });

      it("then emit is called with `build-init`", function() {
        sinon.assert.calledWith(bitbundler.emit, "build-init");
      });

      it("then emit is called with `build-start`", function() {
        sinon.assert.calledWith(bitbundler.emit, "build-start");
      });

      it("then initBuild event handler is called", function() {
        sinon.assert.called(buildInit);
      });

      it("then preBuild event handler is called", function() {
        sinon.assert.called(buildStart);
      });

      it("then postBuild event handler is called", function() {
        sinon.assert.called(buildEnd);
      });
    });
  });

  describe("Given a bundler with a single function notifications configured", function() {
    var notificationStub, initBuildStub, context;

    beforeEach(function() {
      initBuildStub = sinon.stub();
      notificationStub = sinon.stub().returns({ "build-init": initBuildStub });
      createBundler({ notifications: notificationStub });

      sinon.spy(bitbundler, "emit");
      context = createMockContext();
      bitbundler.buildBundles = sinon.stub().resolves(context);

      return bitbundler.bundle(["test/sample/X.js"]);
    });

    it("then the notification function is called", function() {
      sinon.assert.called(notificationStub);
    });

    it("then the registered build-init callback is called", function() {
      sinon.assert.called(initBuildStub);
    });
  });

  describe("Given a bundler with multiple function notifications configured", function() {
    var notificationStub1, notificationStub2, buildInitStub1, buildInitStub2, context;

    beforeEach(function() {
      buildInitStub1 = sinon.stub();
      buildInitStub2 = sinon.stub();
      notificationStub1 = sinon.stub().returns({ "build-init": buildInitStub1 });
      notificationStub2 = sinon.stub().returns({ "build-init": buildInitStub2 });
      createBundler({ notifications: [notificationStub1, notificationStub2] });

      sinon.spy(bitbundler, "emit");
      context = createMockContext();
      bitbundler.buildBundles = sinon.stub().resolves(context);

      return bitbundler.bundle(["test/sample/X.js"]);
    });

    it("then the first notification function is called", function() {
      sinon.assert.called(notificationStub1);
    });

    it("then the second notification function is called", function() {
      sinon.assert.called(notificationStub2);
    });

    it("then the first registered build-init callback is called", function() {
      sinon.assert.called(buildInitStub1);
    });

    it("then the second registered build-init callback is called", function() {
      sinon.assert.called(buildInitStub2);
    });
  });

  describe("Given a bundler with a single notification configured", function() {
    var context, initBuildStub;

    beforeEach(function() {
      initBuildStub = sinon.stub();

      createBundler({
        notifications: {
          "build-init": initBuildStub
        }
      });

      sinon.spy(bitbundler, "emit");
      context = createMockContext();
      bitbundler.buildBundles = sinon.stub().resolves(context);

      return bitbundler.bundle(["test/sample/X.js"]);
    });

    it("then build-init callback is called", function() {
      sinon.assert.called(initBuildStub);
    });
  });
});

function createMockContext() {
  var context = {
    cache: {},
    visitBundles: sinon.stub().returns(context)
  };

  return context;
}

function trimResult(data) {
  return data
    .toString()
    .replace(/\n/g, "")
    .replace(/\/\/# sourceMappingURL=.*/, "");
}

function arrayItemContains(value) {
  return function(array) {
    return array.find(function(str) {
      return str.indexOf(value) !== -1;
    });
  };
}
<|endoftext|>


<commit_before>'use strict';
require('mocha');
require('co-mocha');
const chai = require('chai');
const assert = require('chai').assert;

const r = require('rethinkdbdash')({
    db: process.env.MCDB || 'materialscommons',
    port: process.env.MCDB_PORT || 30815
});

const backend_base = '../../../..';
const dbModelUsers = require(backend_base + '/servers/mcapi/db/model/users');
const samples = require(backend_base + '/servers/mcapi/db/model/samples');

const testHelpers = require('./test-helpers');

const baseProjectName = "Test samples - ";

let random_name = function(){
    let number = Math.floor(Math.random()*10000);
    return baseProjectName + number;
};

let userId = 'test@test.mc';
let sample1 = null;
let sample2 = null;
let experiment = null;
let createSampleProcess = null;
let transformationProcess = null;

before(function*() {
    let user = yield dbModelUsers.getUser(userId);
    assert.isOk(user);

    // create a project
    let projectName = random_name();
    let results = yield testHelpers.createProject(projectName,user);
    assert.isOk(results.val);
    let project = results.val;
    assert.equal(project.otype, "project");
    assert.equal(project.name, projectName);
    assert.equal(project.owner, user.id);
    assert.equal(project.owner, userId);
    assert.equal(project.users.length,1);
    assert.equal(project.users[0].user_id, userId);

    console.log("project name: ", projectName);

    // create an experiment
    let experimentName = "Experment For Test";
    results = yield testHelpers.createExperiment(project,experimentName);
    assert.isOk(results.val);
    experiment = results.val;
    assert.equal(experiment.otype,'experiment');
    assert.equal(experiment.name, experimentName);
    assert.equal(experiment.owner, userId);

    // add a create sample process to it
    let processName = "Create Sample - test process";
    let processTemplateId = "global_Create Samples";
    results = yield testHelpers.createProcess(project,experiment,processName,processTemplateId);
    assert.isOk(results.val);
    createSampleProcess = results.val;
    assert.equal(createSampleProcess.otype,'process');
    assert.equal(createSampleProcess.name, processName);
    assert.equal(createSampleProcess.template_id, processTemplateId);
    assert.equal(createSampleProcess.owner, userId);
    assert.equal(createSampleProcess.process_type, 'create');

    // create a sample set
    let sampleName1 = "Sample1 For Test";
    let sampleName2 = "Sample2 For Test";
    results = yield testHelpers.createSamples(project,experiment,createSampleProcess,[sampleName1, sampleName2]);
    assert.isOk(results.val);
    assert.isOk(results.val.samples);
    let samples = results.val.samples;
    assert.isOk(samples);
    assert.equal(samples.length, 2);
    sample1 = samples[0];
    assert.isOk(sample1);
    assert.equal(sample1.otype,'sample');
    assert.equal(sample1.name, sampleName1);
    sample2 = samples[1];
    assert.isOk(sample2);
    assert.equal(sample2.otype,'sample');
    assert.equal(sample2.name, sampleName2);

    // add a transformation process to it
    processName = "Etching - test process";
    processTemplateId = "global_Etching";
    results = yield testHelpers.createProcess(project,experiment,processName,processTemplateId);
    assert.isOk(results.val);
    transformationProcess = results.val;
    assert.equal(transformationProcess.otype,'process');
    assert.equal(transformationProcess.name, processName);
    assert.equal(transformationProcess.template_id, processTemplateId);
    assert.equal(transformationProcess.owner, userId);

    // add samples for that process
    results = yield testHelpers.addSamplesToProcess(project,experiment,transformationProcess,[sample1]);
    assert.isOk(results.val);
    let checkProcess = results.val;
    assert.equal(checkProcess.otype,'process');
    assert.equal(checkProcess.name, processName);
    assert.equal(checkProcess.template_id, processTemplateId);
    assert.equal(checkProcess.owner, userId);
    assert.equal(checkProcess.process_type, 'transform');
    assert.equal(checkProcess.input_samples[0].id,sample1.id);
    assert.equal(checkProcess.output_samples[0].id,sample1.id);

});

describe('Feature - Samples: ', function() {
    describe('Get Samples', function () {
        it('get samples by id', function*() {
            let results = yield samples.getSample(sample1.id);
            assert.isOk(results.val);
            let sample = results.val;
            assert.equal(sample.otype, 'sample');
            assert.equal(sample.name, sample1.name);
            let experiments = sample.experiments;
            assert.equal(experiments.length, 1);
            assert.equal(experiments[0].id,experiment.id);
            let processes = sample.processes;
            assert.equal(processes.length, 3);
            let checks = [
                {name: createSampleProcess.name, direction: 'out'},
                {name: transformationProcess.name, direction: 'in'},
                {name: transformationProcess.name, direction: 'out'}
            ];
            for (let c = 0; c < checks.length; c++) {
                let name = checks[c].name;
                let direction = checks[c].direction;
                let found = false;
                for (let i = 0; i < processes.length; i++) {
                    if (name === processes[i].name && direction === processes[i].direction) {
                        found = true;
                    }
                }
                assert(found, `Missing process for sample ${sample1.name}: expected name = '${name}' with direction '${direction}'`)
            }
        });

        it('gets all samples for experiment', function*() {
            // let results = yield samples.getAllSamplesForExperiment(experiment.id);
            // console.log(results);
            // assert.isOk(results.val);
            // let sampleList = results.val;
            // assert.equal(sampleList.length,2);
        });
        it('gets all samples for project', function*() {});
    });
});
<commit_msg>Tests for creat and get samples; working<commit_after>'use strict';
require('mocha');
require('co-mocha');
const chai = require('chai');
const assert = require('chai').assert;

const r = require('rethinkdbdash')({
    db: process.env.MCDB || 'materialscommons',
    port: process.env.MCDB_PORT || 30815
});

const backend_base = '../../../..';
const dbModelUsers = require(backend_base + '/servers/mcapi/db/model/users');
const samples = require(backend_base + '/servers/mcapi/db/model/samples');

const testHelpers = require('./test-helpers');

const baseProjectName = "Test samples - ";

let random_name = function(){
    let number = Math.floor(Math.random()*10000);
    return baseProjectName + number;
};

let userId = 'test@test.mc';
let sample1 = null;
let sample2 = null;
let project = null;
let experiment = null;
let createSampleProcess = null;
let transformationProcess1 = null;
let transformationProcess2 = null;

before(function*() {
    let user = yield dbModelUsers.getUser(userId);
    assert.isOk(user);

    // create a project
    let projectName = random_name();
    let results = yield testHelpers.createProject(projectName,user);
    assert.isOk(results.val);
    project = results.val;
    assert.equal(project.otype, "project");
    assert.equal(project.name, projectName);
    assert.equal(project.owner, user.id);
    assert.equal(project.owner, userId);
    assert.equal(project.users.length,1);
    assert.equal(project.users[0].user_id, userId);

    console.log("project name: ", projectName);

    // create an experiment
    let experimentName = "Experment For Test";
    results = yield testHelpers.createExperiment(project,experimentName);
    assert.isOk(results.val);
    experiment = results.val;
    assert.equal(experiment.otype,'experiment');
    assert.equal(experiment.name, experimentName);
    assert.equal(experiment.owner, userId);

    // add a create sample process to it
    let processName = "Create Sample - test process";
    let processTemplateId = "global_Create Samples";
    results = yield testHelpers.createProcess(project,experiment,processName,processTemplateId);
    assert.isOk(results.val);
    createSampleProcess = results.val;
    assert.equal(createSampleProcess.otype,'process');
    assert.equal(createSampleProcess.name, processName);
    assert.equal(createSampleProcess.template_id, processTemplateId);
    assert.equal(createSampleProcess.owner, userId);
    assert.equal(createSampleProcess.process_type, 'create');

    // create a sample set
    let sampleName1 = "Sample1 For Test";
    let sampleName2 = "Sample2 For Test";
    results = yield testHelpers.createSamples(project,experiment,createSampleProcess,[sampleName1, sampleName2]);
    assert.isOk(results.val);
    assert.isOk(results.val.samples);
    let samples = results.val.samples;
    assert.isOk(samples);
    assert.equal(samples.length, 2);
    sample1 = samples[0];
    assert.isOk(sample1);
    assert.equal(sample1.otype,'sample');
    assert.equal(sample1.name, sampleName1);
    sample2 = samples[1];
    assert.isOk(sample2);
    assert.equal(sample2.otype,'sample');
    assert.equal(sample2.name, sampleName2);

    // add a transformation process
    processName = "Etching1 - test process";
    processTemplateId = "global_Etching";
    results = yield testHelpers.createProcess(project,experiment,processName,processTemplateId);
    assert.isOk(results.val);
    transformationProcess1 = results.val;
    assert.equal(transformationProcess1.otype,'process');
    assert.equal(transformationProcess1.name, processName);
    assert.equal(transformationProcess1.template_id, processTemplateId);
    assert.equal(transformationProcess1.owner, userId);

    // add a sample to that process
    results = yield testHelpers.addSamplesToProcess(project,experiment,transformationProcess1,[sample1]);
    assert.isOk(results.val);
    let checkProcess = results.val;
    assert.equal(checkProcess.otype,'process');
    assert.equal(checkProcess.name, processName);
    assert.equal(checkProcess.template_id, processTemplateId);
    assert.equal(checkProcess.owner, userId);
    assert.equal(checkProcess.process_type, 'transform');
    assert.equal(checkProcess.input_samples[0].id,sample1.id);
    assert.equal(checkProcess.output_samples[0].id,sample1.id);

    // add a another transformation process
    processName = "Etching2 - test process";
    processTemplateId = "global_Etching";
    results = yield testHelpers.createProcess(project,experiment,processName,processTemplateId);
    assert.isOk(results.val);
    transformationProcess2 = results.val;
    assert.equal(transformationProcess2.otype,'process');
    assert.equal(transformationProcess2.name, processName);
    assert.equal(transformationProcess2.template_id, processTemplateId);
    assert.equal(transformationProcess2.owner, userId);

    // add the other sample to that process
    results = yield testHelpers.addSamplesToProcess(project,experiment,transformationProcess2,[sample2]);
    assert.isOk(results.val);
    checkProcess = results.val;
    assert.equal(checkProcess.otype,'process');
    assert.equal(checkProcess.name, processName);
    assert.equal(checkProcess.template_id, processTemplateId);
    assert.equal(checkProcess.owner, userId);
    assert.equal(checkProcess.process_type, 'transform');
    assert.equal(checkProcess.input_samples[0].id,sample2.id);
    assert.equal(checkProcess.output_samples[0].id,sample2.id);
});

describe('Feature - Samples: ', function() {
    describe('Get Samples', function () {
        it('get samples by id', function*() {
            let results = yield samples.getSample(sample1.id);
            assert.isOk(results.val);
            let sample = results.val;
            assert.equal(sample.otype, 'sample');
            assert.equal(sample.name, sample1.name);
            let experiments = sample.experiments;
            assert.equal(experiments.length, 1);
            assert.equal(experiments[0].id,experiment.id);
            let processes = sample.processes;
            assert.equal(processes.length, 3);
            let checks = [
                {name: createSampleProcess.name, direction: 'out'},
                {name: transformationProcess1.name, direction: 'in'},
                {name: transformationProcess1.name, direction: 'out'}
            ];
            for (let c = 0; c < checks.length; c++) {
                let name = checks[c].name;
                let direction = checks[c].direction;
                let found = false;
                for (let i = 0; i < processes.length; i++) {
                    if (name === processes[i].name && direction === processes[i].direction) {
                        found = true;
                    }
                }
                assert(found, `Missing process for sample ${sample1.name}: expected name = '${name}' with direction '${direction}'`)
            }
        });

        it('gets all samples for experiment', function*() {
            let results = yield samples.getAllSamplesForExperiment(experiment.id);
            assert.isOk(results.val);
            let sampleList = results.val;
            assert.equal(sampleList.length,2);
            let testTable = {};
            for (let i = 0; i < sampleList.length; i++) {
                testTable[sampleList[i].id] = sampleList[i];
            }
            assert.isOk(testTable[sample1.id]);
            assert.equal(testTable[sample1.id].name, sample1.name);
            assert.isOk(testTable[sample2.id]);
            assert.equal(testTable[sample2.id].name, sample2.name);
        });
        it('gets all samples for project', function*() {
            let results = yield samples.getAllSamplesForProject(project.id);
            assert.isOk(results.val);
            let sampleList = results.val;
            assert.equal(sampleList.length,2);
            let testTable = {};
            for (let i = 0; i < sampleList.length; i++) {
                testTable[sampleList[i].id] = sampleList[i];
            }
            assert.isOk(testTable[sample1.id]);
            assert.equal(testTable[sample1.id].name, sample1.name);
            assert.isOk(testTable[sample2.id]);
            assert.equal(testTable[sample2.id].name, sample2.name);
        });
    });
});
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

// VERSION 2.7.5
Modules.UTILS = true;
Modules.BASEUTILS = true;

// xmlHttpRequest(url, callback, method) - aid for quickly using the nsIXMLHttpRequest interface
//	url - (string) to send the request
//	callback - (function) to be called after request is completed; expects callback(xmlhttp, e) where xmlhttp = xmlhttprequest return object and e = event object
//	(optional) method -	either (string) "POST" or (string) "GET"; defaults to "GET";
//				can also be (string) "JSON", for XHR operations that fetch a JSON object, so the result should be parsed accordingly,
//				in which case the method used is "GET" as well.
this.xmlHttpRequest = function(url, callback, method = "GET") {
	var json = false;
	if(method == "JSON") {
		json = true;
		method = "GET";
	}

	var xmlhttp = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest);
	xmlhttp.open(method, url);
	if(json) {
		xmlhttp.overrideMimeType("application/json");
		xmlhttp.responseType = 'json';
	}
	xmlhttp.onreadystatechange = function(e) { callback(xmlhttp, e); };
	xmlhttp.send();
	return xmlhttp;
};

// aSync(aFunc, aDelay) - lets me run aFunc asynchronously, basically it's a one shot timer with a delay of aDelay msec
//	aFunc - (function) to be called asynchronously
//	(optional) aDelay - (int) msec to set the timer, defaults to 0msec
this.aSync = function(aFunc, aDelay) {
	var newTimer = {
		timer: Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer),
		handler: aFunc,
		cancel: function() {
			this.timer.cancel();
		}
	};
	newTimer.timer.init(newTimer.handler, (!aDelay) ? 0 : aDelay, Ci.nsITimer.TYPE_ONE_SHOT);
	return newTimer;
};

// dispatch(obj, properties) - creates and dispatches an event and returns (bool) whether preventDefault was not called on it
//	aNode - (xul element) object to dispatch the event from, it will be e.target
//	props - (obj) expecting the following sub properties defining the following event characteristics:
//		type - (str) the event type
//		(optional) bubbles - (bool) defaults to true
//		(optional) cancelable - (bool) defaults to true
//		(optional) detail - to be passed to the event
//		(optional) asking - (bool) if true, will return the .detail property of the event, which can be modified by listeners; defaults to false, .detail defaults to undefined
this.dispatch = function(aNode, props) {
	if(!aNode || !aNode.dispatchEvent
	|| (!aNode.ownerDocument && !aNode.document && (!aNode.content || !aNode.content.document))
	|| !props || !props.type) { return false; }

	var bubbles = props.bubbles || true;
	var cancelable = props.cancelable || !props.asking;
	var detail = props.detail || undefined;

	var doc = (aNode.ownerDocument) ? aNode.ownerDocument : (aNode.document) ? aNode.document : aNode.content.document; // last one's for content processes
	var event = doc.createEvent('CustomEvent');

	if(props.asking) {
		event.__defineGetter__('detail', function() { return detail; });
		event.__defineSetter__('detail', function(v) { return detail = v; });
	}

	event.initCustomEvent(props.type, bubbles, cancelable, detail);
	var ret = aNode.dispatchEvent(event);
	return (props.asking) ? detail : ret;
};

// isAncestor(aNode, aParent) - Checks if aNode decends from aParent
//	aNode - (xul element) node to check for ancestry
//	aParent - (xul element) node to check if ancestor of aNode
//	(dont set) aWindow - to be used internally by isAncestor()
this.isAncestor = function(aNode, aParent, aWindow) {
	if(!aNode || !aParent) { return false; };

	if(aNode == aParent) { return true; }

	let ownDocument = aNode.ownerDocument || aNode.document;
	if(ownDocument && ownDocument == aParent) { return true; }
	if(aNode.compareDocumentPosition && (aNode.compareDocumentPosition(aParent) & aNode.DOCUMENT_POSITION_CONTAINS)) { return true; }

	if(aParent.nodeType == aParent.ELEMENT_NODE) {
		let browserNodes = (aParent.tagName == 'browser') ? [aParent] : aParent.getElementsByTagName('browser');
		for(let browser of browserNodes) {
			try { if(!browser.isRemoteBrowser && isAncestor(aNode, browser.contentDocument, browser.contentWindow)) { return true; } }
			catch(ex) { /* this will fail in e10s if comparing a node from a non-remote document to a remote parent, which means we don't care either way */ }
		}
	}

	if(!aWindow) { return false; }
	for(var frame of aWindow.frames) {
		if(isAncestor(aNode, frame.document, frame)) { return true; }
	}
	return false;
};

// trim(str) - trims whitespaces from a string (found in http://blog.stevenlevithan.com/archives/faster-trim-javascript -> trim3())
//	str - (string) to trim
this.trim = function(str) {
	if(typeof(str) != 'string') {
		return '';
	}

	return str.substring(Math.max(str.search(/\S/), 0), str.search(/\S\s*$/) + 1);
};

// replaceObjStrings(node, prop) - replace all objName and objPathString references in the node attributes and its children with the proper names
//	node - (xul element) to replace the strings in
//	(optional) prop -	(string) if specified, instead of checking attributes, it will check for node.prop for occurences of what needs to be replaced.
//				When specified, this method is not recursive, it will not check child nodes!
this.replaceObjStrings = function(node, prop) {
	if(!node) { return; }

	if(prop) {
		if(!node[prop]) { return; }

		while(node[prop].includes('objName')) {
			node[prop] = node[prop].replace('objName', objName);
		}
		while(node[prop].includes('objPathString')) {
			node[prop] = node[prop].replace('objPathString', objPathString);
		}

		return;
	}

	if(node.attributes) {
		for(let attr of node.attributes) {
			while(attr.value.includes('objName')) {
				attr.value = attr.value.replace('objName', objName);
			}
			while(attr.value.includes('objPathString')) {
				attr.value = attr.value.replace('objPathString', objPathString);
			}
		}
	}

	var curChild = node.firstChild;
	while(curChild) {
		replaceObjStrings(curChild);
		curChild = curChild.nextSibling;
	}
};

// getComputedStyle(aNode, pseudo) - returns the resulting object from calling the equivalent window.getComputedStyle() on it
//	aNode - (element) of which to return the computed style object
//	(optional) pseudo -(string) specifying the pseudo-element to match, see https://developer.mozilla.org/en-US/docs/Web/API/Window.getComputedStyle
this.getComputedStyle = function(aNode, pseudo) {
	return aNode.ownerDocument.defaultView.getComputedStyle(aNode, pseudo);
};
<commit_msg>keep aSync timers referenced so they aren't forgotten by GCs<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

// VERSION 2.7.6
Modules.UTILS = true;
Modules.BASEUTILS = true;

// xmlHttpRequest(url, callback, method) - aid for quickly using the nsIXMLHttpRequest interface
//	url - (string) to send the request
//	callback - (function) to be called after request is completed; expects callback(xmlhttp, e) where xmlhttp = xmlhttprequest return object and e = event object
//	(optional) method -	either (string) "POST" or (string) "GET"; defaults to "GET";
//				can also be (string) "JSON", for XHR operations that fetch a JSON object, so the result should be parsed accordingly,
//				in which case the method used is "GET" as well.
this.xmlHttpRequest = function(url, callback, method = "GET") {
	var json = false;
	if(method == "JSON") {
		json = true;
		method = "GET";
	}

	var xmlhttp = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest);
	xmlhttp.open(method, url);
	if(json) {
		xmlhttp.overrideMimeType("application/json");
		xmlhttp.responseType = 'json';
	}
	xmlhttp.onreadystatechange = function(e) { callback(xmlhttp, e); };
	xmlhttp.send();
	return xmlhttp;
};

// A collection of timers created by the aSync method below. Sometimes these timers "forget" to fire if their instances aren't held anywhere.
// So we keep a collection here to make sure they always fire as necessary.
this._aSyncTimers = new Set();

// aSync(aCallback, aDelay) - runs aCallback asynchronously, basically it's a one shot timer with a delay of aDelay msec
//	aCallback - (function) to be called asynchronously
//	(optional) aDelay - (int) msec to set the timer, defaults to 0msec
this.aSync = function(aCallback, aDelay) {
	let newTimer = {
		timer: Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer),
		callback: aCallback,
		clean: function() {
			_aSyncTimers.delete(this);
		},
		handler: function() {
			this.clean();
			this.callback();
		},
		cancel: function() {
			this.timer.cancel();
			this.clean();
		}
	};
	_aSyncTimers.add(newTimer);
	newTimer.timer.init(function() { newTimer.handler(); }, (!aDelay) ? 0 : aDelay, Ci.nsITimer.TYPE_ONE_SHOT);
	return newTimer;
};

// dispatch(obj, properties) - creates and dispatches an event and returns (bool) whether preventDefault was not called on it
//	aNode - (xul element) object to dispatch the event from, it will be e.target
//	props - (obj) expecting the following sub properties defining the following event characteristics:
//		type - (str) the event type
//		(optional) bubbles - (bool) defaults to true
//		(optional) cancelable - (bool) defaults to true
//		(optional) detail - to be passed to the event
//		(optional) asking - (bool) if true, will return the .detail property of the event, which can be modified by listeners; defaults to false, .detail defaults to undefined
this.dispatch = function(aNode, props) {
	if(!aNode || !aNode.dispatchEvent
	|| (!aNode.ownerDocument && !aNode.document && (!aNode.content || !aNode.content.document))
	|| !props || !props.type) { return false; }

	var bubbles = props.bubbles || true;
	var cancelable = props.cancelable || !props.asking;
	var detail = props.detail || undefined;

	var doc = (aNode.ownerDocument) ? aNode.ownerDocument : (aNode.document) ? aNode.document : aNode.content.document; // last one's for content processes
	var event = doc.createEvent('CustomEvent');

	if(props.asking) {
		event.__defineGetter__('detail', function() { return detail; });
		event.__defineSetter__('detail', function(v) { return detail = v; });
	}

	event.initCustomEvent(props.type, bubbles, cancelable, detail);
	var ret = aNode.dispatchEvent(event);
	return (props.asking) ? detail : ret;
};

// isAncestor(aNode, aParent) - Checks if aNode decends from aParent
//	aNode - (xul element) node to check for ancestry
//	aParent - (xul element) node to check if ancestor of aNode
//	(dont set) aWindow - to be used internally by isAncestor()
this.isAncestor = function(aNode, aParent, aWindow) {
	if(!aNode || !aParent) { return false; };

	if(aNode == aParent) { return true; }

	let ownDocument = aNode.ownerDocument || aNode.document;
	if(ownDocument && ownDocument == aParent) { return true; }
	if(aNode.compareDocumentPosition && (aNode.compareDocumentPosition(aParent) & aNode.DOCUMENT_POSITION_CONTAINS)) { return true; }

	if(aParent.nodeType == aParent.ELEMENT_NODE) {
		let browserNodes = (aParent.tagName == 'browser') ? [aParent] : aParent.getElementsByTagName('browser');
		for(let browser of browserNodes) {
			try { if(!browser.isRemoteBrowser && isAncestor(aNode, browser.contentDocument, browser.contentWindow)) { return true; } }
			catch(ex) { /* this will fail in e10s if comparing a node from a non-remote document to a remote parent, which means we don't care either way */ }
		}
	}

	if(!aWindow) { return false; }
	for(var frame of aWindow.frames) {
		if(isAncestor(aNode, frame.document, frame)) { return true; }
	}
	return false;
};

// trim(str) - trims whitespaces from a string (found in http://blog.stevenlevithan.com/archives/faster-trim-javascript -> trim3())
//	str - (string) to trim
this.trim = function(str) {
	if(typeof(str) != 'string') {
		return '';
	}

	return str.substring(Math.max(str.search(/\S/), 0), str.search(/\S\s*$/) + 1);
};

// replaceObjStrings(node, prop) - replace all objName and objPathString references in the node attributes and its children with the proper names
//	node - (xul element) to replace the strings in
//	(optional) prop -	(string) if specified, instead of checking attributes, it will check for node.prop for occurences of what needs to be replaced.
//				When specified, this method is not recursive, it will not check child nodes!
this.replaceObjStrings = function(node, prop) {
	if(!node) { return; }

	if(prop) {
		if(!node[prop]) { return; }

		while(node[prop].includes('objName')) {
			node[prop] = node[prop].replace('objName', objName);
		}
		while(node[prop].includes('objPathString')) {
			node[prop] = node[prop].replace('objPathString', objPathString);
		}

		return;
	}

	if(node.attributes) {
		for(let attr of node.attributes) {
			while(attr.value.includes('objName')) {
				attr.value = attr.value.replace('objName', objName);
			}
			while(attr.value.includes('objPathString')) {
				attr.value = attr.value.replace('objPathString', objPathString);
			}
		}
	}

	var curChild = node.firstChild;
	while(curChild) {
		replaceObjStrings(curChild);
		curChild = curChild.nextSibling;
	}
};

// getComputedStyle(aNode, pseudo) - returns the resulting object from calling the equivalent window.getComputedStyle() on it
//	aNode - (element) of which to return the computed style object
//	(optional) pseudo -(string) specifying the pseudo-element to match, see https://developer.mozilla.org/en-US/docs/Web/API/Window.getComputedStyle
this.getComputedStyle = function(aNode, pseudo) {
	return aNode.ownerDocument.defaultView.getComputedStyle(aNode, pseudo);
};
<|endoftext|>


<commit_before>import { assert } from 'ember-metal/debug';
import isEnabled from 'ember-metal/features';
import { _getPath as getPath } from 'ember-metal/property_get';
import {
  PROPERTY_DID_CHANGE,
  propertyWillChange,
  propertyDidChange
} from 'ember-metal/property_events';
import { defineProperty } from 'ember-metal/properties';
import EmberError from 'ember-metal/error';
import {
  isPath,
  hasThis as pathHasThis
} from 'ember-metal/path_cache';
import {
  peekMeta
} from 'ember-metal/meta';

import {
  lookupDescriptor
} from 'ember-metal/utils';

/**
  Sets the value of a property on an object, respecting computed properties
  and notifying observers and other listeners of the change. If the
  property is not defined but the object implements the `setUnknownProperty`
  method then that will be invoked as well.

  @method set
  @for Ember
  @param {Object} obj The object to modify.
  @param {String} keyName The property key to set
  @param {Object} value The value to set
  @return {Object} the passed value.
  @public
*/
export function set(obj, keyName, value, tolerant) {
  assert(
    `Set must be called with three or four arguments; an object, a property key, a value and tolerant true/false`,
    arguments.length === 3 || arguments.length === 4
  );
  assert(`Cannot call set with '${keyName}' on an undefined object.`, obj !== undefined && obj !== null);
  assert(`The key provided to set must be a string, you passed ${keyName}`, typeof keyName === 'string');
  assert(`'this' in paths is not supported`, !pathHasThis(keyName));

  var meta, possibleDesc, desc;
  if (obj) {
    meta = peekMeta(obj);
    possibleDesc = obj[keyName];
    desc = (possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor) ? possibleDesc : undefined;
  }

  var isUnknown, currentValue;
  if (desc === undefined && isPath(keyName)) {
    return setPath(obj, keyName, value, tolerant);
  }

  assert('calling set on destroyed object', !obj.isDestroyed);

  if (desc) {
    desc.set(obj, keyName, value);
  } else {
    if (value !== undefined && typeof obj === 'object' && obj[keyName] === value) {
      return value;
    }

    isUnknown = 'object' === typeof obj && !(keyName in obj);

    // setUnknownProperty is called if `obj` is an object,
    // the property does not already exist, and the
    // `setUnknownProperty` method exists on the object
    if (isUnknown && 'function' === typeof obj.setUnknownProperty) {
      obj.setUnknownProperty(keyName, value);
    } else if (meta && meta.peekWatching(keyName) > 0) {
      if (meta.proto !== obj) {
        if (isEnabled('mandatory-setter')) {
          currentValue = meta.peekValues(keyName);
        } else {
          currentValue = obj[keyName];
        }
      }
      // only trigger a change if the value has changed
      if (value !== currentValue) {
        propertyWillChange(obj, keyName);

        if (isEnabled('mandatory-setter')) {
          if ((currentValue === undefined && !(keyName in obj)) ||
            !Object.prototype.propertyIsEnumerable.call(obj, keyName)
          ) {
            defineProperty(obj, keyName, null, value); // setup mandatory setter
          } else {
            let descriptor = lookupDescriptor(obj, keyName);
            let isMandatorySetter = descriptor && descriptor.set && descriptor.set.isMandatorySetter;
            if (isMandatorySetter) {
              meta.writeValues(keyName, value);
            } else {
              obj[keyName] = value;
            }
          }
        } else {
          obj[keyName] = value;
        }
        propertyDidChange(obj, keyName);
      }
    } else {
      obj[keyName] = value;
      if (obj[PROPERTY_DID_CHANGE]) {
        obj[PROPERTY_DID_CHANGE](keyName);
      }
    }
  }
  return value;
}

function setPath(root, path, value, tolerant) {
  var keyName;

  // get the last part of the path
  keyName = path.slice(path.lastIndexOf('.') + 1);

  // get the first part of the part
  path    = (path === keyName) ? keyName : path.slice(0, path.length - (keyName.length + 1));

  // unless the path is this, look up the first part to
  // get the root
  if (path !== 'this') {
    root = getPath(root, path);
  }

  if (!keyName || keyName.length === 0) {
    throw new EmberError('Property set failed: You passed an empty path');
  }

  if (!root) {
    if (tolerant) {
      return;
    } else {
      throw new EmberError('Property set failed: object in path "' + path + '" could not be found or was destroyed.');
    }
  }

  return set(root, keyName, value);
}

/**
  Error-tolerant form of `Ember.set`. Will not blow up if any part of the
  chain is `undefined`, `null`, or destroyed.

  This is primarily used when syncing bindings, which may try to update after
  an object has been destroyed.

  @method trySet
  @for Ember
  @param {Object} root The object to modify.
  @param {String} path The property path to set
  @param {Object} value The value to set
  @public
*/
export function trySet(root, path, value) {
  return set(root, path, value, true);
}
<commit_msg>[BUGFIX beta] remove redundant code (already the default M getter)<commit_after>import { assert } from 'ember-metal/debug';
import isEnabled from 'ember-metal/features';
import { _getPath as getPath } from 'ember-metal/property_get';
import {
  PROPERTY_DID_CHANGE,
  propertyWillChange,
  propertyDidChange
} from 'ember-metal/property_events';
import { defineProperty } from 'ember-metal/properties';
import EmberError from 'ember-metal/error';
import {
  isPath,
  hasThis as pathHasThis
} from 'ember-metal/path_cache';
import {
  peekMeta
} from 'ember-metal/meta';

import {
  lookupDescriptor
} from 'ember-metal/utils';

/**
  Sets the value of a property on an object, respecting computed properties
  and notifying observers and other listeners of the change. If the
  property is not defined but the object implements the `setUnknownProperty`
  method then that will be invoked as well.

  @method set
  @for Ember
  @param {Object} obj The object to modify.
  @param {String} keyName The property key to set
  @param {Object} value The value to set
  @return {Object} the passed value.
  @public
*/
export function set(obj, keyName, value, tolerant) {
  assert(
    `Set must be called with three or four arguments; an object, a property key, a value and tolerant true/false`,
    arguments.length === 3 || arguments.length === 4
  );
  assert(`Cannot call set with '${keyName}' on an undefined object.`, obj !== undefined && obj !== null);
  assert(`The key provided to set must be a string, you passed ${keyName}`, typeof keyName === 'string');
  assert(`'this' in paths is not supported`, !pathHasThis(keyName));

  var meta, possibleDesc, desc;
  if (obj) {
    meta = peekMeta(obj);
    possibleDesc = obj[keyName];
    desc = (possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor) ? possibleDesc : undefined;
  }

  var isUnknown, currentValue;
  if (desc === undefined && isPath(keyName)) {
    return setPath(obj, keyName, value, tolerant);
  }

  assert('calling set on destroyed object', !obj.isDestroyed);

  if (desc) {
    desc.set(obj, keyName, value);
  } else {
    if (value !== undefined && typeof obj === 'object' && obj[keyName] === value) {
      return value;
    }

    isUnknown = 'object' === typeof obj && !(keyName in obj);

    // setUnknownProperty is called if `obj` is an object,
    // the property does not already exist, and the
    // `setUnknownProperty` method exists on the object
    if (isUnknown && 'function' === typeof obj.setUnknownProperty) {
      obj.setUnknownProperty(keyName, value);
    } else if (meta && meta.peekWatching(keyName) > 0) {
      if (meta.proto !== obj) {
        currentValue = obj[keyName];
      }
      // only trigger a change if the value has changed
      if (value !== currentValue) {
        propertyWillChange(obj, keyName);

        if (isEnabled('mandatory-setter')) {
          if ((currentValue === undefined && !(keyName in obj)) ||
            !Object.prototype.propertyIsEnumerable.call(obj, keyName)
          ) {
            defineProperty(obj, keyName, null, value); // setup mandatory setter
          } else {
            let descriptor = lookupDescriptor(obj, keyName);
            let isMandatorySetter = descriptor && descriptor.set && descriptor.set.isMandatorySetter;
            if (isMandatorySetter) {
              meta.writeValues(keyName, value);
            } else {
              obj[keyName] = value;
            }
          }
        } else {
          obj[keyName] = value;
        }
        propertyDidChange(obj, keyName);
      }
    } else {
      obj[keyName] = value;
      if (obj[PROPERTY_DID_CHANGE]) {
        obj[PROPERTY_DID_CHANGE](keyName);
      }
    }
  }
  return value;
}

function setPath(root, path, value, tolerant) {
  var keyName;

  // get the last part of the path
  keyName = path.slice(path.lastIndexOf('.') + 1);

  // get the first part of the part
  path    = (path === keyName) ? keyName : path.slice(0, path.length - (keyName.length + 1));

  // unless the path is this, look up the first part to
  // get the root
  if (path !== 'this') {
    root = getPath(root, path);
  }

  if (!keyName || keyName.length === 0) {
    throw new EmberError('Property set failed: You passed an empty path');
  }

  if (!root) {
    if (tolerant) {
      return;
    } else {
      throw new EmberError('Property set failed: object in path "' + path + '" could not be found or was destroyed.');
    }
  }

  return set(root, keyName, value);
}

/**
  Error-tolerant form of `Ember.set`. Will not blow up if any part of the
  chain is `undefined`, `null`, or destroyed.

  This is primarily used when syncing bindings, which may try to update after
  an object has been destroyed.

  @method trySet
  @for Ember
  @param {Object} root The object to modify.
  @param {String} path The property path to set
  @param {Object} value The value to set
  @public
*/
export function trySet(root, path, value) {
  return set(root, path, value, true);
}
<|endoftext|>


<commit_before>
// toggle up and down arrows on the navdrops
$(document).ready( function () {
    // TODO somehow make this smarter
    // bar selector
    $("#barNavdrop").on("shown.bs.collapse", function() {
        $("#barNavdropIcon").removeClass("fa-caret-down").addClass("fa-caret-up");
    });
    $("#barNavdrop").on("hidden.bs.collapse", function() {
        $("#barNavdropIcon").removeClass("fa-caret-up").addClass("fa-caret-down");
    });
    // admin selector
    $("#adminNavdrop").on("shown.bs.collapse", function() {
        $("#adminNavdropIcon").removeClass("fa-caret-down").addClass("fa-caret-up");
    });
    $("#adminNavdrop").on("hidden.bs.collapse", function() {
        $("#adminNavdropIcon").removeClass("fa-caret-up").addClass("fa-caret-down");
    });
});
<commit_msg>Adds the new dropdown<commit_after>
// toggle up and down arrows on the navdrops
$(document).ready( function () {
    // TODO somehow make this smarter
    // bar selector
    $("#barNavdrop").on("shown.bs.collapse", function() {
        $("#barNavdropIcon").removeClass("fa-caret-down").addClass("fa-caret-up");
    });
    $("#barNavdrop").on("hidden.bs.collapse", function() {
        $("#barNavdropIcon").removeClass("fa-caret-up").addClass("fa-caret-down");
    });
    // admin selector
    $("#adminNavdrop").on("shown.bs.collapse", function() {
        $("#adminNavdropIcon").removeClass("fa-caret-down").addClass("fa-caret-up");
    });
    $("#adminNavdrop").on("hidden.bs.collapse", function() {
        $("#adminNavdropIcon").removeClass("fa-caret-up").addClass("fa-caret-down");
    });
    // bar management
    $("#currentBarNavdrop").on("shown.bs.collapse", function() {
        $("#currentBarNavdropIcon").removeClass("fa-caret-down").addClass("fa-caret-up");
    });
    $("#currentBarNavdrop").on("hidden.bs.collapse", function() {
        $("#currentBarNavdropIcon").removeClass("fa-caret-up").addClass("fa-caret-down");
    });
});
<|endoftext|>


<commit_before>import { expect } from "chai";
import pulldeps from "../../src/index";

describe("Test suite", function() {
  var dependencies;

  describe("When parsing a single dynamic `import`", function() {
    before(function() {
      dependencies = pulldeps("import('module-name');").dependencies;
    });

    it("then dependencies length is `1`", function() {
      expect(dependencies).to.have.lengthOf(1);
    });

    it("then dependencies[0] is `module-name`", function() {
      expect(dependencies[0].name).to.equal("module-name");
    });
  });

  describe("When parsing a single `import` with the default named export ", function() {
    before(function() {
      dependencies = pulldeps("import test from 'test'").dependencies;
    });

    it("then dependencies length is `1`", function() {
      expect(dependencies.length).to.equal(1);
    });

    it("then dependencies[0] is `test`", function() {
      expect(dependencies[0].name).to.equal("test");
    });
  });

  describe("When parsing a single `import` with an aliased named export", function() {
    before(function() {
      dependencies = pulldeps("import { test as t } from 'test'").dependencies;
    });

    it("then dependencies length is `1`", function() {
      expect(dependencies.length).to.equal(1);
    });

    it("then dependencies[0] is `test`", function() {
      expect(dependencies[0].name).to.equal("test");
    });
  });

  describe("When parsing a single `import` with no named export", function() {
    before(function() {
      dependencies = pulldeps("import 'test'").dependencies;
    });

    it("then dependencies length is `1`", function() {
      expect(dependencies.length).to.equal(1);
    });

    it("then dependencies[0] is `test`", function() {
      expect(dependencies[0].name).to.equal("test");
    });
  });

  describe("When parsing single `require`", function() {
    before(function() {
      dependencies = pulldeps("require('test')").dependencies;
    });

    it("then dependencies length is `1`", function() {
      expect(dependencies.length).to.equal(1);
    });

    it("then dependencies[0] is `test`", function() {
      expect(dependencies[0].name).to.equal("test");
    });
  });

  describe("When parsing single `require` with an array of dependencies", function() {
    before(function() {
      dependencies = pulldeps("require(['test'])").dependencies;
    });

    it("then dependencies length is `0`", function() {
      expect(dependencies.length).to.equal(0);
    });
  });

  describe("When parsing single `require` and `use strict`", function() {
    before(function() {
      dependencies = pulldeps("'use strict'; require('test')").dependencies;
    });

    it("then dependencies length is `1`", function() {
      expect(dependencies.length).to.equal(1);
    });

    it("then dependencies[0] is `test`", function() {
      expect(dependencies[0].name).to.equal("test");
    });
  });

  describe("When parsing single `require` assigned to a variable", function() {
    before(function() {
      dependencies = pulldeps("var test = require('test')").dependencies;
    });

    it("then dependencies length is `1`", function() {
      expect(dependencies.length).to.equal(1);
    });

    it("then dependencies[0] is `test`", function() {
      expect(dependencies[0].name).to.equal("test");
    });
  });

  describe("When parsing single `require` assigned to a variable in an if statement", function() {
    before(function() {
      dependencies = pulldeps("var x = true; if(x){var test = require('test')}").dependencies;
    });

    it("then dependencies length is `1`", function() {
      expect(dependencies.length).to.equal(1);
    });

    it("then dependencies[0] is `test`", function() {
      expect(dependencies[0].name).to.equal("test");
    });
  });

  describe("When parsing single `define` with an array", function() {
    before(function() {
      dependencies = pulldeps("define(['test'], function() {})").dependencies;
    });

    it("then dependencies length is `1`", function() {
      expect(dependencies.length).to.equal(1);
    });

    it("then dependencies[0] is `test`", function() {
      expect(dependencies[0].name).to.equal("test");
    });
  });

  describe("When parsing single named `define` with an array of two dependencies", function() {
    before(function() {
      dependencies = pulldeps("define('whatever name', ['test1', 'test2'], function() {})").dependencies;
    });

    it("then dependencies length is `2`", function() {
      expect(dependencies.length).to.equal(2);
    });

    it("then dependencies[0] is `test1`", function() {
      expect(dependencies[0].name).to.equal("test1");
    });

    it("then dependencies[1] is `test2`", function() {
      expect(dependencies[1].name).to.equal("test2");
    });
  });

  describe("When parsing single named `define` with an array of two dependencies and two require statements and one is an array", function() {
    before(function() {
      dependencies = pulldeps("define('whatever name', ['test1', 'test2'], function() {require('test3'); require(['test4']);})").dependencies;
    });

    it("then dependencies length is `3`", function() {
      expect(dependencies.length).to.equal(3);
    });

    it("then dependencies[0] is `test3`", function() {
      expect(dependencies[0].name).to.equal("test3");
    });

    it("then dependencies[1] is `test1`", function() {
      expect(dependencies[1].name).to.equal("test1");
    });

    it("then dependencies[2] is `test2`", function() {
      expect(dependencies[2].name).to.equal("test2");
    });
  });
});
<commit_msg>added unit tests with yield, async, and await.<commit_after>import { expect } from "chai";
import pulldeps from "../../src/index";

describe("Test suite", function() {
  var dependencies;

  describe("When parsing a single dynamic `import`", function() {
    before(function() {
      dependencies = pulldeps("import('module-name');").dependencies;
    });

    it("then dependencies length is `1`", function() {
      expect(dependencies).to.have.lengthOf(1);
    });

    it("then dependencies[0] is `module-name`", function() {
      expect(dependencies[0].name).to.equal("module-name");
    });
  });

  describe("When parsing a single dynamic `import` with `yield`", function() {
    before(function() {
      dependencies = pulldeps.fromSource(`
        function* someFUNC() {
          const b = yield import('module-name');
        }
      `).dependencies;
    });

    it("then dependencies length is `1`", function() {
      expect(dependencies).to.have.lengthOf(1);
    });

    it("then dependencies[0] is `module-name`", function() {
      expect(dependencies[0].name).to.equal("module-name");
    });
  });

  describe("When parsing a single dynamic `import` with `async` and `await`", function() {
    before(function() {
      dependencies = pulldeps.fromSource(`
        async function someFUNC() {
          return await import('module-name');
        }
      `, {
        options: {
          ecmaVersion: 8
        }
      }).dependencies;
    });

    it("then dependencies length is `1`", function() {
      expect(dependencies).to.have.lengthOf(1);
    });

    it("then dependencies[0] is `module-name`", function() {
      expect(dependencies[0].name).to.equal("module-name");
    });
  });

  describe("When parsing a single `import` with the default named export ", function() {
    before(function() {
      dependencies = pulldeps("import test from 'test'").dependencies;
    });

    it("then dependencies length is `1`", function() {
      expect(dependencies.length).to.equal(1);
    });

    it("then dependencies[0] is `test`", function() {
      expect(dependencies[0].name).to.equal("test");
    });
  });

  describe("When parsing a single `import` with an aliased named export", function() {
    before(function() {
      dependencies = pulldeps("import { test as t } from 'test'").dependencies;
    });

    it("then dependencies length is `1`", function() {
      expect(dependencies.length).to.equal(1);
    });

    it("then dependencies[0] is `test`", function() {
      expect(dependencies[0].name).to.equal("test");
    });
  });

  describe("When parsing a single `import` with no named export", function() {
    before(function() {
      dependencies = pulldeps("import 'test'").dependencies;
    });

    it("then dependencies length is `1`", function() {
      expect(dependencies.length).to.equal(1);
    });

    it("then dependencies[0] is `test`", function() {
      expect(dependencies[0].name).to.equal("test");
    });
  });

  describe("When parsing single `require`", function() {
    before(function() {
      dependencies = pulldeps("require('test')").dependencies;
    });

    it("then dependencies length is `1`", function() {
      expect(dependencies.length).to.equal(1);
    });

    it("then dependencies[0] is `test`", function() {
      expect(dependencies[0].name).to.equal("test");
    });
  });

  describe("When parsing single `require` with an array of dependencies", function() {
    before(function() {
      dependencies = pulldeps("require(['test'])").dependencies;
    });

    it("then dependencies length is `0`", function() {
      expect(dependencies.length).to.equal(0);
    });
  });

  describe("When parsing single `require` and `use strict`", function() {
    before(function() {
      dependencies = pulldeps("'use strict'; require('test')").dependencies;
    });

    it("then dependencies length is `1`", function() {
      expect(dependencies.length).to.equal(1);
    });

    it("then dependencies[0] is `test`", function() {
      expect(dependencies[0].name).to.equal("test");
    });
  });

  describe("When parsing single `require` assigned to a variable", function() {
    before(function() {
      dependencies = pulldeps("var test = require('test')").dependencies;
    });

    it("then dependencies length is `1`", function() {
      expect(dependencies.length).to.equal(1);
    });

    it("then dependencies[0] is `test`", function() {
      expect(dependencies[0].name).to.equal("test");
    });
  });

  describe("When parsing single `require` assigned to a variable in an if statement", function() {
    before(function() {
      dependencies = pulldeps("var x = true; if(x){var test = require('test')}").dependencies;
    });

    it("then dependencies length is `1`", function() {
      expect(dependencies.length).to.equal(1);
    });

    it("then dependencies[0] is `test`", function() {
      expect(dependencies[0].name).to.equal("test");
    });
  });

  describe("When parsing single `define` with an array", function() {
    before(function() {
      dependencies = pulldeps("define(['test'], function() {})").dependencies;
    });

    it("then dependencies length is `1`", function() {
      expect(dependencies.length).to.equal(1);
    });

    it("then dependencies[0] is `test`", function() {
      expect(dependencies[0].name).to.equal("test");
    });
  });

  describe("When parsing single named `define` with an array of two dependencies", function() {
    before(function() {
      dependencies = pulldeps("define('whatever name', ['test1', 'test2'], function() {})").dependencies;
    });

    it("then dependencies length is `2`", function() {
      expect(dependencies.length).to.equal(2);
    });

    it("then dependencies[0] is `test1`", function() {
      expect(dependencies[0].name).to.equal("test1");
    });

    it("then dependencies[1] is `test2`", function() {
      expect(dependencies[1].name).to.equal("test2");
    });
  });

  describe("When parsing single named `define` with an array of two dependencies and two require statements and one is an array", function() {
    before(function() {
      dependencies = pulldeps("define('whatever name', ['test1', 'test2'], function() {require('test3'); require(['test4']);})").dependencies;
    });

    it("then dependencies length is `3`", function() {
      expect(dependencies.length).to.equal(3);
    });

    it("then dependencies[0] is `test3`", function() {
      expect(dependencies[0].name).to.equal("test3");
    });

    it("then dependencies[1] is `test1`", function() {
      expect(dependencies[1].name).to.equal("test1");
    });

    it("then dependencies[2] is `test2`", function() {
      expect(dependencies[2].name).to.equal("test2");
    });
  });
});
<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react';
import { withRouter, Link, styled } from 'olymp';
import { Tree } from 'olymp-ui';
import { Icon } from 'antd';
import { queryPages, reorderPage, movePage } from './gql';

const badgeStyle = theme => ({
  size: 23,
  borderRadius: '50%',
  textAlign: 'center',
  marginLeft: 3,
  '> i': {
    color: theme.light,
    margin: '0 !important',
  },
  onHover: {
    '> i': {
      color: theme.light2,
    },
  }
});

const Button = styled(({ theme }) => ({
  // backgroundColor: theme.color,
  // ...badgeStyle(theme),
}), ({ className, to, type }) => (
  <Link to={to} className={className}>
    <Icon type={type} />
  </Link>
), p => p);

const Badge = styled(({ theme }) => ({
  // backgroundColor: theme.dark2,
  // ...badgeStyle(theme),
}), ({ className, type }) => (

    <Icon type={type} />

), p => p);

@withRouter
@reorderPage
@movePage
export class Pages extends Component {
  state = {
    expandedKeys: [],
  };
  onDrop = (info) => { // reorder or move nodes on drop
    const { reorder, move } = this.props;
    const parent = info.dropToGap && info.node.props.parent
      ? info.node.props.parent
      : info.node.props.item;
    const page = info.dragNode.props.item;
    const pageId = page.pageId || page.id; // get real pageId in case of binding

    // Get all IDs of children in order
    const childIds = (parent.children || []).map(child => child.id).filter(x => x !== page.id);
    childIds.splice(info.dropPosition, 0, page.id);

    // Check if new parent is itself??
    if (parent.id === pageId) return;
    if (parent.id !== page.parentId) { // parent changed
      move({
        variables: {
          id: pageId,
          parentId: parent.id,
          sorting: childIds.join(','),
        },
      });
    } else { // just moved inside existing parent
      // Disallow sort if parent has fixed sorting
      if (parent.sorting && ['+', '-'].includes(parent.sorting[0])) return;
      reorder({
        variables: {
          id: parent.id,
          sorting: childIds.join(','),
        },
      });
    }
  }
  getNodeIcon = (item) => {
    if (item.sorting && item.sorting[0] === '+') {
      return <Badge type="arrow-up" />;
    } else if (item.sorting && item.sorting[0] === '-') {
      return <Badge type="arrow-down" />;
    } else if (item.slug === '/') {
      return <Badge type="home" />;
    } else if (item.type === 'ALIAS') {
      return <Badge type="copy" />;
    } else if (item.type === 'LINK') {
      return <Badge type="link" />;
    } else if (item.type === 'PLACEHOLDER') {
      return <Badge type="pause" />;
    } else if (item.type === 'MENU') {
      return <Badge type="database" />;
    } return null;
  };
  loop = (data, parent) => data.map((item) => {
    const { query } = this.props;
    const children = item.children && item.children.length ? this.loop(item.children, item) : undefined;
    return (
      <Tree.Node
        key={item.id || item.pathname}
        item={item}
        parent={parent}
        title={
          <Tree.Title disabled={item.state === 'DRAFT'}>
            <Link to={{ pathname: item.pathname, query }}>
              {item.name}
            </Link>
            {this.getNodeIcon(item)}
            {item.bindingId && (
              <Button
                to={{ query: { ...query, '@page': undefined, [`@${item.binding.split(' ')[0]}`]: item.bindingId } }}
                type="share-alt"
              />
            )}
            <Button to={{ pathname: item.pathname, query: { ...query, '@page': item.pageId || item.id } }} type="edit" />
          </Tree.Title>
        }
      >
        {children}
      </Tree.Node>
    );
  })
  render() {
    const { items, pathname, query } = this.props;
    const { expandedKeys } = this.state;
    return (
      <Tree
        selectedKeys={[pathname]}
        draggable
        defaultExpandAll
        className="draggable-tree"
        defaultExpandedKeys={expandedKeys}
        onDragEnter={this.onDragEnter}
        onDrop={this.onDrop}
      >
        {this.loop(items)}
      </Tree>
    );
  }
}
Pages.propTypes = {
  items: PropTypes.arrayOf(PropTypes.object),
};
Pages.defaultProps = {
  items: [],
};
export const PagesGql = queryPages(Pages);
<commit_msg>edit page on tree node click, remove edit button in tree<commit_after>import React, { Component, PropTypes } from 'react';
import { withRouter, Link, styled } from 'olymp';
import { Tree } from 'olymp-ui';
import { Icon } from 'antd';
import { queryPages, reorderPage, movePage } from './gql';

const badgeStyle = theme => ({
  size: 23,
  borderRadius: '50%',
  textAlign: 'center',
  marginLeft: 3,
  '> i': {
    color: theme.light,
    margin: '0 !important',
  },
  onHover: {
    '> i': {
      color: theme.light2,
    },
  }
});

const Button = styled(({ theme }) => ({
  // backgroundColor: theme.color,
  // ...badgeStyle(theme),
}), ({ className, to, type }) => (
  <Link to={to} className={className}>
    <Icon type={type} />
  </Link>
), p => p);

const Badge = styled(({ theme }) => ({
  // backgroundColor: theme.dark2,
  // ...badgeStyle(theme),
}), ({ className, type }) => (

    <Icon type={type} />

), p => p);

@withRouter
@reorderPage
@movePage
export class Pages extends Component {
  state = {
    expandedKeys: [],
  };
  onDrop = (info) => { // reorder or move nodes on drop
    const { reorder, move } = this.props;
    const parent = info.dropToGap && info.node.props.parent
      ? info.node.props.parent
      : info.node.props.item;
    const page = info.dragNode.props.item;
    const pageId = page.pageId || page.id; // get real pageId in case of binding

    // Get all IDs of children in order
    const childIds = (parent.children || []).map(child => child.id).filter(x => x !== page.id);
    childIds.splice(info.dropPosition, 0, page.id);

    // Check if new parent is itself??
    if (parent.id === pageId) return;
    if (parent.id !== page.parentId) { // parent changed
      move({
        variables: {
          id: pageId,
          parentId: parent.id,
          sorting: childIds.join(','),
        },
      });
    } else { // just moved inside existing parent
      // Disallow sort if parent has fixed sorting
      if (parent.sorting && ['+', '-'].includes(parent.sorting[0])) return;
      reorder({
        variables: {
          id: parent.id,
          sorting: childIds.join(','),
        },
      });
    }
  }
  getNodeIcon = (item) => {
    if (item.sorting && item.sorting[0] === '+') {
      return <Badge type="arrow-up" />;
    } else if (item.sorting && item.sorting[0] === '-') {
      return <Badge type="arrow-down" />;
    } else if (item.slug === '/') {
      return <Badge type="home" />;
    } else if (item.type === 'ALIAS') {
      return <Badge type="copy" />;
    } else if (item.type === 'LINK') {
      return <Badge type="link" />;
    } else if (item.type === 'PLACEHOLDER') {
      return <Badge type="pause" />;
    } else if (item.type === 'MENU') {
      return <Badge type="database" />;
    } return null;
  };
  loop = (data, parent) => data.map((item) => {
    const { query } = this.props;
    const children = item.children && item.children.length ? this.loop(item.children, item) : undefined;
    return (
      <Tree.Node
        key={item.id || item.pathname}
        item={item}
        parent={parent}
        title={
          <Tree.Title disabled={item.state === 'DRAFT'}>
            <Link to={{ pathname: item.pathname, query: { ...query, '@page': item.pageId || item.id } }}>
              {item.name}
            </Link>
            {this.getNodeIcon(item)}
            {item.bindingId && (
              <Button
                to={{ query: { ...query, '@page': undefined, [`@${item.binding.split(' ')[0]}`]: item.bindingId } }}
                type="share-alt"
              />
            )}
          </Tree.Title>
        }
      >
        {children}
      </Tree.Node>
    );
  })
  render() {
    const { items, pathname, query } = this.props;
    const { expandedKeys } = this.state;
    return (
      <Tree
        selectedKeys={[pathname]}
        draggable
        defaultExpandAll
        className="draggable-tree"
        defaultExpandedKeys={expandedKeys}
        onDragEnter={this.onDragEnter}
        onDrop={this.onDrop}
      >
        {this.loop(items)}
      </Tree>
    );
  }
}
Pages.propTypes = {
  items: PropTypes.arrayOf(PropTypes.object),
};
Pages.defaultProps = {
  items: [],
};
export const PagesGql = queryPages(Pages);
<|endoftext|>


<commit_before>'use strict';

var request = require('request');

var Joi     = require('joi');
var Promise = require('bluebird');

function buildQuery(options) {
  var results = [];
  Object.keys(options).forEach(function(key) {
    results.push(key + '=' + options[key]);
  });
  return results.join('&');
}

var optionsSchema = Joi.object().keys({
  screen_name         : Joi.string().min(1),
  user_id             : Joi.number().integer().min(0),
  since_id            : Joi.number().integer().min(0),
  count               : Joi.number().integer().min(0),
  max_id              : Joi.number().integer().min(0),
  trim_user           : Joi.boolean(),
  exclude_replies     : Joi.boolean(),
  contributor_details : Joi.boolean(),
  include_rts         : Joi.boolean()
}).or('screen_name', 'user_id');

var getTweets = function(options) {
  var self = this;
  return new Promise(function(resolve, reject) {
    var token = self.token;
    if (typeof token === 'undefined') {
      return reject(false);
    }
    if (options == null || typeof options !== 'object') {
      throw new TypeError('\'options\' must be an object.');
    }

    var requestCallback = function(err, res, body) {
      if (err) {
        return reject(err);
      }

      return resolve(JSON.parse(body));
    };

    Joi.validate(options, optionsSchema, function(err, value) {
      if (err) {
        throw err;
      }

      var requestOptions = {
        url     : 'https://api.twitter.com/1.1/statuses/user_timeline.json?' + buildQuery(options),
        method  : 'GET',
        headers : {
          'Authorization'  : 'Bearer ' + token,
          'User-Agent'     : 'request'
        },
      };

      request.get(requestOptions, requestCallback);
    });
  });
};

module.exports = {
  getTweets       : getTweets,
  optionsSchema   : optionsSchema,
};
<commit_msg>Added response sanity checks<commit_after>'use strict';

var request = require('request');

var Joi     = require('joi');
var Promise = require('bluebird');

function buildQuery(options) {
  var results = [];
  Object.keys(options).forEach(function(key) {
    results.push(key + '=' + options[key]);
  });
  return results.join('&');
}

var optionsSchema = Joi.object().keys({
  screen_name         : Joi.string().min(1),
  user_id             : Joi.number().integer().min(0),
  since_id            : Joi.number().integer().min(0),
  count               : Joi.number().integer().min(0),
  max_id              : Joi.number().integer().min(0),
  trim_user           : Joi.boolean(),
  exclude_replies     : Joi.boolean(),
  contributor_details : Joi.boolean(),
  include_rts         : Joi.boolean()
}).or('screen_name', 'user_id');

var getTweets = function(options) {
  var self = this;
  return new Promise(function(resolve, reject) {
    var token = self.token;
    if (typeof token === 'undefined') {
      return reject(false);
    }
    if (options == null || typeof options !== 'object') {
      throw new TypeError('\'options\' must be an object.');
    }

    var requestCallback = function(err, res, body) {
      if (err) {
        return reject(err);
      }

      if (res.statusCode !== 200) {
        return reject(new Error('Problem retrieving tweets: ' + JSON.stringify(res)));
      }

      return resolve(body ? JSON.parse(body) : null);
    };

    Joi.validate(options, optionsSchema, function(err, value) {
      if (err) {
        throw err;
      }

      var requestOptions = {
        url     : 'https://api.twitter.com/1.1/statuses/user_timeline.json?' + buildQuery(options),
        method  : 'GET',
        headers : {
          'Authorization'  : 'Bearer ' + token,
          'User-Agent'     : 'request'
        },
      };

      request.get(requestOptions, requestCallback);
    });
  });
};

module.exports = {
  getTweets       : getTweets,
  optionsSchema   : optionsSchema,
};
<|endoftext|>