<commit_before>define(["dojo/main", "ppwcode/contracts/doh", "./CrudDaoMock", "../PersistentObject", "../IdNotFoundException", "dojo/_base/declare"],
    function(dojo, doh, CrudDaoMock, PersistentObject, IdNotFoundException, declare) {

      var baseUrl1 = "http://www.ppwcode.org/some/path/";

      function cacheKey(/*String*/ type, /*Number*/ persistenceId) {
        // summary:
        //   Returns a key.
        // description:
        //   Returns `type + "@" + persistenceId`

        return type + "@" + persistenceId;
      }

      function poCacheKey(/*PersistentObject*/ p) {
        // summary:
        //   Returns a key, intended to be unique, for this entry.
        // description:
        //   Returns `persistentObject.declaredClass + "@" + persistentObject.persistenceId`

        return cacheKey(p.declaredClass, p.persistenceId);
      }

      subjectSetup = function() {
        var subject = new CrudDaoMock();
        subject.baseUrl = baseUrl1;
        this.subject = subject;
      };

      var MockPo = declare([PersistentObject], {

        constructor: function(kwargs) {
          this.testProperty = 3;
        },

        testProperty: 5

      });

      function testCreate(subject, waitMillis, semanticException, error) {
        var p = new MockPo({persistenceId: null});
        if (waitMillis) {
          p.waitMillis = waitMillis;
        }
        if (semanticException) {
          p.semanticException = semanticException;
        }
        if (error) {
          p.error = error;
        }
        var tracker1 = {};
        var persistenceIdEvent = null;
        p.watch("persistenceId", function(propertyName, oldValue, newValue) {
          persistenceIdEvent = {
            propertyName: propertyName,
            oldValue: oldValue,
            newValue: newValue
          }
        });
        var deferred = new doh.Deferred();
        var result = subject.create(p, tracker1);
        doh.t(result);
        doh.t(result.persistentObject);
        doh.is(p, result.persistentObject);
        var resultPromise = result.promise;
        doh.t(resultPromise);
        resultPromise.then(
          function(pSuccess) {
            try {
              doh.is(p, pSuccess);
              doh.t(p.persistenceId);
              doh.t(persistenceIdEvent);
              doh.is("persistenceId", persistenceIdEvent.propertyName);
              doh.is(null, persistenceIdEvent.oldValue);
              doh.is(p.get("persistenceId"), persistenceIdEvent.newValue);
              var ce = subject._getExistingCacheEntry(p);
              doh.t(ce);
              doh.is(p, ce.persistentObject);
              doh.is(1, ce.getNrOfReferers());
              doh.t(ce._referers.contains(tracker1));
              deferred.callback(true);
            }
            catch (error) {
              deferred.errback(error);
            }
          },
          function(problem) {
            try {
              doh.is(null, p.persistenceId);
              doh.f(persistenceIdEvent);
              if (error) {
                console.log("Expected error message: " + error);
              }
              else if (semanticException) {
                doh.is(semanticException, problem);
              }
              else {
                doh.fail();
              }
              deferred.callback(true);
            }
            catch (error) {
              deferred.errback(error);
            }
          }
        );
        return deferred;
      }

      function testUpdateNothingChanged(subject, p, persistenceIdEvent, firstTestPropertyEvent, testPropertyEvent, tracker) {
        doh.t(p.persistenceId);
        doh.is(777, p.get("persistenceId"));
        doh.f(persistenceIdEvent);
        var ce = subject._getExistingCacheEntry(p);
        doh.t(ce);
        doh.is(p, ce.persistentObject);
        doh.is(1, ce.getNrOfReferers());
        doh.t(ce._referers.contains(tracker));
        doh.is(9, p.get("testProperty"));
        doh.is(firstTestPropertyEvent, testPropertyEvent);
      }

      function testUpdate(subject, waitMillis, semanticException, error) {
        var p = new MockPo({persistenceId: 777});
        if (waitMillis) {
          p.waitMillis = waitMillis;
        }
        if (semanticException) {
          p.semanticException = semanticException;
        }
        if (error) {
          p.error = error;
        }
        var tracker1 = {};
        subject.track(p, tracker1);
        var persistenceIdEvent = null;
        p.watch("persistenceId", function(propertyName, oldValue, newValue) {
          persistenceIdEvent = {
            propertyName: propertyName,
            oldValue: oldValue,
            newValue: newValue
          }
        });
        var testPropertyEvent = null;
        p.watch("testProperty", function(propertyName, oldValue, newValue) {
          testPropertyEvent = {
            propertyName: propertyName,
            oldValue: oldValue,
            newValue: newValue
          }
        });
        p.set("testProperty", 9);
        var firstTestPropertyEvent = testPropertyEvent;
        doh.t(testPropertyEvent);
        doh.is("testProperty", testPropertyEvent.propertyName);
        doh.is(3, testPropertyEvent.oldValue);
        doh.is(9, testPropertyEvent.newValue);
        var deferred = new doh.Deferred();
        var result = subject.update(p);
        doh.t(result);
        doh.t(result.persistentObject);
        doh.is(p, result.persistentObject);
        var resultPromise = result.promise;
        doh.t(resultPromise);
        resultPromise.then(
          function(pSuccess) {
            try {
              doh.is(p, pSuccess);
              testUpdateNothingChanged(subject, p, persistenceIdEvent, firstTestPropertyEvent, testPropertyEvent, tracker1);
              deferred.callback(true);
            }
            catch (error) {
              deferred.errback(error);
            }
          },
          function(problem) {
            try {
              if (error) {
                console.log("Expected error message: " + error);
                testUpdateNothingChanged(subject, p, persistenceIdEvent, firstTestPropertyEvent, testPropertyEvent, tracker1);
              }
              else if (semanticException) {
                doh.is(semanticException, problem);
                if (semanticException.isInstanceOf && semanticException.isInstanceOf(IdNotFoundException)) {
                  doh.is(null, p.get("persistenceId"));
                  doh.t(persistenceIdEvent);
                  doh.is("persistenceId", persistenceIdEvent.propertyName);
                  doh.is(777, persistenceIdEvent.oldValue);
                  doh.is(null, persistenceIdEvent.newValue);
                  var ce = subject._cache[poCacheKey(p)];
                  doh.f(ce);
                  doh.is(9, p.get("testProperty"));
                  doh.is(firstTestPropertyEvent, testPropertyEvent);
                }
                else {
                  testUpdateNothingChanged(subject, p, persistenceIdEvent, firstTestPropertyEvent, testPropertyEvent, tracker1);
                }
              }
              else {
                doh.fail();
              }
              deferred.callback(true);
            }
            catch (error) {
              deferred.errback(error);
            }
          }
        );
        return deferred;
      }

      doh.register("CrudDao (Mock)", [

        function testConstructor() {
          var subject = new CrudDaoMock();
        },

        {
          name: "base url 1",
          setUp: subjectSetup,
          runTest: function(){
            var result = this.subject.getUrl(PersistentObject, "777");
            console.log(result);
            doh.is(baseUrl1 + PersistentObject.prototype.declaredClass.replace(/\./g, "/") + "/777", result);
          }
        },

        {
          name: "base url 2",
          setUp: subjectSetup,
          runTest: function(){
            var result = this.subject.getUrl(PersistentObject);
            console.log(result);
            doh.is(baseUrl1 + PersistentObject.prototype.declaredClass.replace(/\./g, "/"), result);
          }
        },

        {
          name: "track1",
          setUp: subjectSetup,
          runTest: function() {
            var p = new MockPo({persistenceId: 777});
            var tracker = {};
            this.subject.track(p, tracker);
            var ce = this.subject._getExistingCacheEntry(p);
            doh.t(this.subject._getExistingCacheEntry(p));
            doh.is(p, ce.persistentObject);
            doh.is(1, ce.getNrOfReferers());
            doh.t(ce._referers.contains(tracker));
          }
        },

        {
          name: "track2",
          setUp: subjectSetup,
          runTest: function() {
            var p = new MockPo({persistenceId: 777});
            var tracker = {};
            this.subject.track(p, tracker);
            this.subject.track(p, tracker);
            var ce = this.subject._getExistingCacheEntry(p);
            doh.t(this.subject._getExistingCacheEntry(p));
            doh.is(p, ce.persistentObject);
            doh.is(1, ce.getNrOfReferers());
            doh.t(ce._referers.contains(tracker));
          }
        },

        {
          name: "track3",
          setUp: subjectSetup,
          runTest: function() {
            var p = new MockPo({persistenceId: 777});
            var tracker1 = {};
            var tracker2 = 6;
            this.subject.track(p, tracker1);
            this.subject.track(p, tracker2);
            var ce = this.subject._getExistingCacheEntry(p);
            doh.t(this.subject._getExistingCacheEntry(p));
            doh.is(p, ce.persistentObject);
            doh.is(2, ce.getNrOfReferers());
            doh.t(ce._referers.contains(tracker1));
            doh.t(ce._referers.contains(tracker2));
          }
        },

        {
          name: "stopTracking1",
          setUp: subjectSetup,
          runTest: function() {
            var p = new MockPo({persistenceId: 777});
            var tracker1 = {};
            var tracker2 = 6;
            this.subject.track(p, tracker1);
            this.subject.track(p, tracker2);
            this.subject.stopTracking(p, tracker2);
            var ce = this.subject._getExistingCacheEntry(p);
            doh.t(this.subject._getExistingCacheEntry(p));
            doh.is(p, ce.persistentObject);
            doh.is(1, ce.getNrOfReferers());
            doh.t(ce._referers.contains(tracker1));
          }
        },

        {
          name: "stopTracking2",
          setUp: subjectSetup,
          runTest: function() {
            var p = new MockPo({persistenceId: 777});
            var tracker1 = {};
            var tracker2 = 6;
            this.subject.track(p, tracker1);
            this.subject.track(p, tracker2);
            this.subject.stopTracking(p, tracker2);
            var ce = this.subject._getExistingCacheEntry(p);
            var key = ce.getKey();
            this.subject.stopTracking(p, tracker1);
            ce = this.subject._cache[key];
            doh.f(ce);
          }
        },

        {
          name: "_noLongerInServer",
          setUp: subjectSetup,
          runTest: function() {
            var p = new MockPo({persistenceId: 777});
            var tracker1 = {};
            var tracker2 = 6;
            this.subject.track(p, tracker1);
            this.subject.track(p, tracker2);
            var ce = this.subject._getExistingCacheEntry(p);
            var key = ce.getKey();
            this.subject._noLongerInServer(ce);
            ce = this.subject._cache[key];
            doh.f(ce);
            doh.is(null, p.persistenceId);
          }
        },

        {
          name: "create1",
          setUp: subjectSetup,
          runTest: function() {
            return testCreate(this.subject);
          }
        },

        {
          name: "create2",
          setUp: subjectSetup,
          runTest: function() {
            return testCreate(this.subject, 1500);
          },
          timeout: 3000
        },

        {
          name: "create3",
          setUp: subjectSetup,
          runTest: function() {
            return testCreate(this.subject, 0, "SemanticException");
          }
        },

        {
          name: "create4",
          setUp: subjectSetup,
          runTest: function() {
            return testCreate(this.subject, 1500, "SemanticException");
          },
          timeout: 3000
        },

        {
          name: "create5",
          setUp: subjectSetup,
          runTest: function() {
            return testCreate(this.subject, 0, null, "AN ERROR");
          }
        },

        {
          name: "create6",
          setUp: subjectSetup,
          runTest: function() {
            return testCreate(this.subject, 1500, null, "AN ERROR");
          },
          timeout: 3000
        },

        {
          name: "update1",
          setUp: subjectSetup,
          runTest: function() {
            return testUpdate(this.subject);
          }
        },

        {
          name: "update2",
          setUp: subjectSetup,
          runTest: function() {
            return testUpdate(this.subject, 1500);
          },
          timeout: 3000
        },

        {
          name: "update3",
          setUp: subjectSetup,
          runTest: function() {
            return testUpdate(this.subject, 0, "SemanticException");
          }
        },

        {
          name: "update4",
          setUp: subjectSetup,
          runTest: function() {
            return testUpdate(this.subject, 1500, "SemanticException");
          },
          timeout: 3000
        },

        {
          name: "update5",
          setUp: subjectSetup,
          runTest: function() {
            return testUpdate(this.subject, 0, new IdNotFoundException());
          }
        },

        {
          name: "update6",
          setUp: subjectSetup,
          runTest: function() {
            return testUpdate(this.subject, 1500, new IdNotFoundException());
          },
          timeout: 3000
        },

        {
          name: "update7",
          setUp: subjectSetup,
          runTest: function() {
            return testUpdate(this.subject, 0, null, "AN ERROR");
          }
        },

        {
          name: "update8",
          setUp: subjectSetup,
          runTest: function() {
            return testUpdate(this.subject, 1500, null, "AN ERROR");
          },
          timeout: 3000
        }

      ]);
    }
);
<commit_msg>delete works too<commit_after>define(["dojo/main", "ppwcode/contracts/doh", "./CrudDaoMock", "../PersistentObject", "../IdNotFoundException", "dojo/_base/declare"],
    function(dojo, doh, CrudDaoMock, PersistentObject, IdNotFoundException, declare) {

      var baseUrl1 = "http://www.ppwcode.org/some/path/";

      function cacheKey(/*String*/ type, /*Number*/ persistenceId) {
        // summary:
        //   Returns a key.
        // description:
        //   Returns `type + "@" + persistenceId`

        return type + "@" + persistenceId;
      }

      function poCacheKey(/*PersistentObject*/ p) {
        // summary:
        //   Returns a key, intended to be unique, for this entry.
        // description:
        //   Returns `persistentObject.declaredClass + "@" + persistentObject.persistenceId`

        return cacheKey(p.declaredClass, p.persistenceId);
      }

      subjectSetup = function() {
        var subject = new CrudDaoMock();
        subject.baseUrl = baseUrl1;
        this.subject = subject;
      };

      var MockPo = declare([PersistentObject], {

        constructor: function(kwargs) {
          this.testProperty = 3;
        },

        testProperty: 5

      });

      function testCreate(subject, waitMillis, semanticException, error) {
        var p = new MockPo({persistenceId: null});
        if (waitMillis) {
          p.waitMillis = waitMillis;
        }
        if (semanticException) {
          p.semanticException = semanticException;
        }
        if (error) {
          p.error = error;
        }
        var tracker1 = {};
        var persistenceIdEvent = null;
        p.watch("persistenceId", function(propertyName, oldValue, newValue) {
          persistenceIdEvent = {
            propertyName: propertyName,
            oldValue: oldValue,
            newValue: newValue
          }
        });
        var deferred = new doh.Deferred();
        var result = subject.create(p, tracker1);
        doh.t(result);
        doh.t(result.persistentObject);
        doh.is(p, result.persistentObject);
        var resultPromise = result.promise;
        doh.t(resultPromise);
        resultPromise.then(
          function(pSuccess) {
            try {
              doh.is(p, pSuccess);
              doh.t(p.persistenceId);
              doh.t(persistenceIdEvent);
              doh.is("persistenceId", persistenceIdEvent.propertyName);
              doh.is(null, persistenceIdEvent.oldValue);
              doh.is(p.get("persistenceId"), persistenceIdEvent.newValue);
              var ce = subject._getExistingCacheEntry(p);
              doh.t(ce);
              doh.is(p, ce.persistentObject);
              doh.is(1, ce.getNrOfReferers());
              doh.t(ce._referers.contains(tracker1));
              deferred.callback(true);
            }
            catch (error) {
              deferred.errback(error);
            }
          },
          function(problem) {
            try {
              doh.is(null, p.persistenceId);
              doh.f(persistenceIdEvent);
              if (error) {
                console.log("Expected error message: " + error);
              }
              else if (semanticException) {
                doh.is(semanticException, problem);
              }
              else {
                doh.fail();
              }
              deferred.callback(true);
            }
            catch (error) {
              deferred.errback(error);
            }
          }
        );
        return deferred;
      }

      function testUpdateNothingChanged(subject, p, persistenceIdEvent, firstTestPropertyEvent, testPropertyEvent, tracker) {
        doh.t(p.persistenceId);
        doh.is(777, p.get("persistenceId"));
        doh.f(persistenceIdEvent);
        var ce = subject._getExistingCacheEntry(p);
        doh.t(ce);
        doh.is(p, ce.persistentObject);
        doh.is(1, ce.getNrOfReferers());
        doh.t(ce._referers.contains(tracker));
        doh.is(9, p.get("testProperty"));
        doh.is(firstTestPropertyEvent, testPropertyEvent);
      }

      function testUpdate(subject, waitMillis, semanticException, error) {
        var p = new MockPo({persistenceId: 777});
        if (waitMillis) {
          p.waitMillis = waitMillis;
        }
        if (semanticException) {
          p.semanticException = semanticException;
        }
        if (error) {
          p.error = error;
        }
        var tracker1 = {};
        subject.track(p, tracker1);
        var persistenceIdEvent = null;
        p.watch("persistenceId", function(propertyName, oldValue, newValue) {
          persistenceIdEvent = {
            propertyName: propertyName,
            oldValue: oldValue,
            newValue: newValue
          }
        });
        var testPropertyEvent = null;
        p.watch("testProperty", function(propertyName, oldValue, newValue) {
          testPropertyEvent = {
            propertyName: propertyName,
            oldValue: oldValue,
            newValue: newValue
          }
        });
        p.set("testProperty", 9);
        var firstTestPropertyEvent = testPropertyEvent;
        doh.t(testPropertyEvent);
        doh.is("testProperty", testPropertyEvent.propertyName);
        doh.is(3, testPropertyEvent.oldValue);
        doh.is(9, testPropertyEvent.newValue);
        var deferred = new doh.Deferred();
        var result = subject.update(p);
        doh.t(result);
        doh.t(result.persistentObject);
        doh.is(p, result.persistentObject);
        var resultPromise = result.promise;
        doh.t(resultPromise);
        resultPromise.then(
          function(pSuccess) {
            try {
              doh.is(p, pSuccess);
              testUpdateNothingChanged(subject, p, persistenceIdEvent, firstTestPropertyEvent, testPropertyEvent, tracker1);
              deferred.callback(true);
            }
            catch (error) {
              deferred.errback(error);
            }
          },
          function(problem) {
            try {
              if (error) {
                console.log("Expected error message: " + error);
                testUpdateNothingChanged(subject, p, persistenceIdEvent, firstTestPropertyEvent, testPropertyEvent, tracker1);
              }
              else if (semanticException) {
                doh.is(semanticException, problem);
                if (semanticException.isInstanceOf && semanticException.isInstanceOf(IdNotFoundException)) {
                  doh.is(null, p.get("persistenceId"));
                  doh.t(persistenceIdEvent);
                  doh.is("persistenceId", persistenceIdEvent.propertyName);
                  doh.is(777, persistenceIdEvent.oldValue);
                  doh.is(null, persistenceIdEvent.newValue);
                  var ce = subject._cache[poCacheKey(p)];
                  doh.f(ce);
                  doh.is(9, p.get("testProperty"));
                  doh.is(firstTestPropertyEvent, testPropertyEvent);
                }
                else {
                  testUpdateNothingChanged(subject, p, persistenceIdEvent, firstTestPropertyEvent, testPropertyEvent, tracker1);
                }
              }
              else {
                doh.fail();
              }
              deferred.callback(true);
            }
            catch (error) {
              deferred.errback(error);
            }
          }
        );
        return deferred;
      }

      function testDeleteIdChanged(subject, p, persistenceIdEvent, testPropertyEvent) {
        doh.is(null, p.get("persistenceId"));
        doh.t(persistenceIdEvent);
        doh.is("persistenceId", persistenceIdEvent.propertyName);
        doh.is(777, persistenceIdEvent.oldValue);
        doh.is(null, persistenceIdEvent.newValue);
        var ce = subject._cache[poCacheKey(p)];
        doh.f(ce);
        testDeleteNoChange(p, testPropertyEvent);
      }

      function testDeleteNothingChanged(subject, p, persistenceIdEvent, testPropertyEvent, tracker) {
        doh.t(p.get("persistenceId"));
        doh.is(777, p.get("persistenceId"));
        doh.f(persistenceIdEvent);

        var ce = subject._getExistingCacheEntry(p);
        doh.t(ce);
        doh.is(p, ce.persistentObject);
        doh.is(1, ce.getNrOfReferers());
        doh.t(ce._referers.contains(tracker));
        testDeleteNoChange(p, testPropertyEvent);
      }

      function testDeleteNoChange(p, testPropertyEvent) {
        doh.is(3, p.get("testProperty"));
        doh.f(testPropertyEvent);
      }

      function testDelete(subject, waitMillis, semanticException, error) {
        var p = new MockPo({persistenceId: 777});
        if (waitMillis) {
          p.waitMillis = waitMillis;
        }
        if (semanticException) {
          p.semanticException = semanticException;
        }
        if (error) {
          p.error = error;
        }
        var tracker1 = {};
        subject.track(p, tracker1);
        var persistenceIdEvent = null;
        p.watch("persistenceId", function(propertyName, oldValue, newValue) {
          persistenceIdEvent = {
            propertyName: propertyName,
            oldValue: oldValue,
            newValue: newValue
          }
        });
        var testPropertyEvent = null;
        p.watch("testProperty", function(propertyName, oldValue, newValue) {
          testPropertyEvent = {
            propertyName: propertyName,
            oldValue: oldValue,
            newValue: newValue
          }
        });
        var deferred = new doh.Deferred();
        var result = subject.delete(p);
        doh.t(result);
        doh.t(result.persistentObject);
        doh.is(p, result.persistentObject);
        var resultPromise = result.promise;
        doh.t(resultPromise);
        resultPromise.then(
          function(pSuccess) {
            try {
              doh.is(p, pSuccess);
              testDeleteIdChanged(subject, p, persistenceIdEvent, testPropertyEvent);
              deferred.callback(true);
            }
            catch (error) {
              deferred.errback(error);
            }
          },
          function(problem) {
            try {
              if (error) {
                console.log("Expected error message: " + error);
                testDeleteNothingChanged(subject, p, persistenceIdEvent, testPropertyEvent, tracker1);
              }
              else if (semanticException) {
                doh.is(semanticException, problem);
                testDeleteNothingChanged(subject, p, persistenceIdEvent, testPropertyEvent, tracker1);
              }
              else {
                doh.fail();
              }
              deferred.callback(true);
            }
            catch (error) {
              deferred.errback(error);
            }
          }
        );
        return deferred;
      }

      doh.register("CrudDao (Mock)", [

        function testConstructor() {
          var subject = new CrudDaoMock();
        },

        {
          name: "base url 1",
          setUp: subjectSetup,
          runTest: function(){
            var result = this.subject.getUrl(PersistentObject, "777");
            console.log(result);
            doh.is(baseUrl1 + PersistentObject.prototype.declaredClass.replace(/\./g, "/") + "/777", result);
          }
        },

        {
          name: "base url 2",
          setUp: subjectSetup,
          runTest: function(){
            var result = this.subject.getUrl(PersistentObject);
            console.log(result);
            doh.is(baseUrl1 + PersistentObject.prototype.declaredClass.replace(/\./g, "/"), result);
          }
        },

        {
          name: "track1",
          setUp: subjectSetup,
          runTest: function() {
            var p = new MockPo({persistenceId: 777});
            var tracker = {};
            this.subject.track(p, tracker);
            var ce = this.subject._getExistingCacheEntry(p);
            doh.t(this.subject._getExistingCacheEntry(p));
            doh.is(p, ce.persistentObject);
            doh.is(1, ce.getNrOfReferers());
            doh.t(ce._referers.contains(tracker));
          }
        },

        {
          name: "track2",
          setUp: subjectSetup,
          runTest: function() {
            var p = new MockPo({persistenceId: 777});
            var tracker = {};
            this.subject.track(p, tracker);
            this.subject.track(p, tracker);
            var ce = this.subject._getExistingCacheEntry(p);
            doh.t(this.subject._getExistingCacheEntry(p));
            doh.is(p, ce.persistentObject);
            doh.is(1, ce.getNrOfReferers());
            doh.t(ce._referers.contains(tracker));
          }
        },

        {
          name: "track3",
          setUp: subjectSetup,
          runTest: function() {
            var p = new MockPo({persistenceId: 777});
            var tracker1 = {};
            var tracker2 = 6;
            this.subject.track(p, tracker1);
            this.subject.track(p, tracker2);
            var ce = this.subject._getExistingCacheEntry(p);
            doh.t(this.subject._getExistingCacheEntry(p));
            doh.is(p, ce.persistentObject);
            doh.is(2, ce.getNrOfReferers());
            doh.t(ce._referers.contains(tracker1));
            doh.t(ce._referers.contains(tracker2));
          }
        },

        {
          name: "stopTracking1",
          setUp: subjectSetup,
          runTest: function() {
            var p = new MockPo({persistenceId: 777});
            var tracker1 = {};
            var tracker2 = 6;
            this.subject.track(p, tracker1);
            this.subject.track(p, tracker2);
            this.subject.stopTracking(p, tracker2);
            var ce = this.subject._getExistingCacheEntry(p);
            doh.t(this.subject._getExistingCacheEntry(p));
            doh.is(p, ce.persistentObject);
            doh.is(1, ce.getNrOfReferers());
            doh.t(ce._referers.contains(tracker1));
          }
        },

        {
          name: "stopTracking2",
          setUp: subjectSetup,
          runTest: function() {
            var p = new MockPo({persistenceId: 777});
            var tracker1 = {};
            var tracker2 = 6;
            this.subject.track(p, tracker1);
            this.subject.track(p, tracker2);
            this.subject.stopTracking(p, tracker2);
            var ce = this.subject._getExistingCacheEntry(p);
            var key = ce.getKey();
            this.subject.stopTracking(p, tracker1);
            ce = this.subject._cache[key];
            doh.f(ce);
          }
        },

        {
          name: "_noLongerInServer",
          setUp: subjectSetup,
          runTest: function() {
            var p = new MockPo({persistenceId: 777});
            var tracker1 = {};
            var tracker2 = 6;
            this.subject.track(p, tracker1);
            this.subject.track(p, tracker2);
            var ce = this.subject._getExistingCacheEntry(p);
            var key = ce.getKey();
            this.subject._noLongerInServer(ce);
            ce = this.subject._cache[key];
            doh.f(ce);
            doh.is(null, p.persistenceId);
          }
        },

        {
          name: "create1",
          setUp: subjectSetup,
          runTest: function() {
            return testCreate(this.subject);
          }
        },

        {
          name: "create2",
          setUp: subjectSetup,
          runTest: function() {
            return testCreate(this.subject, 1500);
          },
          timeout: 3000
        },

        {
          name: "create3",
          setUp: subjectSetup,
          runTest: function() {
            return testCreate(this.subject, 0, "SemanticException");
          }
        },

        {
          name: "create4",
          setUp: subjectSetup,
          runTest: function() {
            return testCreate(this.subject, 1500, "SemanticException");
          },
          timeout: 3000
        },

        {
          name: "create5",
          setUp: subjectSetup,
          runTest: function() {
            return testCreate(this.subject, 0, null, "AN ERROR");
          }
        },

        {
          name: "create6",
          setUp: subjectSetup,
          runTest: function() {
            return testCreate(this.subject, 1500, null, "AN ERROR");
          },
          timeout: 3000
        },

        {
          name: "update1",
          setUp: subjectSetup,
          runTest: function() {
            return testUpdate(this.subject);
          }
        },

        {
          name: "update2",
          setUp: subjectSetup,
          runTest: function() {
            return testUpdate(this.subject, 1500);
          },
          timeout: 3000
        },

        {
          name: "update3",
          setUp: subjectSetup,
          runTest: function() {
            return testUpdate(this.subject, 0, "SemanticException");
          }
        },

        {
          name: "update4",
          setUp: subjectSetup,
          runTest: function() {
            return testUpdate(this.subject, 1500, "SemanticException");
          },
          timeout: 3000
        },

        {
          name: "update5",
          setUp: subjectSetup,
          runTest: function() {
            return testUpdate(this.subject, 0, new IdNotFoundException());
          }
        },

        {
          name: "update6",
          setUp: subjectSetup,
          runTest: function() {
            return testUpdate(this.subject, 1500, new IdNotFoundException());
          },
          timeout: 3000
        },

        {
          name: "update7",
          setUp: subjectSetup,
          runTest: function() {
            return testUpdate(this.subject, 0, null, "AN ERROR");
          }
        },

        {
          name: "update8",
          setUp: subjectSetup,
          runTest: function() {
            return testUpdate(this.subject, 1500, null, "AN ERROR");
          },
          timeout: 3000
        },

        {
          name: "delete1",
          setUp: subjectSetup,
          runTest: function() {
            return testDelete(this.subject);
          }
        },

        {
          name: "delete2",
          setUp: subjectSetup,
          runTest: function() {
            return testDelete(this.subject, 1500);
          },
          timeout: 3000
        },

        {
          name: "delete3",
          setUp: subjectSetup,
          runTest: function() {
            return testDelete(this.subject, 0, "SemanticException");
          }
        },

        {
          name: "delete4",
          setUp: subjectSetup,
          runTest: function() {
            return testDelete(this.subject, 1500, "SemanticException");
          },
          timeout: 3000
        },

        {
          name: "delete5",
          setUp: subjectSetup,
          runTest: function() {
            return testDelete(this.subject, 0, null, "AN ERROR");
          }
        },

        {
          name: "delete6",
          setUp: subjectSetup,
          runTest: function() {
            return testDelete(this.subject, 1500, null, "AN ERROR");
          },
          timeout: 3000
        }

      ]);
    }
);
<|endoftext|>


