<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>adams.co.tt blog - tagged with javascript</title>
  <id>http://adams.co.tt/</id>
  <updated>2012-05-30</updated>
  <author>
    <name></name>
  </author>
  <entry>
    <title>Namespacing in JavaScript</title>
    <link rel="alternate" href="http://adams.co.tt/blog/2012/05/30/namespacing-in-javascript/"/>
    <id>http://adams.co.tt/blog/2012/05/30/namespacing-in-javascript/</id>
    <published>2012-05-30</published>
    <updated>2012-05-30</updated>
    <author>
      <name></name>
    </author>
    <content type="html">&lt;p&gt;&lt;a href="http://yuiblog.com/blog/2006/06/01/global-domination/"&gt;JavaScript&amp;rsquo;s global variables are evil&lt;/a&gt;, and namespacing is a &lt;em&gt;good thing&lt;/em&gt;. However, as I regularly move from project to project, I find myself rewriting the code to help manage namespaces again and again. Every time I search for something reusable, I find conventions that require unpleasant boilerplate.&lt;/p&gt;

&lt;p&gt;I started a little personal project, and ended up writing &lt;a href="https://github.com/adscott/n-js"&gt;this&lt;/a&gt;. Hopefully somebody might find it useful.&lt;/p&gt;

&lt;p&gt;Grab the source &lt;a href="https://raw.github.com/adscott/n-js/master/n.js"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Include it in your document like so:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;script src="/path/to/n.js" type="text/javascript"&amp;gt;&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Register objects and classes like so:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;n('foo.bar.baz', function(s) {
  s.Person = function () {
    this.greet = function () {
      alert('hello');
    };
  };
});
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Reference registered objects and classes like so:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;var myPerson = new foo.bar.baz.Person();
myPerson.greet();
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That&amp;rsquo;s all there is to it!&lt;/p&gt;

&lt;p&gt;UPDATE: A minified version can now be found &lt;a href="https://raw.github.com/adscott/n-js/master/n.min.js"&gt;here&lt;/a&gt;. Thanks &lt;a href="https://github.com/ScottHamper"&gt;Scott Hamper&lt;/a&gt;!&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Updated jasmine-underscore</title>
    <link rel="alternate" href="http://adams.co.tt/blog/2012/03/14/updated-jasmine-underscore/"/>
    <id>http://adams.co.tt/blog/2012/03/14/updated-jasmine-underscore/</id>
    <published>2012-03-14</published>
    <updated>2012-03-14</updated>
    <author>
      <name></name>
    </author>
    <content type="html">&lt;p&gt;Last year &lt;a href="https://github.com/adscott/jasmine-underscore"&gt;jasmine-underscore&lt;/a&gt; was &lt;a href="http://adams.co.tt/blog/2011/06/19/jasmine-underscore/"&gt;released&lt;/a&gt;. Since then, some issues have been fixed, and two new matchers have also been included:&lt;/p&gt;

&lt;h5&gt;allToSatisfy&lt;/h5&gt;

&lt;pre&gt;&lt;code&gt;expect([2, 4, 6]).allToSatisfy(function (val) { return val%2 == 0; });
expect([1, 4, 6]).not.allToSatisfy(function (val) { return val%2 == 0; });
&lt;/code&gt;&lt;/pre&gt;

&lt;h5&gt;anyToSatisfy&lt;/h5&gt;

&lt;pre&gt;&lt;code&gt;expect([2, 3, 5]).anyToSatisfy(function (val) { return val%2 == 0; });
expect([1, 3, 5]).not.anyToSatisfy(function (val) { return val%2 == 0; });
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;These matchers allow any predicate to be applied to element of a collection, with the test only passing if all/any of the elements in collection satisfy the predicate.&lt;/p&gt;