<commit_before>describe("chorus.views.DatasetItem", function() {
    function itRendersTheNameAndIcon() {
        it("renders the dataset's name", function() {
            expect(this.view.$(".name")).toContainText("john_the_table");
        });

        it("renders an icon for the dataset", function() {
            expect(this.view.$("img")).toHaveAttr("src", this.dataset.iconUrl());
            expect(this.view.$("img")).toHaveAttr("title", Handlebars.helpers.humanizedDatasetType(this.dataset.attributes));
        });
    }

    beforeEach(function() {
        this.dataset = backboneFixtures.workspaceDataset.datasetTable({
            objectName: "john_the_table"
        });
        this.qtipSpy = stubQtip();
        this.view = new chorus.views.DatasetItem({ model: this.dataset, hasActiveWorkspace: true });
        this.view.render();
    });

    it('renders breadcrumbs for the data source, database and schema', function() {
        expect(this.view.$(".data_source")).toContainText(this.dataset.dataSource().get("name"));
        expect(this.view.$(".database")).toContainText(this.dataset.database().get("name"));
        expect(this.view.$(".schema")).toContainText(this.dataset.schema().get("name"));
    });

    it('attaches the data source model to the data source and database breadcrumbs', function() {
        expect(this.view.$(".data_source").data("data_source")).toEqual(this.dataset.dataSource().attributes);
        expect(this.view.$(".database").data("data_source")).toEqual(this.dataset.dataSource().attributes);
    });

    xdescribe("found in workspaces tooltip (when rendered from the schema browse page)", function() {
        beforeEach(function() {
            this.dataset = backboneFixtures.dataset();

            this.view = new chorus.views.DatasetItem({ model: this.dataset, hasActiveWorkspace: true });
            this.view.render();
        });

        it("is rendered", function() {
            expect(this.view.$(".found_in")).toContainText("Hoge");
        });

        it("qtip-ifies the other_menu", function() {
            expect(this.qtipSpy).not.toHaveVisibleQtip();
            this.view.$('.found_in .open_other_menu').click();
            expect(this.qtipSpy).toHaveVisibleQtip();
            expect(this.qtipSpy.find('li').length).toBe(2);
        });

        context("when the dataset is not used in any workspace", function() {
            beforeEach(function() {
                this.dataset.unset("workspaceUsed");
                delete this.dataset._workspaceAssociated;
                this.view.render();
            });

            it("renders successfully without the workspace usage section", function() {
                expect(this.view.$(".found_in")).not.toExist();
            });
        });
    });

    xdescribe("when the workspace is archived", function() {
        beforeEach(function() {
            this.view.options.hasActiveWorkspace = false;
            this.view.render();
        });

        it('does not have dataset links (still has data source links)', function() {
            expect(this.view.$("a.image")).not.toExist();
            expect(this.view.$("a.name")).not.toExist();
        });
    });

    context("when the user has credentials to view the dataset", function() {
        itRendersTheNameAndIcon();

        it("links the dataset name and icon to its show page", function() {
            expect(this.view.$(".name")).toHaveHref(this.dataset.showUrl());
            expect(this.view.$(".image")).toHaveHref(this.dataset.showUrl());
        });
    });

    context("when the user does not have credentials to view the dataset", function() {
        beforeEach(function() {
            this.dataset.set({hasCredentials: false});
        });

        it("adds the 'no_credentials' class to the element", function() {
            expect($(this.view.el)).toHaveClass("no_credentials");
        });

        itRendersTheNameAndIcon();

        it("does not link the dataset name or icon to its show page", function() {
            expect(this.view.$(".name")).toBe("span");
            expect(this.view.$(".image")).toBe("span");
        });
    });

    context("when the dataset has a comment", function() {
        beforeEach(function() {
            this.dataset.set({ recentComments: [{
                body: "I love you john.",
                author: {
                    id: "1",
                    lastName: "Smith",
                    firstName: "Bob"
                },
                timestamp: "2011-12-15T12:34:56Z"
            }]});
        });

        it("renders the most recent comment", function() {
            expect(this.view.$(".comment .body")).toContainText("I love you john.");
            expect(this.view.$(".comment a")).toContainText("Bob Smith");
            expect(this.view.$(".comment_info .on")).toContainText("Dec 15");
        });

        it("does not display the 'other comments' text", function() {
            expect(this.view.$(".comment")).not.toContainText(t("comments.other_comments", {count: 0}));
        });

    });

    context("when there are no comments", function() {
        beforeEach(function() {
            this.dataset.unset("recentComments");
        });

        it("does not display the most recent comment", function() {
            expect(this.view.$(".comment")).not.toExist();
        });
    });

    context("when the dataset has more than one comment", function() {
        beforeEach(function() {
            this.dataset.set({ commentCount: 3 });
        });

        it("displays the 'other comments' text", function() {
            expect(this.view.$(".comment")).toContainText(t("comments.other_comments", { count: 2 }));
        });
    });

    context("when the model has an import schedule", function() {
        beforeEach(function() {
            this.dataset.set({ frequency: "WEEKLY"});
        });

        it("displays the correct import tag", function() {
            expect(this.view.$(".tag .tag_name").text()).toContainTranslation("import.frequency.weekly");
        });
    });

    context("when the model does not have an import schedule", function() {
        beforeEach(function() {
            this.dataset.unset("frequency");
        });

        it("does not display the import tag", function() {
            expect(this.view.$(".tag")).not.toExist();
        });
    });

    context("when the dataset has tags", function () {
        beforeEach(function () {
            this.dataset.tags().reset([{name: "tag1"}, {name: "tag2"}]);
            this.view.render();
        });

        it("shows a list of tags", function () {
            expect(this.view.$('.item_tag_list')).toContainTranslation("tag_list.title");
            expect(this.view.$('.item_tag_list')).toContainText("tag1 tag2");
        });
    });

    it("works with database objects as well as datasets", function() {
        var table = backboneFixtures.dataset({objectName: 'yyy'});
        var view = new chorus.views.DatasetItem({ model: table });
        view.render();
        expect(view.$(".name")).toHaveHref(table.showUrl());
        expect(view.$(".image")).toHaveHref(table.showUrl());
    });

    describe("when the model received an 'invalidated' trigger", function() {
        beforeEach(function() {
            spyOn(this.dataset, "fetch");
        });

        it("reloads the model", function() {
            this.dataset.trigger("invalidated");
            expect(this.dataset.fetch).toHaveBeenCalled();
        });
    });

    describe("presenting tags", function() {
        beforeEach(function() {
            this.model = this.dataset;
        });

        itBehavesLike.ItPresentsModelWithTags();
    });

    context("when the dataset is an HDFS file mask posing as dataset", function () {
        beforeEach(function() {
            this.dataset = backboneFixtures.workspaceDataset.hdfsDataset({
                objectName: "john_the_table"
            });
            this.qtipSpy = stubQtip();
            this.view = new chorus.views.DatasetItem({ model: this.dataset, hasActiveWorkspace: true });
            this.view.render();
        });

        it('renders breadcrumbs for the data source, database and schema', function() {
            expect(this.view.$(".data_source")).toContainText(this.dataset.dataSource().get("name"));
            expect(this.view.$(".database")).not.toExist();
            expect(this.view.$(".schema")).not.toExist();
        });

        it('attaches the data source model to the data source and database breadcrumbs', function() {
            expect(this.view.$(".data_source").data("data_source")).toEqual(this.dataset.dataSource().attributes);
            expect(this.view.$(".database").data("data_source")).toEqual(this.dataset.dataSource().attributes);
        });

        context("when the user has credentials to view the dataset", function() {
            itRendersTheNameAndIcon();

            it("links the dataset name and icon to its show page", function() {
                expect(this.view.$(".name")).toHaveHref(this.dataset.showUrl());
                expect(this.view.$(".image")).toHaveHref(this.dataset.showUrl());
            });
        });

        context("when the user does not have credentials to view the dataset", function() {
            beforeEach(function() {
                this.dataset.set({hasCredentials: false});
            });

            it("adds the 'no_credentials' class to the element", function() {
                expect($(this.view.el)).toHaveClass("no_credentials");
            });

            itRendersTheNameAndIcon();

            it("does not link the dataset name or icon to its show page", function() {
                expect(this.view.$(".name")).toBe("span");
                expect(this.view.$(".image")).toBe("span");
            });
        });

        context("when the dataset has a comment", function() {
            beforeEach(function() {
                this.dataset.set({ recentComments: [{
                    body: "I love you john.",
                    author: {
                        id: "1",
                        lastName: "Smith",
                        firstName: "Bob"
                    },
                    timestamp: "2011-12-15T12:34:56Z"
                }]});
            });

            it("renders the most recent comment", function() {
                expect(this.view.$(".comment .body")).toContainText("I love you john.");
                expect(this.view.$(".comment a")).toContainText("Bob Smith");
                expect(this.view.$(".comment_info .on")).toContainText("Dec 15");
            });

            it("does not display the 'other comments' text", function() {
                expect(this.view.$(".comment")).not.toContainText(t("comments.other_comments", {count: 0}));
            });

        });

        context("when there are no comments", function() {
            beforeEach(function() {
                this.dataset.unset("recentComments");
            });

            it("does not display the most recent comment", function() {
                expect(this.view.$(".comment")).not.toExist();
            });
        });

        context("when the dataset has more than one comment", function() {
            beforeEach(function() {
                this.dataset.set({ commentCount: 3 });
            });

            it("displays the 'other comments' text", function() {
                expect(this.view.$(".comment")).toContainText(t("comments.other_comments", { count: 2 }));
            });
        });

        context("when the model has an import schedule", function() {
            beforeEach(function() {
                this.dataset.set({ frequency: "WEEKLY"});
            });

            it("displays the correct import tag", function() {
                expect(this.view.$(".tag .tag_name").text()).toContainTranslation("import.frequency.weekly");
            });
        });

        context("when the model does not have an import schedule", function() {
            beforeEach(function() {
                this.dataset.unset("frequency");
            });

            it("does not display the import tag", function() {
                expect(this.view.$(".tag")).not.toExist();
            });
        });

        context("when the dataset has tags", function () {
            beforeEach(function () {
                this.dataset.tags().reset([{name: "tag1"}, {name: "tag2"}]);
                this.view.render();
            });

            it("shows a list of tags", function () {
                expect(this.view.$('.item_tag_list')).toContainTranslation("tag_list.title");
                expect(this.view.$('.item_tag_list')).toContainText("tag1 tag2");
            });
        });

        it("works with database objects as well as datasets", function() {
            var table = backboneFixtures.dataset({objectName: 'yyy'});
            var view = new chorus.views.DatasetItem({ model: table });
            view.render();
            expect(view.$(".name")).toHaveHref(table.showUrl());
            expect(view.$(".image")).toHaveHref(table.showUrl());
        });

        describe("when the model received an 'invalidated' trigger", function() {
            beforeEach(function() {
                spyOn(this.dataset, "fetch");
            });

            it("reloads the model", function() {
                this.dataset.trigger("invalidated");
                expect(this.dataset.fetch).toHaveBeenCalled();
            });
        });

        describe("presenting tags", function() {
            beforeEach(function() {
                this.model = this.dataset;
            });

            itBehavesLike.ItPresentsModelWithTags();
        });
    });
});
<commit_msg>Fix specs<commit_after>describe("chorus.views.DatasetItem", function() {
    function itRendersTheNameAndIcon() {
        it("renders the dataset's name", function() {
            expect(this.view.$(".name")).toContainText("john_the_table");
        });

        it("renders an icon for the dataset", function() {
            expect(this.view.$("img")).toHaveAttr("src", this.dataset.iconUrl());
            expect(this.view.$("img")).toHaveAttr("title", Handlebars.helpers.humanizedDatasetType(this.dataset.attributes));
        });
    }

    beforeEach(function() {
        this.dataset = backboneFixtures.workspaceDataset.datasetTable({
            objectName: "john_the_table"
        });
        this.qtipSpy = stubQtip();
        this.view = new chorus.views.DatasetItem({ model: this.dataset, hasActiveWorkspace: true });
        this.view.render();
    });

    it('renders breadcrumbs for the data source, database and schema', function() {
        expect(this.view.$(".data_source")).toContainText(this.dataset.dataSource().get("name"));
        expect(this.view.$(".database")).toContainText(this.dataset.database().get("name"));
        expect(this.view.$(".schema")).toContainText(this.dataset.schema().get("name"));
    });

    it('attaches the data source model to the data source and database breadcrumbs', function() {
        expect(this.view.$(".data_source").data("data_source")).toEqual(this.dataset.dataSource().attributes);
        expect(this.view.$(".database").data("data_source")).toEqual(this.dataset.dataSource().attributes);
    });

    xdescribe("found in workspaces tooltip (when rendered from the schema browse page)", function() {
        beforeEach(function() {
            this.dataset = backboneFixtures.dataset();

            this.view = new chorus.views.DatasetItem({ model: this.dataset, hasActiveWorkspace: true });
            this.view.render();
        });

        it("is rendered", function() {
            expect(this.view.$(".found_in")).toContainText("Hoge");
        });

        it("qtip-ifies the other_menu", function() {
            expect(this.qtipSpy).not.toHaveVisibleQtip();
            this.view.$('.found_in .open_other_menu').click();
            expect(this.qtipSpy).toHaveVisibleQtip();
            expect(this.qtipSpy.find('li').length).toBe(2);
        });

        context("when the dataset is not used in any workspace", function() {
            beforeEach(function() {
                this.dataset.unset("workspaceUsed");
                delete this.dataset._workspaceAssociated;
                this.view.render();
            });

            it("renders successfully without the workspace usage section", function() {
                expect(this.view.$(".found_in")).not.toExist();
            });
        });
    });

    xdescribe("when the workspace is archived", function() {
        beforeEach(function() {
            this.view.options.hasActiveWorkspace = false;
            this.view.render();
        });

        it('does not have dataset links (still has data source links)', function() {
            expect(this.view.$("a.image")).not.toExist();
            expect(this.view.$("a.name")).not.toExist();
        });
    });

    context("when the user has credentials to view the dataset", function() {
        itRendersTheNameAndIcon();

        it("links the dataset name and icon to its show page", function() {
            expect(this.view.$(".name")).toHaveHref(this.dataset.showUrl());
            expect(this.view.$(".image")).toHaveHref(this.dataset.showUrl());
        });
    });

    context("when the user does not have credentials to view the dataset", function() {
        beforeEach(function() {
            this.dataset.set({hasCredentials: false});
        });

        it("adds the 'no_credentials' class to the element", function() {
            expect($(this.view.el)).toHaveClass("no_credentials");
        });

        itRendersTheNameAndIcon();

        it("does not link the dataset name or icon to its show page", function() {
            expect(this.view.$(".name")).toBe("span");
            expect(this.view.$(".image")).toBe("span");
        });
    });

    context("when the dataset has a comment", function() {
        beforeEach(function() {
            this.dataset.set({ recentComments: [{
                body: "I love you john.",
                author: {
                    id: "1",
                    lastName: "Smith",
                    firstName: "Bob"
                },
                timestamp: "2011-12-15T12:34:56Z"
            }]});
        });

        it("renders the most recent comment", function() {
            expect(this.view.$(".comment .body")).toContainText("I love you john.");
            expect(this.view.$(".comment a")).toContainText("Bob Smith");
            expect(this.view.$(".comment_info .on")).toContainText("Dec 15");
        });

        it("does not display the 'other comments' text", function() {
            expect(this.view.$(".comment")).not.toContainText(t("comments.other_comments", {count: 0}));
        });

    });

    context("when there are no comments", function() {
        beforeEach(function() {
            this.dataset.unset("recentComments");
        });

        it("does not display the most recent comment", function() {
            expect(this.view.$(".comment")).not.toExist();
        });
    });

    context("when the dataset has more than one comment", function() {
        beforeEach(function() {
            this.dataset.set({ commentCount: 3 });
        });

        it("displays the 'other comments' text", function() {
            expect(this.view.$(".comment")).toContainText(t("comments.other_comments", { count: 2 }));
        });
    });

    context("when the model has an import schedule", function() {
        beforeEach(function() {
            this.dataset.set({ frequency: "WEEKLY"});
        });

        it("displays the correct import tag", function() {
            expect(this.view.$(".tag .tag_name").text()).toContainTranslation("import.frequency.weekly");
        });
    });

    context("when the model does not have an import schedule", function() {
        beforeEach(function() {
            this.dataset.unset("frequency");
        });

        it("does not display the import tag", function() {
            expect(this.view.$(".tag")).not.toExist();
        });
    });

    context("when the dataset has tags", function () {
        beforeEach(function () {
            this.dataset.tags().reset([{name: "tag1"}, {name: "tag2"}]);
            this.view.render();
        });

        it("shows a list of tags", function () {
            expect(this.view.$('.item_tag_list')).toContainTranslation("tag_list.title");
            expect(this.view.$('.item_tag_list')).toContainText("tag1 tag2");
        });
    });

    it("works with database objects as well as datasets", function() {
        var table = backboneFixtures.dataset({objectName: 'yyy'});
        var view = new chorus.views.DatasetItem({ model: table });
        view.render();
        expect(view.$(".name")).toHaveHref(table.showUrl());
        expect(view.$(".image")).toHaveHref(table.showUrl());
    });

    describe("when the model received an 'invalidated' trigger", function() {
        beforeEach(function() {
            spyOn(this.dataset, "fetch");
        });

        it("reloads the model", function() {
            this.dataset.trigger("invalidated");
            expect(this.dataset.fetch).toHaveBeenCalled();
        });
    });

    describe("presenting tags", function() {
        beforeEach(function() {
            this.model = this.dataset;
        });

        itBehavesLike.ItPresentsModelWithTags();
    });

    context("when the dataset is an HDFS file mask posing as dataset", function () {
        beforeEach(function() {
            this.dataset = backboneFixtures.workspaceDataset.hdfsDataset({
                objectName: "john_the_table"
            });
            this.qtipSpy = stubQtip();
            this.view = new chorus.views.DatasetItem({ model: this.dataset, hasActiveWorkspace: true });
            this.view.render();
        });

        it('renders breadcrumbs for the data source, database and schema', function() {
            expect(this.view.$(".data_source")).toContainText(this.dataset.dataSource().get("name"));
            expect(this.view.$(".database")).not.toExist();
            expect(this.view.$(".schema")).not.toExist();
        });

        it('attaches the data source model to the data source and database breadcrumbs', function() {
            expect(this.view.$(".data_source").data("data_source")).toEqual(this.dataset.dataSource().attributes);
            expect(this.view.$(".database").data("data_source")).not.toExist();
        });

        context("when the user has credentials to view the dataset", function() {
            itRendersTheNameAndIcon();

            it("links the dataset name and icon to its show page", function() {
                expect(this.view.$(".name")).toHaveHref(this.dataset.showUrl());
                expect(this.view.$(".image")).toHaveHref(this.dataset.showUrl());
            });
        });

        context("when the user does not have credentials to view the dataset", function() {
            beforeEach(function() {
                this.dataset.set({hasCredentials: false});
            });

            it("adds the 'no_credentials' class to the element", function() {
                expect($(this.view.el)).toHaveClass("no_credentials");
            });

            itRendersTheNameAndIcon();

            it("does not link the dataset name or icon to its show page", function() {
                expect(this.view.$(".name")).toBe("span");
                expect(this.view.$(".image")).toBe("span");
            });
        });

        context("when the dataset has a comment", function() {
            beforeEach(function() {
                this.author = {
                    id: "1",
                    lastName: "Buganvilia",
                    firstName: "Sally"
                };

                this.dataset.set({ recentComments: [{
                    body: "I love you john.",
                    author: this.author,
                    timestamp: "2011-12-15T12:34:56Z"
                }]});
            });

            it("renders the most recent comment", function() {
                expect(this.view.$(".comment .body")).toContainText("I love you john.");
                expect(this.view.$(".comment a")).toContainText(this.author.firstName + ' ' + this.author.lastName);
                expect(this.view.$(".comment_info .on")).toContainText("Dec 15");
            });

            it("does not display the 'other comments' text", function() {
                expect(this.view.$(".comment")).not.toContainText(t("comments.other_comments", {count: 0}));
            });

            context("when the dataset has more than one comment", function() {
                beforeEach(function() {
                    this.dataset.set({ commentCount: 3 });
                });

                it("displays the 'other comments' text", function() {
                    var $comment = this.view.$(".comment");
                    var text = t("comments.other_comments", { count: 2 });

                    expect($comment).toContainText(text);
                });
            });
        });

        context("when there are no comments", function() {
            beforeEach(function() {
                this.dataset.unset("recentComments");
            });

            it("does not display the most recent comment", function() {
                expect(this.view.$(".comment")).not.toExist();
            });
        });

        context("when the model has an import schedule", function() {
            beforeEach(function() {
                this.dataset.set({ frequency: "WEEKLY"});
            });

            it("displays the correct import tag", function() {
                expect(this.view.$(".tag .tag_name").text()).toContainTranslation("import.frequency.weekly");
            });
        });

        context("when the model does not have an import schedule", function() {
            beforeEach(function() {
                this.dataset.unset("frequency");
            });

            it("does not display the import tag", function() {
                expect(this.view.$(".tag")).not.toExist();
            });
        });

        context("when the dataset has tags", function () {
            beforeEach(function () {
                this.dataset.tags().reset([{name: "tag1"}, {name: "tag2"}]);
                this.view.render();
            });

            it("shows a list of tags", function () {
                expect(this.view.$('.item_tag_list')).toContainTranslation("tag_list.title");
                expect(this.view.$('.item_tag_list')).toContainText("tag1 tag2");
            });
        });

        it("works with database objects as well as datasets", function() {
            var table = backboneFixtures.dataset({objectName: 'yyy'});
            var view = new chorus.views.DatasetItem({ model: table });
            view.render();
            expect(view.$(".name")).toHaveHref(table.showUrl());
            expect(view.$(".image")).toHaveHref(table.showUrl());
        });

        describe("when the model received an 'invalidated' trigger", function() {
            beforeEach(function() {
                spyOn(this.dataset, "fetch");
            });

            it("reloads the model", function() {
                this.dataset.trigger("invalidated");
                expect(this.dataset.fetch).toHaveBeenCalled();
            });
        });

        describe("presenting tags", function() {
            beforeEach(function() {
                this.model = this.dataset;
            });

            itBehavesLike.ItPresentsModelWithTags();
        });
    });
});
<|endoftext|>


<commit_before>const deep = require('deep-diff').diff;
const fs = require('fs');
const JSZip = require('jszip');
const path = require('path');
const request = require('request');

const diffTfvars = (client, assetsZip, expected) => {
  JSZip.loadAsync(assetsZip).then(zip => {
    zip.file(/tfvars$/)[0].async('string').then(tfvars => {
      const diff = deep(JSON.parse(tfvars), expected);
      if (diff !== undefined) {
        client.assert.fail(
          'The following terraform.tfvars attributes differ from their expected value: ' +
          diff.map(({attr, lhs, rhs}) => `${attr} (expected: ${rhs}, got: ${lhs})`).join(', ')
        );
      }
    });
  });
};

const testManualBoot = (client, expectedFilename) => {
  client.page.submitPage()
    .click('@manuallyBoot')
    .expect.element('a[href="/terraform/assets"]').to.be.visible.before(120000);

  client.getCookie('tectonic-installer', ({value}) => {
    const options = {
      url: `${client.launch_url}/terraform/assets`,
      method: 'GET',
      encoding: null,
      headers: {'Cookie': `tectonic-installer=${value}`},
    };
    request(options, (err, res, assetsZip) => {
      if (err) {
        return client.assert.fail(err);
      }
      if (res.statusCode !== 200 || res.headers['content-type'] !== 'application/zip') {
        return client.assert.fail('Terraform get assets API call failed');
      }

      // eslint-disable-next-line no-sync
      const expected = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'output', expectedFilename), 'utf8'));

      diffTfvars(client, assetsZip, expected);
    });
  });
};