&lt;p&gt;Get version 1.1 &lt;a href="https://github.com/downloads/adscott/jasmine-underscore/jasmine-underscore-v1.1.zip"&gt;here&lt;/a&gt;. Enjoy!&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>jasmine-underscore</title>
    <link rel="alternate" href="http://adams.co.tt/blog/2011/06/19/jasmine-underscore/"/>
    <id>http://adams.co.tt/blog/2011/06/19/jasmine-underscore/</id>
    <published>2011-06-19</published>
    <updated>2011-06-19</updated>
    <author>
      <name></name>
    </author>
    <content type="html">&lt;p&gt;I love &lt;a href="http://pivotal.github.com/jasmine/"&gt;Jasmine&lt;/a&gt;. It&amp;rsquo;s a fantastic testing framework with a good set of extensions (e.g. &lt;a href="https://github.com/velesin/jasmine-jquery/"&gt;jasmine-jquery&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;I also love &lt;a href="http://documentcloud.github.com/underscore/"&gt;Underscore&lt;/a&gt;. It has a number of utility functions that help improve the readability of my code and dramatically reduces the code duplication associated with managing collections in JavaScript.&lt;/p&gt;

&lt;p&gt;Recently I&amp;rsquo;ve been using Jasmine and Underscore together in tests. Underscore provides a number of functions to interrogate the state of an object, and I find I often use these in my Jasmine specs:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;it('should return today as a date', function () {
  var cal = new AwesomeCalendar();
  expect(_(cal.today()).isDate()).toBeTruthy();
});
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is a useful test, however it doesn&amp;rsquo;t read quite as nicely as it could. There is a lot of noise, and the failure reporting won&amp;rsquo;t be particularly informative. With that in mind I created &lt;a href="https://github.com/adscott/jasmine-underscore"&gt;jasmine-underscore&lt;/a&gt;. This extension creates matchers for Jasmine based on the Underscore&amp;rsquo;s object functions. Any function that Underscore provides that has the &amp;lsquo;is&amp;rsquo; prefix can be used as a matcher. For example, the test above becomes:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;it('should return today as a date', function () {
  var cal = new AwesomeCalendar();
  expect(cal.today()).toBeDate();
});
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is not only more readable, it also produces better failure messages. The first spec&amp;rsquo;s error message would be &lt;code&gt;Expected false to be truthy&lt;/code&gt;. Now the failure will read &lt;code&gt;Expected null to be date&lt;/code&gt; if today unexpectedly returns null.&lt;/p&gt;

&lt;h2&gt;using&lt;/h2&gt;

&lt;p&gt;Another situation I found myself using Underscore with Jasmine a great deal is the generation of examples for specs:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;_([
    [1, 2, 3], 
    [2, 3, 5]
  ]).each(function (vals) {

  var first = vals[0];
  var second = vals[1];
  var total = vals[2];

  it('should sum ' + first + ' and ' + second, function () {
      expect(sum(first, second)).toEqual(total);
  });
});
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Again, this somewhat noisy, and could read somewhat better. The jasmine-underscore extension provides the &lt;code&gt;using&lt;/code&gt; function. It is backed by Underscore and helps generate test examples in a meaningful way:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;using([1, 2, 3], [2, 3, 5], function (first, second, total) {
  it('should sum ' + first + ' and ' + second, function () {
      expect(sum(first, second)).toEqual(total);
  });
});
&lt;/code&gt;&lt;/pre&gt;
</content>
  </entry>
  <entry>
    <title>Backbone.js - Events and Controllers</title>
    <link rel="alternate" href="http://adams.co.tt/blog/2011/05/09/backbonejs---events-and-controllers/"/>
    <id>http://adams.co.tt/blog/2011/05/09/backbonejs---events-and-controllers/</id>
    <published>2011-05-09</published>
    <updated>2011-05-09</updated>
    <author>
      <name></name>
    </author>
    <content type="html">&lt;p&gt;In my &lt;a href="/blog/2011/05/08/backbonejs---models-and-views/"&gt;last post&lt;/a&gt;, we discussed Backbone models and views, and how they can form a basic application. Now we&amp;rsquo;ll discuss how we can leverage Backbone events to allow rich client interaction, and how controllers can be used to create multiple pages within your application.&lt;/p&gt;

&lt;h2&gt;View events&lt;/h2&gt;

&lt;p&gt;Let us take the ArticleView from the previous post&amp;rsquo;s examples:&lt;/p&gt;

&lt;pre&gt;&lt;code class="javascript"&gt;app.views.ArticleView = Backbone.View.extend({
  events : {
    'click span.remove' : 'remove'
  },

  remove : function () {
    var self = this;
    this.model.destroy({
      success : function () {
        $(self.el).remove();
      },
      error : function () {
        throw self.model.id + ' could not be removed';
      }
    });
  },

  render : function () {
    var out = '&amp;lt;h1&amp;gt;' + this.model.get('title') + '&amp;lt;/h1&amp;gt;';
    out += '&amp;lt;p&amp;gt;' + this.model.publishDate() + '&amp;lt;/p&amp;gt;';
    out += '&amp;lt;p&amp;gt;' + this.model.get('body') + '&amp;lt;/p&amp;gt;';
    out += '&amp;lt;span class="remove"&amp;gt;REMOVE&amp;lt;/span&amp;gt;' 
    $(this.el).html(out);
    return this;
  }
});&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;There has been some behaviour added to the ArticleView. A span has been added to which we have registered a click event. Clicking on the text &amp;ldquo;REMOVE&amp;rdquo; will result in the model it represents being destroyed on the server. This is performed by Backbone.js sending an HTTP &lt;code&gt;DELETE&lt;/code&gt; request to the server. Upon success of this operation, the element in the DOM which represents this model will be removed.&lt;/p&gt;

&lt;p&gt;As we can see the events hash can be used to great effect in declaring any behaviour that you wish be be a product of direct user interaction. Events are written in the format &lt;code&gt;{&amp;ldquo;event&amp;nbsp;selector&amp;rdquo;&amp;nbsp;:&amp;nbsp;&amp;ldquo;callback&amp;rdquo;}&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;Model events&lt;/h2&gt;

&lt;p&gt;Let us refer back to the code that we used to initialise the application in the previous post:&lt;/p&gt;

&lt;pre&gt;&lt;code class='javascript'&gt;var app = {
  models : {},
  views : {},
  init : function () {
    var articleList = new app.models.ArticleList();
    articleList.fetch({success : function () {
      var view = new app.views.ArticleListView({
        collection : articleList
      });
      view.render();
    });
  }
};

$(document).ready(app.init);&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;As you can see, we load the article list once on page load, and then never again. However, suppose an editor modifies, adds or removes an existing article, and we wish to update the list in the browser to reflect that new state.&lt;/p&gt;

&lt;p&gt;By altering the ArticleListView, we can leverage registration to model events:&lt;/p&gt;

&lt;pre&gt;&lt;code class="javascript"&gt;app.views.ArticleListView = Backbone.View.extend({
  initialize : function () {
    _.bindAll(this, 'render');
    this.collection.bind('refresh', this.render);
  },    

  render : function () {
    var renderedArticles = _.map(this.collection.models, function (article) {
      return new app.views.ArticleView({model : article}).render().el;
    })
    $(this.el).html(renderedArticles);
    $('#container').html(this.el);
    return this;
  }
});&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Now we can change the application initialisation:&lt;/p&gt;

&lt;pre&gt;&lt;code class='javascript'&gt;var app = {
  models : {},
  views : {},
  init : function () {
    var articleList = new app.models.ArticleList();
    new app.views.ArticleListView({collection : articleList});
    setInterval(articleList.fetch, 10000);
  }
};

$(document).ready(app.init);&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;As a result, any changes to the article list on the server will be displayed shortly thereafter on the browser. Backbone.js models and collections generate a number of events:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&amp;ldquo;add&amp;rdquo; (model, collection) — when a model is added to a collection.&lt;/li&gt;
&lt;li&gt;&amp;ldquo;remove&amp;rdquo; (model, collection) — when a model is removed from a collection.&lt;/li&gt;
&lt;li&gt;&amp;ldquo;refresh&amp;rdquo; (collection) — when the collection&amp;rsquo;s entire contents have been replaced.&lt;/li&gt;
&lt;li&gt;&amp;ldquo;change&amp;rdquo; (model, collection) — when a model&amp;rsquo;s attributes have changed.&lt;/li&gt;
&lt;li&gt;&amp;ldquo;change:[attribute]&amp;rdquo; (model, collection) — when a specific attribute has been updated.&lt;/li&gt;
&lt;li&gt;&amp;ldquo;error&amp;rdquo; (model, collection) — when a model&amp;rsquo;s validation fails, or a save call fails on the server.&lt;/li&gt;
&lt;li&gt;&amp;ldquo;route:[name]&amp;rdquo; (controller) — when one of a controller&amp;rsquo;s routes has matched.&lt;/li&gt;
&lt;li&gt;&amp;ldquo;all&amp;rdquo; — this special event fires for any triggered event, passing the event name as the first argument.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;Controllers&lt;/h2&gt;

&lt;p&gt;It is debatable as to whether Backbone.js controllers can be considered controllers in the context of the common understanding of MVC. They, in fact, bear closer semblance to the rails routes.rb, declaring handlers for URLs. Consider the following example:&lt;/p&gt;

&lt;pre&gt;&lt;code class='javascript'&gt;app.controllers.AppController = Backbone.Controller.extend({

  routes : function () {
    'articles' : 'index',
    'articles/:id/edit' : 'editArticle',
    'articles/new' : 'newArticle'
  }

  defaultView : function () {
    window.location.hash = 'articles';
  },

  index : function () {
    var articleList = new app.models.ArticleList();
    new app.views.ArticleListView({collection : articleList});
    articleList.fetch();
  },

  editArticle : function (articleId) {
    var article = new app.models.Article({id : articleId});
    new app.views.ArticleEditView({model : article});
    article.fetch();
  },

  newArticle : function () {
    new app.views.ArticleNewView({
     model : new app.models.Article();
    });
  }
});&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Here we have an application that not only renders an article list, but also allows the user to create new articles and edit existing ones. Each function on the controller is invoked when the hash fragment of the url matches the url pattern described in the routes hash. When the user has completed an action on any given page, all the view need do is change the url hash to correspond with whatever the user wants or should do next.&lt;/p&gt;

&lt;p&gt;Using events and controllers it is possible to provide a user experience which is rich in behaviour and interaction.&lt;/p&gt;

&lt;pre&gt;&lt;code class='javascript'&gt;var app = {
  models : {},
  views : {},
  controllers : {},
  init : function () {
    new app.controllers.AppController();
    Backbone.history.start();
  }
};

$(document).ready(app.init);&lt;/code&gt;&lt;/pre&gt;

</content>
  </entry>
  <entry>
    <title>Backbone.js - Models and Views</title>
    <link rel="alternate" href="http://adams.co.tt/blog/2011/05/08/backbonejs---models-and-views/"/>
    <id>http://adams.co.tt/blog/2011/05/08/backbonejs---models-and-views/</id>
    <published>2011-05-08</published>
    <updated>2011-05-08</updated>
    <author>
      <name></name>
    </author>
    <content type="html">&lt;h2&gt;What is backbone?&lt;/h2&gt;

&lt;p&gt;Backbone.js is a JavaScript framework which brings Model View Controller semantics to your JavaScript application. These semantics allow a  rich JavaScript client application to be broken up in meaningful ways. DOM manipulation is separated from business logic by the views and models respectively. Controllers can be used to switch between &amp;lsquo;pages&amp;rsquo; within your application.&lt;/p&gt;

&lt;h2&gt;Models and collections&lt;/h2&gt;

&lt;p&gt;Backbone provides model and collection classes. For example consider the following:&lt;/p&gt;

&lt;pre&gt;&lt;code class="javascript"&gt;app.models.Article = Backbone.Model.extend({
  publishedTime : function () {
    return new Date(this.get('publishedDate')).toLocaleTimeString();
  }
});&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Here we have a very simple Article class. You&amp;rsquo;ll notice we have not declared any attributes on this class. This is because backbone models gain their attribute structure from the data used to hydrate them.&lt;/p&gt;

&lt;p&gt;Here we have a collection class:&lt;/p&gt;

&lt;pre&gt;&lt;code class="javascript"&gt;app.models.ArticleList = Backbone.Collection.extend({
  url : '/articles',
  model : app.models.Article
});&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;As you can see, again the collection class is very anaemic. Both models and collections can be passed to views for rendering, and generate events. In this example the Article list maps to a url which returns JSON in the form:&lt;/p&gt;

&lt;pre&gt;&lt;code class="javascript"&gt;[ 
  { 
    "id" : 1000,
    "body" : "Bar",
    "publishedDate" : "Mon May 02 2011 16:00:00 GMT+1000 (EST)",
    "title" : "Foo"
  },
  { 
    "id" : 2000,
    "body" : "Bam",
    "publishedDate" : "Fri May 06 2011 15:30:00 GMT+1000 (EST)",
    "title" : "Baz"
  }
]&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;The object list described here is what provides the models with their structure.&lt;/p&gt;

&lt;h2&gt;Views&lt;/h2&gt;

&lt;p&gt;Backbone provides a single view class from which we can extend:&lt;/p&gt;

&lt;pre&gt;&lt;code class="javascript"&gt;app.views.ArticleListView = Backbone.View.extend({
  render : function () {
    var renderedArticles = _.map(this.collection.models, function (article) {
      return new app.views.ArticleView({model : article}).render().el;
    })
    $(this.el).html(renderedArticles);
    $('#container').html(this.el);
    return this;
  }
});

app.views.ArticleView = Backbone.View.extend({
  render : function () {
    var out = '&amp;lt;h1&amp;gt;' + this.model.get('title') + '&amp;lt;/h1&amp;gt;';
    out += '&amp;lt;p&amp;gt;' + this.model.publishedTime() + '&amp;lt;/p&amp;gt;';
    out += '&amp;lt;p&amp;gt;' + this.model.get('body') + '&amp;lt;/p&amp;gt;';
    $(this.el).html(out);
    return this;
  }
});&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Here we see views which can display the article list. The ArticleListView delegates to the ArticleView for rendering of individual elements of the collection. In this example we&amp;rsquo;re generating the HTML inline, however as your application grows, it&amp;rsquo;s most likely that you&amp;rsquo;ll want to extract this to some form of templating system.&lt;/p&gt;

&lt;h2&gt;The Application&lt;/h2&gt;

&lt;p&gt;Up until now we&amp;rsquo;ve only seen models, collections and views on their own. Now we can see how a very basic Backbone.js application hangs together. Here we declare the namespaces, the init function and register it to run on document ready.&lt;/p&gt;

&lt;pre&gt;&lt;code class='javascript'&gt;var app = {
  models : {},
  views : {},
  init : function () {
    var articleList = new app.models.ArticleList();
    articleList.fetch({success : function () {
      var view = new app.views.ArticleListView({
        collection : articleList
      });
      view.render();
    }});
  }
};

$(document).ready(app.init);&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;And here we have an extremely basic Backbone.js application. You&amp;rsquo;ll notice that we have not yet leveraged any events or controllers. In my next post we&amp;rsquo;ll go over how to use these features to create an application to allow rich user interaction.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>RhinoUnit with env.js</title>
    <link rel="alternate" href="http://adams.co.tt/blog/2009/05/20/rhinounit-with-envjs/"/>
    <id>http://adams.co.tt/blog/2009/05/20/rhinounit-with-envjs/</id>
    <published>2009-05-20</published>
    <updated>2009-05-20</updated>
    <author>
      <name></name>
    </author>
    <content type="html">&lt;p&gt;In my previous post, I mentioned the possibility of using John Resig&amp;rsquo;s &lt;a href="http://ejohn.org/blog/bringing-the-browser-to-the-server"&gt;env.js&lt;/a&gt; as a means to provide a DOM to &lt;a href="http://code.google.com/p/rhinounit/"&gt;RhinoUnit&lt;/a&gt;. Since then I&amp;rsquo;ve been playing around with it to some success.&lt;br /&gt;&lt;br /&gt;As I described before having a DOM available to RhinoUnit would carry a number of advantages. One of the great things about RhinoUnit is that it runs headless, and thanks to the speed of &lt;a href="http://www.mozilla.org/rhino/"&gt;Rhino&lt;/a&gt;, tests can run very quickly. It&amp;rsquo;s problem is that it doesn&amp;rsquo;t have a DOM available to it, and so it means that testing view logic is very difficult.&lt;br /&gt;&lt;br /&gt;This does have a big advantage that it encourages developers to separate their business logic and view logic, and to have good, loosely coupled testing around their business logic. However it does also mean that the view logic goes basically untested at the unit level. This is less than ideal. It also means that any interactions with frameworks like &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt; and their plugins also cannot be tested by RhinoUnit.&lt;br /&gt;&lt;br /&gt;This is where env.js comes in. Env.js is a javascript implementation of the browser, which would allow RhinoUnit to interact with DOM provided they can be made to play nice together. As it turns out, both needed some minor tweaking in order to work with each other.&lt;br /&gt;&lt;br /&gt;RhinoUnit uses javascript object &lt;code&gt;self&lt;/code&gt; for logging, however env.js overrides this and therefore breaks RhinoUnit&amp;rsquo;s logging. To fix RhinoUnit, &lt;code&gt;self&lt;/code&gt; needs to be assigned to a variable and all references to &lt;code&gt;self&lt;/code&gt; need to be updated.&lt;br /&gt;&lt;br /&gt;Env.js also needs some minor changes. In order to run RhinoUnit in this example, Rhino is hooked into the Bean Scripting Framework for java. This does not provide all the rhino shell commands that env.js expects, specifically the &lt;code&gt;print&lt;/code&gt; function. By simply replacing all calls to &lt;code&gt;print&lt;/code&gt; with the &lt;code&gt;self&lt;/code&gt; instance variable&amp;rsquo;s log function, env.js can be made to work.&lt;br /&gt;&lt;br /&gt;Finally, RhinoUnit will fail if it thinks you&amp;rsquo;ve polluted the global namespace. This an extremely useful rule, however env.js does rather break that, with the dozens of ways javascript can interact with a browser. As a result RhinoUnit needs to be configured to ignore a rather long list of global variables, including but not limited to:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;rhinounit window closed defaultStatus event frames innerHeight innerWidth clientHeight clientWidth name opener outerHeight outerWidth pageXOffest pageYOffset parent screenLeft screenTop screenX screenY status top open close NodeList Node CharacterData Text DOMText CDATASection Comment DocumentType Attr Element DocumentFragment ProcessingInstruction $domparser DOMParser DOMImplementation Document HTMLDocument HTMLElement HTMLCollection HTMLAnchorElement Anchor HTMLAreaElement HTMLBaseElement HTMLQuoteElement HTMLButtonElement HTMLTableColElement HTMLModElement HTMLFieldSetElement Form HTMLFormElement HTMLFrameElement HTMLFrameSetElement HTMLHeadElement HTMLIFrameElement HTMLImageElement HTMLInputElement HTMLLabelElement HTMLLegendElement Link HTMLLinkElement HTMLMapElement HTMLMetaElement HTMLObjectElement HTMLOptGroupElement HTMLOptionElement HTMLParamElement HTMLScriptElement HTMLSelectElement HTMLStyleElement HTMLTableElement HTMLTableCellElement HTMLTableRowElement Event CSS2Properties CSSRule CSSStyleSheet location $currentHistoryIndex $history history navigator setTimeout setInterval clearTimeout clearInterval addEventListener removeEventListener dispatchEvent onerror XMLHttpRequest getComputedStyle screen moveBy moveTo resizeBy resizeTo scroll scrollBy scrollTo alert confirm prompt $profiler $profile document node iRet nodeList&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Once you have RhinoUnit and env.js behaving, you can write tests as follows:&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;eval(loadFile(&amp;lsquo;env-js/dist/env.rhino.js&amp;rsquo;));&lt;br /&gt;eval(loadFile(&amp;lsquo;example/lib/adminUtils.js&amp;rsquo;));&lt;br /&gt;eval(loadFile(&amp;lsquo;example/src/TagPickerInputView.js&amp;rsquo;));&lt;br /&gt;&lt;br /&gt;var templateRenderer;&lt;br /&gt;var view;&lt;br /&gt;&lt;br /&gt;testCases(test,&lt;br /&gt;    function setUp() {&lt;br /&gt;        templateRenderer = {};&lt;br /&gt;        view = new rhinounit.example.tagpicker.TagPickerInputView(templateRenderer, &amp;lsquo;first-tag-picker&amp;rsquo;);&lt;br /&gt;    },&lt;br /&gt;&lt;br /&gt;    function shouldShowLoadMessage() {&lt;br /&gt;        document.loadXML(&amp;lsquo;&amp;lt;div id=&amp;quot;first-tag-picker&amp;quot;&amp;gt;&amp;rsquo; +&lt;br /&gt;                         &amp;lsquo;&amp;lt;form&amp;gt;&amp;rsquo; +&lt;br /&gt;                         &amp;lsquo;&amp;lt;label for=&amp;quot;tagPickerInput1&amp;quot;&amp;gt;Please select the first tag&amp;lt;/label&amp;gt;&amp;rsquo; +&lt;br /&gt;                         &amp;lsquo;&amp;lt;input id=&amp;quot;tagPickerInput1&amp;quot; type=&amp;quot;text&amp;quot; class=&amp;quot;tag-picker-input&amp;quot; name=&amp;quot;tagPickerInput&amp;quot; autocomplete=&amp;quot;off&amp;quot;/&amp;gt;&amp;rsquo; + &lt;br /&gt;                         &amp;lsquo;&amp;lt;div id=&amp;quot;loadMessage&amp;quot; class=&amp;quot;tag-picker-load-message hidden&amp;quot;&amp;gt;Loading&amp;hellip;&amp;lt;/div&amp;gt;&amp;rsquo; +&lt;br /&gt;                         &amp;lsquo;&amp;lt;div class=&amp;quot;tag-picker-matched-tags&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&amp;rsquo; +&lt;br /&gt;                         &amp;lsquo;&amp;lt;/form&amp;gt;&amp;rsquo; +&lt;br /&gt;                         &amp;lsquo;&amp;lt;/div&amp;gt;&amp;rsquo;);&lt;br /&gt;        document.getElementById(&amp;lsquo;loadMessage&amp;rsquo;).style.display = &amp;lsquo;none&amp;rsquo;;&lt;br /&gt;        &lt;br /&gt;        view.showLoadMessage();&lt;br /&gt;        assert.that(document.getElementById(&amp;lsquo;loadMessage&amp;rsquo;).style.display, eq(&amp;lsquo;block&amp;rsquo;));&lt;br /&gt;    });&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Although env.js also apparently supports jQuery, my attempts to integrate the two with RhinoUnit have so far been fruitless. This may be due to the fact that although env.js does offer a high proportion of the features available in your average browser, the holes in functionality are still too great at the time of writing to satisfy the recent versions of jQuery.&lt;br /&gt;&lt;br /&gt;Footnote: There are a couple of branches of env.js. This is the one that I used: &lt;a href="http://github.com/thatcher/env-js/tree/master"&gt;link&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Screw.Unit outside the browser</title>
    <link rel="alternate" href="http://adams.co.tt/blog/2009/05/08/screwunit-outside-the-browser/"/>
    <id>http://adams.co.tt/blog/2009/05/08/screwunit-outside-the-browser/</id>
    <published>2009-05-08</published>
    <updated>2009-05-08</updated>
    <author>
      <name></name>
    </author>
    <content type="html">&lt;p&gt;&lt;a href="http://github.com/nkallen/screw-unit/tree/master"&gt;Screw.Unit&lt;/a&gt; seems to be the current favourite means of testing JavaScript code. It has many advantages. It has nice BDD style syntax. It has a custom matchers. It&amp;rsquo;s easy to extend. It has many lovely things.&lt;br /&gt;&lt;br /&gt;It also runs inside the browser, which means it has access to the DOM. This lets you test against the DOM which is handy, but does result in the overhead of having to run a browser for your tests. JavaScript testing frameworks like &lt;a href="http://code.google.com/p/rhinounit/"&gt;RhinoUnit&lt;/a&gt; don&amp;rsquo;t run in the browser and as a result can run headless and can run a lot faster. The disadvantage is, of course, that these frameworks cannot test against the DOM.&lt;br /&gt;&lt;br /&gt;This isn&amp;rsquo;t an altogether bad thing. In order to test under RhinoUnit, one must separate view logic from business logic, forcing the developer to think about good encapsulation. It does however still leave you with the question of how to quickly test javascript against a DOM.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://ejohn.org/projects/bringing-the-browser-to-the-server/"&gt;John Resig&amp;rsquo;s Env.js&lt;/a&gt; provides one possible alternative. It looks like a solution that would integrate well with RhinoUnit. Another possible solution which I&amp;rsquo;ve chosen to explore was one which was originally discussed with Fabio Lessa, a colleague of mine, which is to run Screw.Unit tests from inside &lt;a href="http://htmlunit.sourceforge.net/"&gt;HtmlUnit&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The following mainfile combined with the subsequent buildr buildfile generates a jar that can be used to run Screw.Unit test suites. The onejar reference in the buildfile allows me to package all the dependency jars into a single jar with the mainfile. This saves me having to add all the dependency jars to the classpath. It isn&amp;rsquo;t strictly necessary here. (For more details on the subject, see &lt;a href="http://lizdouglass.wordpress.com/2008/10/28/a-jar-of-jars/"&gt;Liz Douglass' post&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;Mainfile:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;package net.randomfocus.screwunitrunner;&lt;br /&gt;&lt;br /&gt;import java.io.File;&lt;br /&gt;&lt;br /&gt;import be.roam.hue.doj.Doj;&lt;br /&gt;&lt;br /&gt;import com.gargoylesoftware.htmlunit.WebClient;&lt;br /&gt;import com.gargoylesoftware.htmlunit.html.HtmlPage;&lt;br /&gt;&lt;br /&gt;public class ScrewUnitRunner {&lt;br /&gt;&lt;br /&gt;   public static void main(String[] args) throws Exception {&lt;br /&gt;       for (String arg : args) {&lt;br /&gt;           runTestsForSuite(new File(arg).toURL().toString());&lt;br /&gt;       }&lt;br /&gt;       System.out.println(&amp;ldquo;Screw.Unit tests passed.&amp;rdquo;);&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   private static void runTestsForSuite(String suite) throws Exception {&lt;br /&gt;       WebClient client = new WebClient();&lt;br /&gt;       HtmlPage page;&lt;br /&gt;       page = (HtmlPage) client.getPage(suite);&lt;br /&gt;       Doj dom = Doj.on(page);&lt;br /&gt;&lt;br /&gt;       // Allow tests to run.&lt;br /&gt;       Integer timeout = 0;&lt;br /&gt;       while (&amp;ldquo;Running&amp;hellip;&amp;rdquo;.equals(dom.get(&amp;ldquo;.status&amp;rdquo;).text())) {&lt;br /&gt;           Thread.sleep(100);&lt;br /&gt;           timeout++;&lt;br /&gt;           if (timeout &amp;gt; 300) {&lt;br /&gt;               throw new RuntimeException(&amp;ldquo;Test in suite [&amp;rdquo; + suite&lt;br /&gt;                       + &amp;ldquo;] timed out.&amp;rdquo;);&lt;br /&gt;           }&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       // Check for failures&lt;br /&gt;       if (dom.get(&amp;ldquo;.error&amp;rdquo;).allElements().length &amp;gt; 0) {&lt;br /&gt;           throw new RuntimeException(&amp;ldquo;Test in suite [&amp;rdquo; + suite + &amp;ldquo;] failed.&amp;rdquo;);&lt;br /&gt;       }&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Buildfile:&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;require &amp;lsquo;buildr&amp;rsquo;&lt;br /&gt; &lt;br /&gt;VERSION_NUMBER = &amp;lsquo;1.0&amp;rsquo;&lt;br /&gt;&lt;br /&gt;HTMLUNIT_JARS = [&amp;lsquo;xalan:xalan:jar:2.7.1&amp;rsquo;,&lt;br /&gt;                 &amp;lsquo;net.sourceforge.htmlunit:htmlunit:jar:2.5&amp;rsquo;, &lt;br /&gt;                 &amp;lsquo;net.sourceforge.htmlunit:htmlunit-core-js:jar:2.5&amp;rsquo;, &lt;br /&gt;                 &amp;lsquo;net.sourceforge.cssparser:cssparser:jar:0.9.5&amp;rsquo;, &lt;br /&gt;                 &amp;lsquo;commons-httpclient:commons-httpclient:jar:3.1&amp;rsquo;, &lt;br /&gt;                 &amp;lsquo;commons-io:commons-io:jar:1.4&amp;rsquo;, &lt;br /&gt;                 &amp;lsquo;commons-logging:commons-logging:jar:1.1.1&amp;rsquo;, &lt;br /&gt;                 &amp;lsquo;commons-lang:commons-lang:jar:2.4&amp;rsquo;, &lt;br /&gt;                 &amp;lsquo;commons-codec:commons-codec:jar:1.3&amp;rsquo;,&lt;br /&gt;                 &amp;lsquo;xerces:xerces:jar:2.4.0&amp;rsquo;,&lt;br /&gt;                 &amp;lsquo;rhino:js:jar:1.7R1&amp;rsquo;,&lt;br /&gt;                 &amp;lsquo;net.sourceforge.nekohtml:nekohtml:jar:1.9.12&amp;rsquo;,&lt;br /&gt;                 &amp;lsquo;commons-collections:commons-collections:jar:3.2.1&amp;rsquo;,&lt;br /&gt;                 &amp;lsquo;be.roam.hue:hue:jar:1.1&amp;rsquo;,&lt;br /&gt;                 &amp;lsquo;org.w3c.css:sac:jar:1.3&amp;rsquo;]&lt;br /&gt;                 &lt;br /&gt;TEST_JARS = [&amp;lsquo;junit:junit:jar:4.5&amp;rsquo;, &amp;lsquo;org.hamcrest:hamcrest-all:jar:1.1&amp;rsquo;]&lt;br /&gt; &lt;br /&gt;repositories.local = &amp;lsquo;./repository&amp;rsquo;&lt;br /&gt;repositories.remote &amp;lt;&amp;lt; &amp;lsquo;http://www.ibiblio.org/maven2/&amp;rsquo;&lt;br /&gt;repositories.remote &amp;lt;&amp;lt; &amp;lsquo;http://hue.googlecode.com/svn/maven2/&amp;rsquo;&lt;br /&gt; &lt;br /&gt;desc &amp;lsquo;Browser Unit&amp;rsquo;&lt;br /&gt;define &amp;lsquo;browserunit&amp;rsquo; do&lt;br /&gt; &lt;br /&gt;  project.version = VERSION_NUMBER&lt;br /&gt;  project.group = &amp;lsquo;scott&amp;rsquo;&lt;br /&gt;&lt;br /&gt;  define &amp;lsquo;browser&amp;rsquo; do&lt;br /&gt;    compile.with HTMLUNIT_JARS&lt;br /&gt;    test.with TEST_JARS&lt;br /&gt;    package :jar&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  define &amp;lsquo;packaged&amp;rsquo; do&lt;br /&gt;    package(:jar).path(&amp;quot;lib&amp;quot;).tap do &amp;#124;p&amp;#124;&lt;br /&gt;      HTMLUNIT_JARS.each do &amp;#124;j&amp;#124;&lt;br /&gt;        p.include artifact(j).to_s&lt;br /&gt;      end&lt;br /&gt;    end&lt;br /&gt;    package(:jar).path(&amp;quot;main&amp;quot;).tap do &amp;#124;p&amp;#124;&lt;br /&gt;      p.include project(&amp;lsquo;browser&amp;rsquo;).package(:jar)&lt;br /&gt;    end&lt;br /&gt;    package(:jar).with :manifest=&amp;gt;manifest.merge(&lt;br /&gt;      &amp;lsquo;One-Jar-Main-Class&amp;rsquo;=&amp;gt;&amp;lsquo;net.randomfocus.screwunitrunner.ScrewUnitRunner&amp;rsquo;,&lt;br /&gt;      &amp;lsquo;Main-Class&amp;rsquo;=&amp;gt;&amp;lsquo;com.simontuffs.onejar.Boot&amp;rsquo;&lt;br /&gt;    )&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;end&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Running it:&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;buildr clean package&lt;br /&gt;java -jar packaged/target/browserunit-packaged-1.0.jar screwunit/screw-unit/example/spec/suite.html&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now if we were to try running those against real suites, we&amp;rsquo;d see that the error reporting is currently nonexistent. Those nice Screw.Unit test reports are lost. Finding a way to represent those accurately is the next big step for making this a viable solution for JavaScript testing outside of the browser.&lt;/p&gt;
</content>
  <