const jsonDir = path.join(__dirname, '..', '..', '__tests__', 'examples');
// eslint-disable-next-line no-sync
const loadJson = filename => JSON.parse(fs.readFileSync(path.join(jsonDir, filename), 'utf8'));

module.exports = {
  loadJson,
  testManualBoot,
};
<commit_msg>frontend: Fix Nightwatch test diff output and make it more readable<commit_after>const deep = require('deep-diff').diff;
const fs = require('fs');
const JSZip = require('jszip');
const path = require('path');
const request = require('request');

const diffTfvars = (client, assetsZip, expected) => {
  JSZip.loadAsync(assetsZip).then(zip => {
    zip.file(/tfvars$/)[0].async('string').then(tfvars => {
      const diff = deep(JSON.parse(tfvars), expected);
      if (diff !== undefined) {
        client.assert.fail(
          'The following terraform.tfvars attributes differ from their expected value: ' +
          diff.map(d => `\n  ${d.path.join('.')} (expected: ${d.rhs}, got: ${d.lhs})`)
        );
      }
    });
  });
};

const testManualBoot = (client, expectedFilename) => {
  client.page.submitPage()
    .click('@manuallyBoot')
    .expect.element('a[href="/terraform/assets"]').to.be.visible.before(120000);

  client.getCookie('tectonic-installer', ({value}) => {
    const options = {
      url: `${client.launch_url}/terraform/assets`,
      method: 'GET',
      encoding: null,
      headers: {'Cookie': `tectonic-installer=${value}`},
    };
    request(options, (err, res, assetsZip) => {
      if (err) {
        return client.assert.fail(err);
      }
      if (res.statusCode !== 200 || res.headers['content-type'] !== 'application/zip') {
        return client.assert.fail('Terraform get assets API call failed');
      }

      // eslint-disable-next-line no-sync
      const expected = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'output', expectedFilename), 'utf8'));

      diffTfvars(client, assetsZip, expected);
    });
  });
};

const jsonDir = path.join(__dirname, '..', '..', '__tests__', 'examples');
// eslint-disable-next-line no-sync
const loadJson = filename => JSON.parse(fs.readFileSync(path.join(jsonDir, filename), 'utf8'));

module.exports = {
  loadJson,
  testManualBoot,
};
<|endoftext|>


<commit_before>define(function(require, exports, module) {
  "use strict";

  var cc = require("../cc");

  var AudioAPI;

  if (typeof document !== "undefined") {
    var AudioContext = global.AudioContext || global.webkitAudioContext;
    if (AudioContext) {
      AudioAPI = (function() {
        function WebAudioAPI(sys, opts) {
          this.sys = sys;
          this.context = opts.AudioContext || new AudioContext();
          this.sampleRate = this.context.sampleRate;
          this.channels   = 2;
          this.type = "Web Audio API";
          this.delegate = !!opts.AudioContext;
        }
        WebAudioAPI.prototype.init = function() {
          var sys = this.sys;
          var onaudioprocess;
          var strm = sys.strm;
          var strmLength = sys.strmLength;
          if (this.sys.speaker) {
            if (this.sys.sampleRate === this.sampleRate) {
              onaudioprocess = function(e) {
                var outs = e.outputBuffer;
                var outL = outs.getChannelData(0);
                var outR = outs.getChannelData(1);
                var i = strmLength, j = strmLength << 1;
                sys.process();
                while (j--, i--) {
                  outL[i] = strm[i] * 0.000030517578125;
                  outR[i] = strm[j] * 0.000030517578125;
                }
              };
            }
          } else {
            onaudioprocess = function() {
              sys.process();
            };
          }
          this.bufSrc = this.context.createBufferSource();
          this.jsNode = this.context.createJavaScriptNode(strmLength, 2, this.channels);
          this.jsNode.onaudioprocess = onaudioprocess;
        };
        WebAudioAPI.prototype.play = function() {
          if (!this.bufSrc) {
            return; // TODO: throw an error
          }
          this.bufSrc.noteOn(0);
          this.bufSrc.connect(this.jsNode);
          if (!this.delegate) {
            this.jsNode.connect(this.context.destination);
          }
        };
        WebAudioAPI.prototype.pause = function() {
          if (!this.bufSrc) {
            return; // TODO: throw an error
          }
          this.bufSrc.disconnect();
          if (!this.delegate) {
            this.jsNode.disconnect();
          }
        };
        WebAudioAPI.prototype.decodeAudioFile = function(buffer, callback) {
          buffer = this.context.createBuffer(buffer, false);
          var bufLength   = buffer.length;
          var numChannels = buffer.numberOfChannels;
          var numSamples  = bufLength * numChannels;
          var samples = new Float32Array(numSamples);
          var i, j, k = 0;
          var channelData = new Array(numChannels);
          for (j = 0; j < numChannels; ++j) {
            channelData[j] = buffer.getChannelData(j);
          }
          for (i = 0; i < bufLength; ++i) {
            for (j = 0; j < numChannels; ++j) {
              samples[k++] = channelData[j][i];
            }
          }
          callback({
            sampleRate : buffer.sampleRate,
            numChannels: buffer.numberOfChannels,
            numFrames  : buffer.length,
            samples    : samples,
          });
        };
        return WebAudioAPI;
      })();
    } else if (typeof Audio === "function" && typeof new Audio().mozSetup === "function") {
      AudioAPI = (function() {
        /*global URL:true */
        var timer = (function() {
          var source = "var t=0;onmessage=function(e){if(t)t=clearInterval(t),0;if(typeof e.data=='number'&&e.data>0)t=setInterval(function(){postMessage(0);},e.data);};";
          var blob = new Blob([source], {type:"text/javascript"});
          var path = URL.createObjectURL(blob);
          return new Worker(path);
        })();
        /*global URL:false */
        function AudioDataAPI(sys) {
          this.sys = sys;
          this.sampleRate = 44100;
          this.channels   = 2;
          this.type = "Audio Data API";
        }
        AudioDataAPI.prototype.init = function() {
          this.audio = new Audio();
          this.interleaved = new Float32Array(this.sys.strmLength * this.sys.channels);
        };
        AudioDataAPI.prototype.play = function() {
          if (!this.audio) {
            return; // TODO: throw an error
          }
          var sys = this.sys;
          var audio = this.audio;
          var interleaved = this.interleaved;
          var msec = (sys.strmLength / sys.sampleRate) * 1000;
          var written = 0;
          var start = Date.now();
          var inL = new Int16Array(sys.strm.buffer, 0, sys.strmLength);
          var inR = new Int16Array(sys.strm.buffer, sys.strmLength * 2);

          var onaudioprocess = function() {
            if (written > Date.now() - start) {
              return;
            }
            var i = interleaved.length;
            var j = inL.length;
            sys.process();
            while (j--) {
              interleaved[--i] = inR[j] * 0.000030517578125;
              interleaved[--i] = inL[j] * 0.000030517578125;
            }
            audio.mozWriteAudio(interleaved);
            written += msec;
          };

          audio.mozSetup(sys.channels, sys.sampleRate);
          timer.onmessage = onaudioprocess;
          timer.postMessage(msec * 0.8);
        };
        AudioDataAPI.prototype.pause = function() {
          if (!this.audio) {
            return; // TODO: throw an error
          }
          timer.postMessage(0);
        };
        return AudioDataAPI;
      })();
    }

    if (!AudioAPI) {
      AudioAPI = (function() {
        function FallbackAudioAPI(sys) {
          this.sys = sys;
          this.sampleRate = 44100;
          this.channels   = 2;
          this.type = "Fallback";
        }
        FallbackAudioAPI.prototype.init = function() {
        };
        FallbackAudioAPI.prototype.play = function() {
          if (fallback.play) {
            this.play = fallback.play;
            this.play();
          }
        };
        FallbackAudioAPI.prototype.pause = function() {
          if (fallback.pause) {
            this.pause = fallback.pause;
            this.pause();
          }
        };

        var fallback = {};
        window.addEventListener("load", function() {
          var swfSrc  = cc.rootPath + "coffee-collider-fallback.swf";
          var swfName = swfSrc + "?" + Date.now();
          var swfId   = "coffee-collider-fallback";
          var div = document.createElement("div");
          div.style.display = "inline";
          div.width  = 1;
          div.height = 1;
          /*jshint quotmark:single */
          div.innerHTML = '<object id="'+swfId+'" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="1" height="1"><param name="movie" value="'+swfName+'"/><param name="bgcolor" value="#FFFFFF"/><param name="quality" value="high"/><param name="allowScriptAccess" value="always"/></object>';
          /*jshint quotmark:double */
          document.body.appendChild(div);

          window.coffeecollider_flashfallback_init = function() {
            var swf = document.getElementById(swfId);
            var timerId = 0;
            fallback.play = function() {
              if (timerId === 0) {
                var sys = this.sys;
                var msec = (sys.strmLength / sys.sampleRate) * 1000;
                var written = 0;
                var start = Date.now();
                var out   = new Array(sys.strmLength * sys.channels);
                var len   = out.length;

                var onaudioprocess = function() {
                  if (written > Date.now() - start) {
                    return;
                  }
                  sys.process();
                  var _in = sys.strm;
                  for (var i = 0; i < len; ++i) {
                    out[i] = String.fromCharCode( ((_in[i] + 32768)>>1) + 16384 );
                  }
                  swf.writeAudio(out.join(""));
                  written += msec;
                };

                timerId = setInterval(onaudioprocess, msec * 0.8);
                swf.play();
              }
            };
            fallback.pause = function() {
              if (timerId !== 0) {
                swf.pause();
                clearInterval(timerId);
                timerId = 0;
              }
            };
          };
        });
        return FallbackAudioAPI;
      })();
    }
  } else if (typeof global.GLOBAL !== "undefined") {
    AudioAPI = (function() {
      var Readable = global.require("stream").Readable;
      var Speaker  = global.require("speaker");
      if (!Readable) {
        Readable = global.require("readable-stream/readable");
      }
      function NodeAudioAPI(sys) {
        this.sys = sys;
        this.sampleRate = C.SOCKET_SAMPLERATE;
        this.channels   = C.SOCKET_CHANNELS;
        this.node = null;
        this.isPlaying = false;
      }
      NodeAudioAPI.prototype.init = function() {
      };
      NodeAudioAPI.prototype.play = function() {
        var sys = this.sys;
        this.isPlaying = true;
        this.node = new Readable();
        this.node._read = function(n) {
          var strm = sys._strm;
          var strmLength = sys.strmLength;
          var buf  = new Buffer(n);
          var x, i, j, k = 0;
          n = (n >> 2) / sys.strmLength;
          x = strm;
          while (n--) {
            sys._process();
            for (i = 0, j = strmLength; i < strmLength; ++i, ++j) {
              buf.writeInt16LE(strm[i], k);
              k += 2;
              buf.writeInt16LE(strm[j], k);
              k += 2;
            }
          }
          this.push(buf);
        };
        this.node.pipe(new Speaker({sampleRate:this.sampleRate}));
      };
      NodeAudioAPI.prototype.pause = function() {
        if (this.node) {
          process.nextTick(this.node.emit.bind(this.node, "end"));
        }
        this.node = null;
        this.isPlaying = false;
      };
      return NodeAudioAPI;
    })();
  }

  module.exports = {
    AudioAPI: AudioAPI
  };

});
<commit_msg>Fixed AudioAPI for Firefox<commit_after>define(function(require, exports, module) {
  "use strict";

  var cc = require("../cc");

  var AudioAPI;

  if (typeof document !== "undefined") {
    var AudioContext = global.AudioContext || global.webkitAudioContext;
    if (AudioContext) {
      AudioAPI = (function() {
        function WebAudioAPI(sys, opts) {
          this.sys = sys;
          this.context = opts.AudioContext || new AudioContext();
          this.sampleRate = this.context.sampleRate;
          this.channels   = 2;
          this.type = "Web Audio API";
          this.delegate = !!opts.AudioContext;
        }
        WebAudioAPI.prototype.init = function() {
          var sys = this.sys;
          var onaudioprocess;
          var strm = sys.strm;
          var strmLength = sys.strmLength;
          if (this.sys.speaker) {
            if (this.sys.sampleRate === this.sampleRate) {
              onaudioprocess = function(e) {
                var outs = e.outputBuffer;
                var outL = outs.getChannelData(0);
                var outR = outs.getChannelData(1);
                var i = strmLength, j = strmLength << 1;
                sys.process();
                while (j--, i--) {
                  outL[i] = strm[i] * 0.000030517578125;
                  outR[i] = strm[j] * 0.000030517578125;
                }
              };
            }
          } else {
            onaudioprocess = function() {
              sys.process();
            };
          }
          this.bufSrc = this.context.createBufferSource();
          if (this.context.createScriptProcessor) {
            this.jsNode = this.context.createScriptProcessor(strmLength, 2, this.channels);
          } else {
            this.jsNode = this.context.createJavaScriptNode(strmLength, 2, this.channels);
          }
          this.jsNode.onaudioprocess = onaudioprocess;
        };
        WebAudioAPI.prototype.play = function() {
          if (!this.bufSrc) {
            return; // TODO: throw an error
          }
          if (this.bufSrc.noteOn) {
            this.bufSrc.noteOn(0);
            this.bufSrc.connect(this.jsNode);
          }
          if (!this.delegate) {
            this.jsNode.connect(this.context.destination);
          }
        };
        WebAudioAPI.prototype.pause = function() {
          if (!this.bufSrc) {
            return; // TODO: throw an error
          }
          this.bufSrc.disconnect();
          if (!this.delegate) {
            this.jsNode.disconnect();
          }
        };
        WebAudioAPI.prototype.decodeAudioFile = function(buffer, callback) {
          buffer = this.context.createBuffer(buffer, false);
          var bufLength   = buffer.length;
          var numChannels = buffer.numberOfChannels;
          var numSamples  = bufLength * numChannels;
          var samples = new Float32Array(numSamples);
          var i, j, k = 0;
          var channelData = new Array(numChannels);
          for (j = 0; j < numChannels; ++j) {
            channelData[j] = buffer.getChannelData(j);
          }
          for (i = 0; i < bufLength; ++i) {
            for (j = 0; j < numChannels; ++j) {
              samples[k++] = channelData[j][i];
            }
          }
          callback({
            sampleRate : buffer.sampleRate,
            numChannels: buffer.numberOfChannels,
            numFrames  : buffer.length,
            samples    : samples,
          });
        };
        return WebAudioAPI;
      })();
    } else if (typeof Audio === "function" && typeof new Audio().mozSetup === "function") {
      AudioAPI = (function() {
        /*global URL:true */
        var timer = (function() {
          var source = "var t=0;onmessage=function(e){if(t)t=clearInterval(t),0;if(typeof e.data=='number'&&e.data>0)t=setInterval(function(){postMessage(0);},e.data);};";
          var blob = new Blob([source], {type:"text/javascript"});
          var path = URL.createObjectURL(blob);
          return new Worker(path);
        })();
        /*global URL:false */
        function AudioDataAPI(sys) {
          this.sys = sys;
          this.sampleRate = 44100;
          this.channels   = 2;
          this.type = "Audio Data API";
        }
        AudioDataAPI.prototype.init = function() {
          this.audio = new Audio();
          this.interleaved = new Float32Array(this.sys.strmLength * this.sys.channels);
        };
        AudioDataAPI.prototype.play = function() {
          if (!this.audio) {
            return; // TODO: throw an error
          }
          var sys = this.sys;
          var audio = this.audio;
          var interleaved = this.interleaved;
          var msec = (sys.strmLength / sys.sampleRate) * 1000;
          var written = 0;
          var start = Date.now();
          var inL = new Int16Array(sys.strm.buffer, 0, sys.strmLength);
          var inR = new Int16Array(sys.strm.buffer, sys.strmLength * 2);

          var onaudioprocess = function() {
            if (written > Date.now() - start) {
              return;
            }
            var i = interleaved.length;
            var j = inL.length;
            sys.process();
            while (j--) {
              interleaved[--i] = inR[j] * 0.000030517578125;
              interleaved[--i] = inL[j] * 0.000030517578125;
            }
            audio.mozWriteAudio(interleaved);
            written += msec;
          };

          audio.mozSetup(sys.channels, sys.sampleRate);
          timer.onmessage = onaudioprocess;
          timer.postMessage(msec * 0.8);
        };
        AudioDataAPI.prototype.pause = function() {
          if (!this.audio) {
            return; // TODO: throw an error
          }
          timer.postMessage(0);
        };
        return AudioDataAPI;
      })();
    }

    if (!AudioAPI) {
      AudioAPI = (function() {
        function FallbackAudioAPI(sys) {
          this.sys = sys;
          this.sampleRate = 44100;
          this.channels   = 2;
          this.type = "Fallback";
        }
        FallbackAudioAPI.prototype.init = function() {
        };
        FallbackAudioAPI.prototype.play = function() {
          if (fallback.play) {
            this.play = fallback.play;
            this.play();
          }
        };
        FallbackAudioAPI.prototype.pause = function() {
          if (fallback.pause) {
            this.pause = fallback.pause;
            this.pause();
          }
        };

        var fallback = {};
        window.addEventListener("load", function() {
          var swfSrc  = cc.rootPath + "coffee-collider-fallback.swf";
          var swfName = swfSrc + "?" + Date.now();
          var swfId   = "coffee-collider-fallback";
          var div = document.createElement("div");
          div.style.display = "inline";
          div.width  = 1;
          div.height = 1;
          /*jshint quotmark:single */
          div.innerHTML = '<object id="'+swfId+'" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="1" height="1"><param name="movie" value="'+swfName+'"/><param name="bgcolor" value="#FFFFFF"/><param name="quality" value="high"/><param name="allowScriptAccess" value="always"/></object>';
          /*jshint quotmark:double */
          document.body.appendChild(div);

          window.coffeecollider_flashfallback_init = function() {
            var swf = document.getElementById(swfId);
            var timerId = 0;
            fallback.play = function() {
              if (timerId === 0) {
                var sys = this.sys;
                var msec = (sys.strmLength / sys.sampleRate) * 1000;
                var written = 0;
                var start = Date.now();
                var out   = new Array(sys.strmLength * sys.channels);
                var len   = out.length;

                var onaudioprocess = function() {
                  if (written > Date.now() - start) {
                    return;
                  }
                  sys.process();
                  var _in = sys.strm;
                  for (var i = 0; i < len; ++i) {
                    out[i] = String.fromCharCode( ((_in[i] + 32768)>>1) + 16384 );
                  }
                  swf.writeAudio(out.join(""));
                  written += msec;
                };

                timerId = setInterval(onaudioprocess, msec * 0.8);
                swf.play();
              }
            };
            fallback.pause = function() {
              if (timerId !== 0) {
                swf.pause();
                clearInterval(timerId);
                timerId = 0;
              }
            };
          };
        });
        return FallbackAudioAPI;
      })();
    }
  } else if (typeof global.GLOBAL !== "undefined") {
    AudioAPI = (function() {
      var Readable = global.require("stream").Readable;
      var Speaker  = global.require("speaker");
      if (!Readable) {
        Readable = global.require("readable-stream/readable");
      }
      function NodeAudioAPI(sys) {
        this.sys = sys;
        this.sampleRate = C.SOCKET_SAMPLERATE;
        this.channels   = C.SOCKET_CHANNELS;
        this.node = null;
        this.isPlaying = false;
      }
      NodeAudioAPI.prototype.init = function() {
      };
      NodeAudioAPI.prototype.play = function() {
        var sys = this.sys;
        this.isPlaying = true;
        this.node = new Readable();
        this.node._read = function(n) {
          var strm = sys._strm;
          var strmLength = sys.strmLength;
          var buf  = new Buffer(n);
          var x, i, j, k = 0;
          n = (n >> 2) / sys.strmLength;
          x = strm;
          while (n--) {
            sys._process();
            for (i = 0, j = strmLength; i < strmLength; ++i, ++j) {
              buf.writeInt16LE(strm[i], k);
              k += 2;
              buf.writeInt16LE(strm[j], k);
              k += 2;
            }
          }
          this.push(buf);
        };
        this.node.pipe(new Speaker({sampleRate:this.sampleRate}));
      };
      NodeAudioAPI.prototype.pause = function() {
        if (this.node) {
          process.nextTick(this.node.emit.bind(this.node, "end"));
        }
        this.node = null;
        this.isPlaying = false;
      };
      return NodeAudioAPI;
    })();
  }

  module.exports = {
    AudioAPI: AudioAPI
  };

});
<|endoftext|>


<commit_before>EventEngine = Class.create({

  initialize: function() {

    // startDrag, stopDrag, click, mouseDown, mouseUp, mouseMove

    this.listeners = [];
    this.state = {type: "unknown"};
    this.latestEvent = null;
    this.clickTimeout = null;

    this.clickTime = 250; // in milliseconds;

    var that = this;

    document.onmousedown = function(event) {that.onMouseDown.call(that, event);};
    document.onmouseup = function(event) {that.onMouseUp.call(that, event);};
    document.onmousemove = function(event) {that.onMouseMove.call(that, event);};

  },

  addListener: function(type, closure, thisArgument) {

    this.listeners.push({type: type, closure: closure, thisArgument: thisArgument});

  },

  removeListener: function(type, closure) {
    var i;

    for (i = 0; i < this.listeners.length; i++) {
      if (this.listeners[i].type === type && this.listeners[i].closure === closure) {
        this.listeners.splice(i, 1);
      }
    }
  },

  dispatchEvent: function(event) {
    var i;

    this.latestEvent = event;

    for (i = 0; i < this.listeners.length; i++) {
      if (this.listeners[i].type === event.type) {
        this.listeners[i].closure.call(this.listeners[i].thisArgument, event);
      }
    }
  },

  onMouseDown: function(event) {
    var coordinates = getRelativeCoordinates(event, $("editor"));

    var myEvent = new Event("mouseDown");
        myEvent.parameter = event;
        myEvent.mouseX = coordinates.x;
        myEvent.mouseY = coordinates.y;

    this.dispatchEvent(myEvent);

    this.state = {type: "down", x: coordinates.x, y: coordinates.y};

    var myScope = this;

    this.clickTimeoutID = setTimeout(

      function(coordinates, event) {
        myScope.onClickTimeout(coordinates, event);
      },

      this.clickTime, coordinates, event
    );
  },

  onMouseUp: function(event) {

    if (this.clickTimeoutID) {
      clearTimeout(this.clickTimeoutID);
      this.clickTimeoutID = null;
    }

    var type;

    if (this.state.type === "drag") {

      type = "stopDrag";

    } else if (this.state.type === "down") {

      type = "click";

    }

    var coordinates = getRelativeCoordinates(event, $("editor"));

    var myEvent = new Event(type);
        myEvent.parameter = event;
        myEvent.mouseX = coordinates.x;
        myEvent.mouseY = coordinates.y;

    this.state.type = "up";

    this.dispatchEvent(myEvent);
  },

  onMouseMove: function(event) {

    var coordinates = getRelativeCoordinates(event, $("editor"));

    var myEvent = new Event("mouseMove");
        myEvent.parameter = event;
        myEvent.mouseX = coordinates.x;
        myEvent.mouseY = coordinates.y;

    this.dispatchEvent(myEvent);

    if (this.state.type !== "up") {

      myEvent.type = "drag";
      this.dispatchEvent(myEvent);

    }

    if (this.state.type === "down") {
      var distance = (function(oldX, oldY, newX, newY) {

        var x = newX - oldX;
        var y = newY - oldY;

        return Math.sqrt(x * x + y * y);
      }(this.state.x, this.state.y, coordinates.x, coordinates.y));

      if (distance > 5) {

        this.onClickTimeout({x: this.state.x, y: this.state.y});

      }
    }
  },

  onClickTimeout: function(coordinates, event) {

    if (this.state.type !== "down") {
      return;
    }

    this.clickTimeoutID = null;

    this.state.type = "drag";

    var myEvent = new Event("startDrag");
        myEvent.parameter = event;
        myEvent.mouseX = coordinates.x;
        myEvent.mouseY = coordinates.y;

    this.dispatchEvent(myEvent);
  }

});<commit_msg>fixed scrollbar dragging, eventlistening on body<commit_after>EventEngine = Class.create({

  initialize: function() {

    // startDrag, stopDrag, click, mouseDown, mouseUp, mouseMove

    this.listeners = [];
    this.state = {type: "unknown"};
    this.latestEvent = null;
    this.clickTimeout = null;

    this.clickTime = 250; // in milliseconds;

    var that = this;

    document.body.onmousedown = function(event) {that.onMouseDown.call(that, event);};
    document.body.onmouseup = function(event) {that.onMouseUp.call(that, event);};
    document.body.onmousemove = function(event) {that.onMouseMove.call(that, event);};

  },

  addListener: function(type, closure, thisArgument) {

    this.listeners.push({type: type, closure: closure, thisArgument: thisArgument});

  },

  removeListener: function(type, closure) {
    var i;

    for (i = 0; i < this.listeners.length; i++) {
      if (this.listeners[i].type === type && this.listeners[i].closure === closure) {
        this.listeners.splice(i, 1);
      }
    }
  },

  dispatchEvent: function(event) {
    var i;

    this.latestEvent = event;

    for (i = 0; i < this.listeners.length; i++) {
      if (this.listeners[i].type === event.type) {
        this.listeners[i].closure.call(this.listeners[i].thisArgument, event);
      }
    }
  },

  onMouseDown: function(event) {
    var coordinates = getRelativeCoordinates(event, $("editor"));

    var myEvent = new Event("mouseDown");
        myEvent.parameter = event;
        myEvent.mouseX = coordinates.x;
        myEvent.mouseY = coordinates.y;

    this.dispatchEvent(myEvent);

    this.state = {type: "down", x: coordinates.x, y: coordinates.y};

    var myScope = this;

    this.clickTimeoutID = setTimeout(

      function(coordinates, event) {
        myScope.onClickTimeout(coordinates, event);
      },

      this.clickTime, coordinates, event
    );
  },

  onMouseUp: function(event) {

    if (this.clickTimeoutID) {
      clearTimeout(this.clickTimeoutID);
      this.clickTimeoutID = null;
    }

    var type;

    if (this.state.type === "drag") {

      type = "stopDrag";

    } else if (this.state.type === "down") {

      type = "click";

    }

    var coordinates = getRelativeCoordinates(event, $("editor"));

    var myEvent = new Event(type);
        myEvent.parameter = event;
        myEvent.mouseX = coordinates.x;
        myEvent.mouseY = coordinates.y;

    this.state.type = "up";

    this.dispatchEvent(myEvent);
  },

  onMouseMove: function(event) {

    var coordinates = getRelativeCoordinates(event, $("editor"));

    var myEvent = new Event("mouseMove");
        myEvent.parameter = event;
        myEvent.mouseX = coordinates.x;
        myEvent.mouseY = coordinates.y;

    this.dispatchEvent(myEvent);

    if (this.state.type !== "up") {

      myEvent.type = "drag";
      this.dispatchEvent(myEvent);

    }

    if (this.state.type === "down") {
      var distance = (function(oldX, oldY, newX, newY) {

        var x = newX - oldX;
        var y = newY - oldY;

        return Math.sqrt(x * x + y * y);
      }(this.state.x, this.state.y, coordinates.x, coordinates.y));

      if (distance > 5) {

        this.onClickTimeout({x: this.state.x, y: this.state.y});

      }
    }
  },

  onClickTimeout: function(coordinates, event) {

    if (this.state.type !== "down") {
      return;
    }

    this.clickTimeoutID = null;

    this.state.type = "drag";

    var myEvent = new Event("startDrag");
        myEvent.parameter = event;
        myEvent.mouseX = coordinates.x;
        myEvent.mouseY = coordinates.y;

    this.dispatchEvent(myEvent);
  }

});<|endoftext|>


<commit_before><commit_msg>rocking out while I'm coding it up. creating the message controller<commit_after>app.controller("MessageController", ["$routeParams", "$scope", "MessageService", function($routeParams, $scope, MessageService) {

}])<|endoftext|>


<commit_before>
"use strict";

import {Model} from './Model';

/**
 * Private method to do a simple check on the nature of an object.
 */
function isModel(obj) {
    return '$data' in obj && '$fields' in obj && '$deleted' in obj && '$new' in obj;
};

class Collection {

    constructor() {
        this.model = Model;
        this.storage = [];
    }

    /**
     * Overridable helper setting defaults for items in this collection.
     */
    defaults(obj) {
        return obj;
    }

    push(...args) {
        let idx = this.storage.length;
        args = args.map(arg => this.defaults(arg));
        args = args.map(arg => isModel(arg) ? arg : (new this.model()).$create(arg));
        this.storage.push(...args);
        for (let i = idx; i < this.storage.length; i++) {
            Object.defineProperty(this, i, {get: () => this.storage[i] || undefined, configurable: true});
        }
        return this.length;
    }

    shift() {
        let shifted = this.storage(shift);
        if (shifted !== undefined) {
            delete this[this.storage.length];
        }
        return shifted;
    }

    unshift(...args) {
        args = args.map(arg => this.defaults(arg));
        args = args.map(arg => isModel(arg) ? arg : (new this.model()).$create(args));
        let work = new Array(this.storage);
        work.unshift(...args);
        this.storage = [];
        work.map(item => this.push(item));
        return this.length;
    }

    pop() {
        let popped = this.storage.pop();
        if (popped !== undefined) {
            delete this[this.storage.length];
        }
        return popped;
    }

    get length() {
        return this.storage.length;
    }

    reverse() {
        this.storage.reverse();
    }

    sort(...args) {
        this.storage.sort(...args);
        return this;
    }

    splice(start, deleteCount, ...args) {
        args = args.map(arg => this.defaults(arg));
        args = args.map(arg => isModel(arg) ? arg : (new this.model()).$create(args));
        let work = new Array(this.storage);
        let retval = work.splice(start, deleteCount, ...args);
        this.storage = [];
        work.map(item => this.push(item));
        return retval;
    }

    indexOf(item) {
        return this.storage.indexOf(item);
    }

    get $dirty() {
        for (let i = 0; i < this.storage.length; i++) {
            if (this.storage[i].$new || this.storage[i].$dirty) {
                return true;
            }
        }
        return false;
    }

};

export {Collection};

<commit_msg>better isModel check, and call $create statically<commit_after>
"use strict";

import {Model} from './Model';

/**
 * Private method to do a simple check on the nature of an object.
 */
function isModel(obj) {
    return typeof obj == 'object' && obj instanceof Model;
};

class Collection {

    constructor() {
        this.model = Model;
        this.storage = [];
    }

    /**
     * Overridable helper setting defaults for items in this collection.
     */
    defaults(obj) {
        return obj;
    }

    push(...args) {
        let idx = this.storage.length;
        args = args.map(arg => this.defaults(arg));
        args = args.map(arg => isModel(arg) ? arg : Model.$create(arg, this.model));
        this.storage.push(...args);
        for (let i = idx; i < this.storage.length; i++) {
            Object.defineProperty(this, i, {get: () => this.storage[i] || undefined, configurable: true});
        }
        return this.length;
    }

    shift() {
        let shifted = this.storage(shift);
        if (shifted !== undefined) {
            delete this[this.storage.length];
        }
        return shifted;
    }

    unshift(...args) {
        args = args.map(arg => this.defaults(arg));
        args = args.map(arg => isModel(arg) ? arg : (new this.model()).$create(args));
        let work = new Array(this.storage);
        work.unshift(...args);
        this.storage = [];
        work.map(item => this.push(item));
        return this.length;
    }

    pop() {
        let popped = this.storage.pop();
        if (popped !== undefined) {
            delete this[this.storage.length];
        }
        return popped;
    }

    get length() {
        return this.storage.length;
    }

    reverse() {
        this.storage.reverse();
    }

    sort(...args) {
        this.storage.sort(...args);
        return this;
    }

    splice(start, deleteCount, ...args) {
        args = args.map(arg => this.defaults(arg));
        args = args.map(arg => isModel(arg) ? arg : (new this.model()).$create(args));
        let work = new Array(this.storage);
        let retval = work.splice(start, deleteCount, ...args);
        this.storage = [];
        work.map(item => this.push(item));
        return retval;
    }

    indexOf(item) {
        return this.storage.indexOf(item);
    }

    get $dirty() {
        for (let i = 0; i < this.storage.length; i++) {
            if (this.storage[i].$new || this.storage[i].$dirty) {
                return true;
            }
        }
        return false;
    }

};

export {Collection};

<|endoftext|>