<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>todd anderson</title>
	<atom:link href="http://custardbelly.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://custardbelly.com/blog</link>
	<description>it&#039;s a long story</description>
	<lastBuildDate>Wed, 06 Mar 2013 11:21:28 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>The Making of a Test-Driven Grocery List Application in JS: Part X</title>
		<link>http://custardbelly.com/blog/2013/03/06/the-making-of-a-test-driven-grocery-list-application-in-js-part-x/</link>
		<comments>http://custardbelly.com/blog/2013/03/06/the-making-of-a-test-driven-grocery-list-application-in-js-part-x/#comments</comments>
		<pubDate>Wed, 06 Mar 2013 11:15:38 +0000</pubDate>
		<dc:creator>todd anderson</dc:creator>
				<category><![CDATA[AMD]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[RequireJS]]></category>
		<category><![CDATA[grocery-ls]]></category>
		<category><![CDATA[jasmine]]></category>

		<guid isPermaLink="false">http://custardbelly.com/blog/?p=823</guid>
		<description><![CDATA[This is the tenth installment in a series of building a Test-Driven Grocery List application using Jasmine and RequireJS. To learn more about the intent and general concept of the series please visit The Making of a Test-Driven Grocery List Application in JavaScript: Part I
&#8212;
Introduction
When we last left, we properly modified list-controller to support event [...]]]></description>
			<content:encoded><![CDATA[<p><em>This is the tenth installment in a series of building a Test-Driven Grocery List application using <a href="http://pivotal.github.com/jasmine/" target="_blank">Jasmine</a> and <a href="http://requirejs.org" target="_blank">RequireJS</a>. To learn more about the intent and general concept of the series please visit <a href="http://custardbelly.com/blog/2012/11/26/the-making-of-a-test-driven-grocery-list-application-in-javascript-part-i/">The Making of a Test-Driven Grocery List Application in JavaScript: Part I</a></em><br />
&#8212;</p>
<h2>Introduction</h2>
<p>When we last left, we properly modified <code>list-controller</code> to support event notification upon change to its collection as well as created a <code>storage-service</code> communication layer with <code>localStorage</code>. That gave us some great passing tests, but nothing to show off as the service was not integrated into the <strong>Grocery List</strong> application. In this article, we&#8217;ll do just that, but&#8230;</p>
<h2>Before we hook up list-controller events to storage-service operations&#8230;</h2>
<p>We need a way to supply the <code>list-controller</code> with the stored items. The <code>list-controller</code> has a <code>createNewItem()</code> method, but no methods to provide a previously created item. Since we are not burdening the <code>list-controller</code> in communicating with the <code>storage-service</code> directly, we&#8217;ll need to open up the API to allow items to be added &#8211; at least at the onset.</p>
<h3>Tests</h3>
<p>First we&#8217;ll include all our tests in our <em>specrunner</em> again as changes to <code>list-controller</code> may impact tests across multiple specs. And while we are poking around, let&#8217;s add a spec suite for <code>setItems()</code> on the <code>list-controller</code> and watch it fail:</p>
<p><em>/test/jasmine/spec/list-controller.spec.js</em></p>
<pre class="brush: jscript; first-line: 0; title: ;">
describe('setItems()', function() {

  var itemOne = modelFactory.create(),
      itemTwo = modelFactory.create();

  beforeEach( function() {
    itemOne.name = 'apples';
    itemTwo.name = 'oranges';
    listController.setItems([itemOne, itemTwo]);
  });

  afterEach( function() {
    listController.getItemList().removeAll();
  });

  it('should fill list with provided items', function() {
    var items = listController.getItemList();
    expect(items.itemLength()).toEqual(2);
    expect(items.getItemAt(0)).toBe(itemOne);
    expect(items.getItemAt(1)).toBe(itemTwo);
  });

});
</pre>
<p>This simple first spec tells us that an array of items can be provided to the <code>list-controller</code> using <code>setItems()</code> and should be accessible by its collection. And we fail with no surprises:<br />
<img src="http://custardbelly.com/blog/images/tdd_js/part_ix_17.png" alt="Failing on setItems of list-controller" /></p>
<h3>list-controller modification</h3>
<p>Throughout this series I have employed a quasi-<a href="http://coderetreat.org/facilitating/activities/tdd-as-if-you-meant-it" target="_blank"><em>&#8220;TDD as if you mean it&#8221;</em></a> approach when creating new components and modifying the API on existing ones. With this modification to the <code>list-controller</code>, I am going to stick to getting the tests to pass by modifying the <code>list-controller</code> directly as I feel it is going to get a little more involved and will require some refactoring that would be better suited by focusing on true implementation.</p>
<p>With that said, let&#8217;s modify <code>list-controller</code> to get that new spec passing:</p>
<p><em>/script/controller/list-controller.js</em></p>
<pre class="brush: jscript; first-line: 19; highlight: [46,47,48]; title: ;">
listController = {
  $view: undefined,
  getItemList: function() {
    return collection;
  },
  getRendererFromItem: function(item) {
    var i = rendererList.itemLength(),
        renderer;
    while( --i &gt; -1 ) {
      renderer = rendererList.getItemAt(i);
      if(renderer.model === item) {
        return renderer;
      }
    }
    return undefined;
  },
  createNewItem: function() {
    var model = modelFactory.create();
    collection.addItem(model);
    return model;
  },
  removeItem: function(item) {
    return collection.removeItem(item);
  },
  setView: function(view) {
    this.$view = (view instanceof $) ? view : $(view);
  },
  setItems: function(items) {
    collection = collectionFactory.create(items);
  }
};
</pre>
<p>Well, that was easy enough!<br />
<img src="http://custardbelly.com/blog/images/tdd_js/part_ix_18.png" alt="Passing on setItems() of list-controller" /></p>
<h3>Tests</h3>
<p>Not so fast&#8230; I think our single spec may be deceiving our expectations. Let&#8217;s add a few more and make sure we are on the right path. To start, we expect changes to these new models to propagate events when it is modified &#8211; such as in the work we have done previously.</p>
<p><em>/test/jasmine/spec/list-controller.spec.js</em></p>
<pre class="brush: jscript; first-line: 62; title: ;">
async.it('should dispatch events of property-change from provided items', function(done) {
  var items = listController.getItemList(),
      itemOne = items.getItemAt(0);
  $(listController).on('save-item', function(event) {
    $(listController).off('save-item');
    expect(event.item).toBe(itemOne);
    done();
  });
  itemOne.marked = true;
});
</pre>
<p>This spec tells us that changes to an item should be notified through the <code>list-controller</code> &#8211; basically the work we had done previously in getting the <code>list-controller</code> to dispatch events related to its underlying collection so as to be captured by observing parties.<br />
<img src="http://custardbelly.com/blog/images/tdd_js/part_ix_19.png" alt="Failing on async timeout of event from item" /></p>
<p>This test actually reveals some refactoring that is required within the <code>list-controller</code>. In essence, creating a new collection from the provided items in <code>setItems()</code> is not enough to have the application work as expected &#8211; each individual item needs to be managed by a <code>list-item-controller</code> which responds and notifies of changes accordingly. We had previously paired an item with a item controller within the <code>collection-change</code> event handler of the collection in <code>list-controller</code>:</p>
<p><em>/script/controller/list-controller.js</em></p>
<pre class="brush: jscript; first-line: 51; title: ;">
(function assignCollectionHandlers($collection) {

  var EventKindEnum = collectionFactory.collectionEventKind,
      isValidValue = function(value) {
        return value &amp;&amp; (value.hasOwnProperty('length') &amp;&amp; value.length &gt; 0);
      };

  $collection.on('collection-change', function(event) {
    var model,
        itemController,
        $itemController,
        $itemView;
    switch( event.kind ) {
      case EventKindEnum.ADD:
        $itemView = $('&lt;li&gt;');
        model = event.items.shift();
        itemController = itemControllerFactory.create($itemView, model);
        $itemController = $(itemController);

        $itemView.appendTo(listController.$view);
        rendererList.addItem(itemController);
        $(listController).trigger(createSaveEvent(model));
        itemController.state = itemControllerFactory.state.EDITABLE;

        $itemController.on('remove', function(event) {
          listController.removeItem(model);
        });
        $itemController.on('commit', function(event) {
          if(!isValidValue(model.name)) {
            listController.removeItem(model);
          }
          else {
            $(listController).trigger(createSaveEvent(model));
          }
        });
        break;
      case EventKindEnum.REMOVE:
        model = event.items.shift();
        itemController = listController.getRendererFromItem(model),
        $itemController = $(itemController);

        if(itemController) {
          $itemView = itemController.parentView;
          $itemView.remove();
          itemController.dispose();
          $itemController.off('remove');
          $itemController.off('commit');
          rendererList.removeItem(itemController);
          $(listController).trigger(createRemoveEvent(model));
        }
        break;
      case EventKindEnum.RESET:
        break;
    }
  });

}($(collection)));
</pre>
<p>That <a href="http://benalman.com/news/2010/11/immediately-invoked-function-expression/" target="_blank">IIFE</a> was run in the module prior to returning the <code>list-controller</code> instance. Now, we could just copy that code from the <code>EventKindEnum.ADD</code> case and shove it into <code>setItems()</code>, applying it to each item in a loop, but that wouldn&#8217;t be very efficient, not to mention a cry-inducing solution for anyone (including yourself) which need to revisit your code.</p>
<h3>list-controller refactor</h3>
<p>I think we are going to have to get rid of this <strong>IIFE</strong>, but let&#8217;s do that modification in piecemeal; first, let&#8217;s strip out the item management when added to a collection:</p>
<p><em>/script/controller/list-controller.js</em></p>
<pre class="brush: jscript; first-line: 17; highlight: [19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42]; title: ;">
var collection = collectionFactory.create(),
    rendererList = collectionFactory.create(),
    manageItemInList = function(item, listController) {
      var $itemView = $('&lt;li&gt;'),
          itemController = itemControllerFactory.create($itemView, item),
          $itemController = $(itemController),
          isValidValue = function(value) {
            return value &amp;&amp; (value.hasOwnProperty('length') &amp;&amp; value.length &gt; 0);
          };

      $itemView.appendTo(listController.$view);
      rendererList.addItem(itemController);

      $itemController.on('remove', function(event) {
        listController.removeItem(item);
      });
      $itemController.on('commit', function(event) {
        if(!isValidValue(item.name)) {
          listController.removeItem(item);
        }
        else {
          $(listController).trigger(createSaveEvent(item));
        }
      });
      return itemController;
    },
    listController = {
      $view: undefined,
      ...
    };
</pre>
<p>Most of what was held in the <code>EventKindEnum.ADD</code> case of the <code>collection-change</code> handler has been moved to its own function expression &#8211; <code>manageItemInList()</code>. If we look at how this case is modified we see that we have left state initialization and event dispatching:</p>
<p><em>/script/controller/list-controller.js</em></p>
<pre class="brush: jscript; first-line: 85; title: ;">
case EventKindEnum.ADD:
  model = event.items.shift();
  itemController = manageItemInList(model, listController);
  itemController.state = itemControllerFactory.state.EDITABLE;
  $(listController).trigger(createSaveEvent(model));
  break;
</pre>
<p>When an item is added to the collection and the list-controller is notified, it creates a new <code>list-item-controller</code> using <code>manageItemInList()</code>, sets the controller&#8217;s state to <code>EDITABLE</code> and notifies of its addition. The last two operations are of note, as they only pertain to <em>new</em> additions to the collection &#8211; we don&#8217;t want such things for existing items being added to the list from <code>setItems()</code>.</p>
<p><em>/script/controller/list-controller.js</em></p>
<pre class="brush: jscript; first-line: 70; highlight: [71,72,73,74]; title: ;">
setItems: function(items) {
  var i, length = items.length;
  collection = collectionFactory.create();
  for( i = 0; i &lt; length; i++ ) {
    manageItemInList(items[i], this);
    collection.addItem(items[i]);
  }
}
</pre>
<p>Now if we run the tests again:<br />
<img src="http://custardbelly.com/blog/images/tdd_js/part_ix_20.png" alt="Passing on modifications to item management in list-controller" /></p>
<p>Passing! </p>
<h3>Tests</h3>
<p>I don&#8217;t think we are out of the woods yet, however&#8230; Let&#8217;s continue to add more expectations about setting the collection through <code>setItems() </code>on <code>list-controller</code>:</p>
<p><em>/test/jasmine/spec/list-controller.spec.js</em></p>
<pre class="brush: jscript; first-line: 75; title: ;">
async.it('should dispatch event of remove-item from collection', function(done) {
  $(listController).on('remove-item', function(event) {
    $(listController).off('remove-item');
    expect(event.item).toBe(itemOne);
    done();
  });
  listController.removeItem(itemOne);
});
</pre>
<p>This test ensures that the <code>list-controller</code> should still be responding to and notifying of changes to the new collection created through <code>setItems()</code> just as it should if the <code>list-controller</code> was only being instructed to modify the collection through calls to <code>createNewItem()</code>.</p>
<h3>list-controller refactoring</h3>
<p>To save you some time in downloading more images, believe me when I tell you I just put us back in <span style="color: red;">red</span> <img src='http://darko.liquidweb.com/~custardb/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  The reason being that dang <code>assignCollectionHandlers</code> <a href="http://benalman.com/news/2010/11/immediately-invoked-function-expression/" target="_blank">IIFE</a>. The collection that is created in <code>setItems()</code> is not being observed. The <strong>IIFE</strong> to assign events handlers is only run upon load of the module and only targets the collection instantiated in its declaration. In other words, any new collections will not be observed.</p>
<p>I say we move that <strong>IIFE</strong> out into its own expression:</p>
<p><em>/script/controller/list-controller.js</em></p>
<pre class="brush: jscript; first-line: 17; highlight: [19]; title: ;">
var collection = collectionFactory.create(),
    rendererList = collectionFactory.create(),
    assignCollectionHandlers = function($collection) {
      var EventKindEnum = collectionFactory.collectionEventKind;
      $collection.on('collection-change', function(event) {
        var model,
            itemController,
            $itemController,
            $itemView;
        switch( event.kind ) {
          case EventKindEnum.ADD:
            model = event.items.shift();
            itemController = manageItemInList(model, listController);
            itemController.state = itemControllerFactory.state.EDITABLE;
            $(listController).trigger(createSaveEvent(model));
            break;
          case EventKindEnum.REMOVE:
            model = event.items.shift();
            itemController = listController.getRendererFromItem(model),
            $itemController = $(itemController);

            if(itemController) {
              $itemView = itemController.parentView;
              $itemView.remove();
              itemController.dispose();
              $itemController.off('remove');
              $itemController.off('commit');
              rendererList.removeItem(itemController);
              $(listController).trigger(createRemoveEvent(model));
            }
            break;
          case EventKindEnum.RESET:
            break;
        }
      });
    },
    manageItemInList = function(item, listController) {
      // implementation removed to reduce noise
    },
    listController = {
      // implementation removed to reduce noise
    }
</pre>
<p>We basically took what was the named <code>assignCollectionHandlers</code> <strong>IIFE</strong> and added it to the variable declarations within the <code>list-controller</code> module. That changes the code between those declarations and the return of the <code>listController</code> instance to:</p>
<p><em>/script/controller/list-controller.js</em></p>
<pre class="brush: jscript; first-line: 17; highlight: [29]; title: ;">
var collection = collectionFactory.create(),
    rendererList = collectionFactory.create(),
    assignCollectionHandlers = function($collection) {
      // implementation removed to reduce noise
    },
    manageItemInList = function(item, listController) {
      // implementation removed to reduce noise
    },
    listController = {
      // implementation removed to reduce noise
    };

assignCollectionHandlers($(collection));

return listController;
</pre>
<p>With those changes we are still failing on the last spec we created, but more importantly we have not caused any other tests to fail!<br />
<img src="http://custardbelly.com/blog/images/tdd_js/part_ix_21.png" alt="Still failing, but failing well!" /></p>
<p>Let&#8217;s get that last spec to pass:</p>
<p><em>/script/controller/list-controller.js</em></p>
<pre class="brush: jscript; first-line: 104; highlight: [110]; title: ;">
setItems: function(items) {
  var i, length = items.length;
  collection = collectionFactory.create();
  for( i = 0; i &lt; length; i++ ) {
    manageItemInList(items[i], this);
    collection.addItem(items[i]);
  }
  assignCollectionHandlers($(collection));
}
</pre>
<p>Hurrah!<br />
<img src="http://custardbelly.com/blog/images/tdd_js/part_ix_22.png" alt="Passing again!" /></p>
<p>Tagged <strong>0.1.13</strong>: <a href="https://github.com/bustardcelly/grocery-ls/tree/0.1.13" target="_blank">https://github.com/bustardcelly/grocery-ls/tree/0.1.13</a></p>
<h2>Hooking it all together</h2>
<p>We have created our <code>storage-service</code> to communicate with <code>localStorage</code>, modified <code>list-controller</code> to dispatch events and accept initial items for its collection and all our tests are still passing! It&#8217;s a wonderous feeling. Now let&#8217;s get to actually hooking them up so that the <code>storage-service</code> is told how to handle changes to the list by responding to <code>list-controller</code> events.</p>
<p>Normally, in such situations I would create another component to the application that would serve as an mediator for such integration, receiving events from <code>list-controller</code> and invoking the <code>storage-service</code>. Naturally, that would also call for more tests in assuring that the mediator did its job correctly. I am not going to do that here. This is a small application meant for our own personal use and this series has gotten quite long; I don&#8217;t want to scare you away by adding more dependencies, but I would encourage you to do so on your own if you feel so&#8230;. just don&#8217;t forget the tests!</p>
<p>I think modifying the main JavaScript file (<em>/script/grocery-ls.js</em>) that defines the module dependencies and initializes the <strong>Grocery List</strong> application is fine enough for the task at hand:</p>
<p><em>/script/grocery-ls.js</em></p>
<pre class="brush: jscript; first-line: 1; highlight: [12,15,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34]; title: ;">
(function(window, require) {

  require.config({
    baseUrl: &quot;.&quot;,
    paths: {
      &quot;lib&quot;: &quot;./lib&quot;,
      &quot;script&quot;: &quot;./script&quot;,
      &quot;jquery&quot;: &quot;./lib/jquery-1.8.3.min&quot;
    }
  });

  require( ['jquery', 'script/controller/list-controller', 'script/service/storage-service'],
            function($, listController, storageService) {

    var $listController = $(listController);
    listController.setView($('section.groceries ul'));

    storageService.getItems().then(function(items) {
      listController.setItems(items);
    });
    $listController.on('save-item', function(event) {
      storageService.saveItem(event.item).then(function(item) {
        console.log('Item saved! ' + item.name);
      }, function(error) {
        console.log('Item not saved: ' + error)
      });
    });
    $listController.on('remove-item', function(event) {
      storageService.removeItem(event.item).then(function(item) {
        console.log('Item removed! ' + item.name);
      }, function(error) {
        console.log('Item not removed: ' + error);
      });
    });
    $('#add-item-button').on('click', function(event) {
      listController.createNewItem();
    });

  });

}(window, requirejs));
</pre>
<p>Just a slight modification to the main file. We added <code>storage-service</code> as an initial dependency, request and supply stored items to the list-controller and respond to <code>save-item</code> and <code>remove-item</code> events, forwarding actions along to the <code>storage-service</code> appropriately.</p>
<p>If we run the application now, we can add, mark-off, remove items from the list. Same as before, but now, if we refresh the page, items and their state a persisted!</p>
<p><img src="http://custardbelly.com/blog/images/tdd_js/part_ix_27.png" alt="Grocery list application" /></p>
<p><small>It may look a little different than your if you have been following along in the code. I added some nice styling and committed it to the repo.</small></p>
<p>Tagged <strong>0.2.0</strong> : <a href="https://github.com/bustardcelly/grocery-ls/tree/0.2.0" target="_blank">https://github.com/bustardcelly/grocery-ls/tree/0.2.0</a></p>
<h2>Conclusion</h2>
<p>We have completed our <strong>Grocery List</strong> application and have it fully tested (well, hopefully <img src='http://darko.liquidweb.com/~custardb/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ). We now have a grocery list that we can curate and is persisted in the browser. It should be noted that it is not persistent across browser<strong>s</strong>, plural &#8211; so make sure to open it in the same browser on your mobile device when creating the list and shopping. I am most likely going to whip up a little server to persist the list remotely, but am not going to document that in this series. It may end up in the <a href="https://github.com/bustardcelly/grocery-ls">github repo</a> eventually, however, so keep an eye out.</p>
<p>Thanks for sticking around in this long series (<em>ten parts!</em>) of building an application by trying to adhere to <strong>TDD</strong>. I may have gone off course here and there, but I hope it was informative in any way.</p>
<p>Cheers!</p>
<p>&#8212;-</p>
<h1>Link Dump</h1>
<h2>Reference</h2>
<p><a href="http://tddjs.com/" target="_blank">Test-Driven JavaScript Development by Christian Johansen</a><br />
<a href="http://dannorth.net/introducing-bdd/" target="_blank">Introducing BDD by Dan North</a><br />
<a href="http://cumulative-hypotheses.org/2011/08/30/tdd-as-if-you-meant-it/">TDD as if you Meant it by Keith Braithwaite</a><br />
<a href="http://requirejs.org/" target="_blank">RequireJS</a><br />
<a href="https://github.com/amdjs/amdjs-api/wiki/AMD" target="_blank">AMD</a><br />
<a href="http://pivotal.github.com/jasmine/" target="_blank">Jasmine</a><br />
<a href="http://sinonjs.org/" target="_blank">Sinon</a><br />
<a href="https://github.com/derickbailey/jasmine.async" target="_blank">Jasmine.Async</a></p>
<h2>Post Series</h2>
<p><a href="https://github.com/bustardcelly/grocery-ls">grocery-ls github repo</a><br />
<a href="http://custardbelly.com/blog/2012/11/26/the-making-of-a-test-driven-grocery-list-application-in-javascript-part-i" target="_blank">Part I &#8211; Introduction</a><br />
<a href="http://custardbelly.com/blog/2012/11/26/the-making-of-a-test-driven-grocery-list-application-in-js-part-ii">Part II &#8211; Feature: Add Item</a><br />
<a href="http://custardbelly.com/blog/2012/12/06/the-making-of-a-test-driven-grocery-list-application-in-js-part-iii">Part III &#8211; Feature: Mark-Off Item</a><br />
<a href="http://custardbelly.com/blog/2012/12/17/the-making-of-a-test-driven-grocery-list-application-in-js-part-iv">Part IV &#8211; Feature: List-Item-Controller</a><br />
<a href="http://custardbelly.com/blog/2012/12/31/the-making-of-a-test-driven-grocery-list-application-in-js-part-v/">Part V &#8211; Feature: List-Controller Refactoring</a><br />
<a href="http://custardbelly.com/blog/2013/01/08/the-making-of-a-test-driven-grocery-list-application-in-js-part-vi/" target="_blank">Part VI &#8211; Back to Passing</a><br />
<a href="http://custardbelly.com/blog/2013/01/17/the-making-of-a-test-driven-grocery-list-application-in-js-part-vii/">Part VII &#8211; Remove Item</a><br />
<a href="http://custardbelly.com/blog/2013/01/22/the-making-of-a-test-driven-grocery-list-application-part-viii/">Part VIII &#8211; Bug Fixing</a><br />
<a href="http://custardbelly.com/blog/2013/02/15/the-making-of-a-test-driven-grocery-list-application-in-js-part-ix/">Part IX &#8211; Persistence</a><br />
<a href="http://custardbelly.com/blog/2013/03/06/the-making-of-a-test-driven-grocery-list-application-in-js-part-x/">Part X &#8211; It Lives!</a></p>
]]></content:encoded>
			<wfw:commentRss>http://custardbelly.com/blog/2013/03/06/the-making-of-a-test-driven-grocery-list-application-in-js-part-x/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Making of a Test-Driven Grocery List Application in JS: Part IX</title>
		<link>http://custardbelly.com/blog/2013/02/15/the-making-of-a-test-driven-grocery-list-application-in-js-part-ix/</link>
		<comments>http://custardbelly.com/blog/2013/02/15/the-making-of-a-test-driven-grocery-list-application-in-js-part-ix/#comments</comments>
		<pubDate>Fri, 15 Feb 2013 14:47:48 +0000</pubDate>
		<dc:creator>todd anderson</dc:creator>
				<category><![CDATA[AMD]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[RequireJS]]></category>
		<category><![CDATA[grocery-ls]]></category>
		<category><![CDATA[jasmine]]></category>
		<category><![CDATA[unit-testing]]></category>

		<guid isPermaLink="false">http://custardbelly.com/blog/?p=777</guid>
		<description><![CDATA[This is the ninth installment in a series of building a Test-Driven Grocery List application using Jasmine and RequireJS. To learn more about the intent and general concept of the series please visit The Making of a Test-Driven Grocery List Application in JavaScript: Part I
&#8212;
Introduction
In the previous article, we pretty much wrapped up all the [...]]]></description>
			<content:encoded><![CDATA[<p><em>This is the ninth installment in a series of building a Test-Driven Grocery List application using <a href="http://pivotal.github.com/jasmine/" target="_blank">Jasmine</a> and <a href="http://requirejs.org" target="_blank">RequireJS</a>. To learn more about the intent and general concept of the series please visit <a href="http://custardbelly.com/blog/2012/11/26/the-making-of-a-test-driven-grocery-list-application-in-javascript-part-i/">The Making of a Test-Driven Grocery List Application in JavaScript: Part I</a></em><br />
&#8212;</p>
<h1>Introduction</h1>
<p>In the <a href="http://custardbelly.com/blog/2013/01/22/the-making-of-a-test-driven-grocery-list-application-part-viii/" target="_blank">previous article</a>, we pretty much wrapped up all the user-based functionality and ended with a working <strong>Grocery List</strong> application that we could start using. There is one little snag though&#8230; no persistance. If you made this gloriously elaborate list that detailed everything you needed at the store, then closed the browser and reopened it, the list was gone! That will not do.</p>
<p>There are many factors and paradigms to consider in choosing the level of persistence when it comes to handling session and user based applications. Without introducing a discussion about authentication, when approaching the integration persistence you have to take into account system-based vs user-based persistence, client-side vs server-side storage, and &#8211; nowadays, more commonly &#8211; the cross pollination of the two: <a href="http://en.wikipedia.org/wiki/Occasionally_connected_computing" target="_blank">occasional-connectivity</a>. (<em>not to mention browser support in all this</em>) We won&#8217;t be getting into all of that <img src='http://darko.liquidweb.com/~custardb/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  We&#8217;ll be using the <code>localStorage</code> of today&#8217;s modern browser.</p>
<p>The intent of this article in the series is to implement client-side, browser-based persistence for the <strong>Grocery List</strong> application. It would be nice to store our list remotely so it can be accessed by all browsers on all devices, but I feel it would introduce too many new libraries, software and concepts to this series. I will most likely add it personally after this series is over, and I invite you to as well &#8211; keeping in mind to do it using TDD <img src='http://darko.liquidweb.com/~custardb/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  The most I can offer at this point, is to keep the code we will write clean enough to support such future endeavours.</p>
<h1>What Tests to Modify to Get Us There?</h1>
<p>Good question. Let&#8217;s first think about what actions will prompt an update to the list in storage. Actually, if we look at the feature specs we have created throughout this series and separated out into the <code>/feature</code> directory itself, we pretty much have all the defined actions that will trigger an update to the stored list:<br />
<img src="http://custardbelly.com/blog/images/tdd_js/part_ix_1.png" alt="Spec listing" /></p>
<p>All of these features are a result from interacting with the <code>list-controller</code>. My first inkling is to add responsibility to the <code>list-controller</code> so that, along with the other operations it handles in list management, it communicates with a service layer to update the <strong>Grocery List</strong> in storage. However, I think that would add too much burden on the <code>list-controller</code> and, when taking into account that requirements around storage may change, the introduction of such complexity into the <code>list-controller</code> may quickly make our tests feel chaotic.</p>
<p>As such, I propose that we should start off with the expectation that the <code>list-controller</code> will notify of its underlying collection having been modified, not only upon its change in length, but of the items within the collection, as well. We can then capture those events and forward them on to whichever service implementation we have without having to pass that dependency into the <code>list-controller</code> and burdening it with such communication.</p>
<h2>New Expectation for Add Item</h2>
<p>To start, let&#8217;s add a quick spec to the <em>Add Item</em> feature that defines an expectation from the <code>list-controller</code> to notify when an item has been added:</p>
<p><em>/test/jasmine/spec/feature/additem.spec.js</em></p>
<pre class="brush: jscript; first-line: 45; title: ;">
async.it('should dispatch a save-item event', function(done) {
  var newItem;

  $(listController).on('save-item', function(event) {
    expect(event.item).not.toBeUndefined();
    $(listController).off('save-item');
    done();
  });
  newItem = listController.createNewItem();
});
</pre>
<p>In creating this expectation, we have also begun to define the actual make-up of the event we intend to receive: the event type being <code>save-item</code> and the access of the <code>item</code> that was saved.</p>
<p>Run it and we are red, as expected:<br />
<img src="http://custardbelly.com/blog/images/tdd_js/part_ix_2.png" alt="Failing test on add item event response" /></p>
<p>Taking what we have defined as our expectation when an item is added, we&#8217;ll modify the list-controller to get this passing. First we&#8217;ll add a factory method to generate <code>save-item</code> events:</p>
<p><em>/script/controller/list-controller.js</em></p>
<pre class="brush: jscript; first-line: 5; title: ;">
function createSaveEvent(item) {
  var event = $.Event('save-item');
  event.item = item;
  return event;
}
</pre>
<p>Fairly straight-forward and similar to other event factory methods declared previously in this series. Since we are addressing an expectation of event notification on add of item, we know where in the list-controller we can add that dispatch &#8211; in response to the addition of an item on the collection:</p>
<p><em>/script/controller/list-controller.js</em></p>
<pre class="brush: jscript; first-line: 61; highlight: [63]; title: ;">
$itemView.appendTo(listController.$view);
rendererList.addItem(itemController);
$(listController).trigger(createSaveEvent(model));
itemController.state = itemControllerFactory.state.EDITABLE;
</pre>
<p>Back in business.<br />
<img src="http://custardbelly.com/blog/images/tdd_js/part_ix_3.png" alt="Passing test on add item event response" /></p>
<h2>New Expectation for Remove Item</h2>
<p>Let&#8217;s quickly just do a similar modification to the <code>list-controller</code> with regards to the <em>Remove Item</em> feature. First we&#8217;ll append a spec in the <em>removeitem.spec</em> suite with an expectation of being notified on <code>remove-item</code>:</p>
<p><em>/test/jasmine/spec/feature/removeitem.spec.js</em></p>
<pre class="brush: jscript; first-line: 30; title: ;">
async.it('should dispatch a remove-item event', function(done) {
  var removedItem;

  $(listController).on('remove-item', function(event) {
    expect(event.item).not.toBeUndefined();
    $(listController).off('remove-item');
    done();
  });
  removedItem = listController.removeItem(groceryItem);
});
</pre>
<p>Sparing you another image of the specrunner turning <span style='color: red;'>red</span>, that will fail with the timeout that we saw before. We&#8217;ll fix that up by adding a trigger in the removal of an item from the collection handler in <code>list-controller</code>. First with the addition of a factory method for the <code>remove-item</code> event:</p>
<p><em>/script/controller/list-controller.js</em></p>
<pre class="brush: jscript; first-line: 11; title: ;">
function createRemoveEvent(item) {
  var event = $.Event('remove-item');
  event.item = item;
  return event;
}
</pre>
<p>And then with an additional line to the <code>remove</code> response on the collection:</p>
<p><em>/script/controller/list-controller.js</em></p>
<pre class="brush: jscript; first-line: 81; highlight: [93]; title: ;">
case EventKindEnum.REMOVE:
  model = event.items.shift();
  itemController = listController.getRendererFromItem(model),
  $itemController = $(itemController);

  if(itemController) {
    $itemView = itemController.parentView;
    $itemView.remove();
    itemController.dispose();
    $itemController.off('remove');
    $itemController.off('commit');
    rendererList.removeItem(itemController);
    $(listController).trigger(createRemoveEvent(model));
  }
break;
</pre>
<p>Run the tests, and we are back to passing:<br />
<img src="http://custardbelly.com/blog/images/tdd_js/part_ix_4.png" alt="Passing on removal event from list-controller" /></p>
<h2>New Expectation for Save Item</h2>
<p>Sort of repetitive, but we are on a roll&#8230; let&#8217;s go through the similar process to ensure that a notification for <code>save-item</code> is dispatched when the user has modified its name and committed it to the list &#8211; the <em>Save Item</em> feature we added in the <a href="http://custardbelly.com/blog/2013/01/22/the-making-of-a-test-driven-grocery-list-application-part-viii/" target="_blank">last article</a>.</p>
<p><em>/test/jasmine/spec/feature/saveitem.spec.js</em></p>
<pre class="brush: jscript; first-line: 79; title: ;">
async.it('should dispatch a save-item event', function(done) {

  $(listController).on('save-item', function(event) {
    expect(event.item).toEqual(item);
    $(listController).off('save-item');
    done();
  });

  item.name = itemName;
  itemRenderer.state = itemControllerFactory.state.UNEDITABLE;
});
</pre>
<p>That&#8217;ll put us in the <span style="color: red;">red</span> with the same old timeout issue. Getting back to green, we&#8217;ll trigger the <code>save-item</code> event upon committal of the item to the list, which if you remember &#8211; and is described in the test &#8211; is in response to the <code>list-item-controller</code> notifying of change to the item model:</p>
<p><em>/test/jasmine/spec/feature/list-controller.js</em></p>
<pre class="brush: jscript; first-line: 75; highlight: [79,80,81]; title: ;">
$itemController.on('commit', function(event) {
  if(!isValidValue(model.name)) {
    listController.removeItem(model);
  }
  else {
    $(listController).trigger(createSaveEvent(model));
  }
});
</pre>
<p>Back to green!<br />
<img src="http://custardbelly.com/blog/images/tdd_js/part_ix_5.png" alt="Passing on commital of item form list-item-controller" /></p>
<p>The amount of those little dots just keeps growing. Makes you feel all warm inside. Cherish that, &#8217;cause it will go away&#8230;</p>
<h3>Hold Up</h3>
<p>Just stepping back, it may seem a little odd that we are calling <code>save-item</code> when we add and commit the item to the list; after all they are the same item, we do we need to notify on save multiple times? The reason being is that upon any modification to an item &#8211; including its existence &#8211; the store needs to be modified. We haven&#8217;t gotten into the service layer for storage yet, but it will be abstracted out that a response from save-item will be internally handled as whether to append the item (from add) or to update an item already existant (from commit). Until we get to that service layer implementation for <code>localStorage</code>, we&#8217;ll go about setting expectations of <code>save-item</code> notification on modification to an item.</p>
<p>Which actually brings up a good point&#8230; what about marking off an item? We will need to notify on change of an item being marked off, as well.</p>
<h2>New Expectation for Mark-Off Item</h2>
<p>We tackled the <em>Mark-Off Item</em> feature a <a href="http://custardbelly.com/blog/2012/12/06/the-making-of-a-test-driven-grocery-list-application-in-js-part-iii/" target="_blank">while back</a> in this series. Just a quick refresher on the story:</p>
<p><em>// story</em><br />
—<br />
<strong>Story</strong>: Item is marked off on grocery list</p>
<p><strong>In order to</strong> remember what items have already made it to the cart<br />
<strong>As a</strong> grocery shopper<br />
<strong>I want to</strong> mark an item as being attained on the grocery list.<br />
—</p>
<p>We implemented the feature, and upon user press of the item while in non-edit mode, it toggles its <code>marked</code> property on the model and updates the UI to add or remove a <del datetime="2013-02-01T10:32:47+00:00">strikethrough</del> on the label.</p>
<p>We&#8217;ve got a spec suite for the <em>Mark-Off Item</em> feature already, so we&#8217;ll append an expectation for <code>save-item</code> to it just as we have done with the other feature specs in this article:</p>
<p><em>/test/jasmine/spec/feature/markitem.spec.js</em></p>
<pre class="brush: jscript; first-line: 44; title: ;">
async.it('should dispatch a save-item event', function(done) {

   var timeout = setTimeout(function() {
     clearTimeout(timeout);
     $(listController).off('save-item');
   }, jasmine.DEFAULT_TIMEOUT_INTERNAL);

  $(listController).on('save-item', function(event) {
    expect(event.item).toBe(item);
    $(listController).off('save-item');
    done();
  });

  item.marked = true;
});
</pre>
<p>&#8230; and that will bring us back to <span style="color: red;">failing</span>.<br />
<small>The <code>timeout</code> placed in there is just to ensure that listener(s) to the <code>save-item</code> event are removed regardless of the async test timing out.</small></p>
<p>The resolution to the issue is a trickier one than those of the previous in this article, however. Currently the <code>list-item-controller</code> is the only component that actually concerned with this change in marked status. It is not concerned with notifying any other party of the change to its model. The model does, however, notify of any property changes. I see two ways in which we can get back to <span style="color: green;">passing</span>:</p>
<ol type="a">
<li>Assign a handler for <code>property-change</code> on model when it is first created and returned from <code>listController.createNewItem()</code></li>
<li>Dispatch a <code>commit</code> event from <code>list-item-controller</code> on change to <code>marked</code> property on the underlying model</li>
</ol>
<p>While both options will most likely get us where we need to be, the former adds additional management to the <code>list-controller</code>; its already listening in on <code>commit</code> from its <code>list-item-controller</code> instance, so modifying the <code>list-item-controller</code> to notify of change to the <code>marked</code> property seems to be the path of least resistance.</p>
<p>We had previously set up the <code>commit</code> notification on response from leaving the <code>EDITABLE</code> state of the <code>list-item-controller</code>:</p>
<p><em>/script/controller/list-item-controller.js</em></p>
<pre class="brush: jscript; first-line: 45; title: ;">
// append state-based item.
if(event.newState === stateEnum.UNEDITABLE) {
  controller.parentView.append(controller.$uneditableView);
  controller.save();
}
</pre>
<p>That implementation got us to passing previously in which we described the expectation of a user committing an item to the list with a valid name (un-empty string). Our issue at hand is to also invoke the <code>save()</code> method on <code>list-item-controller</code> when the <code>marked</code> property is modified. In thinking about it now, while the committal of an item is tied to the change of state, it runs a validation on the <code>name</code> property to ensure that the item can be added/kept in the collection &#8211; so, in actuality <code>commit</code> can be tied to property updates to the item model.</p>
<p>As such, let&#8217;s remove line <code>48</code> from the above snippet and insert the invocation of <code>save()</code> to the handler in <code>list-item-controller</code> for <code>property-change</code> on the model:</p>
<p><em>/script/controller/list-item-controller.js</em></p>
<pre class="brush: jscript; first-line: 102; highlight: [105]; title: ;">
$(this.model).on('property-change', (function(controller) {
  return function(event) {
    handlePropertyChange.call(null, controller, event);
    controller.save();
  };
}(this)));
</pre>
<p>Run the specrunner again&#8230;<br />
<img src="http://custardbelly.com/blog/images/tdd_js/part_ix_5_fail.png" alt="We broke it" /></p>
<p>&#8230; and we broke it <img src='http://darko.liquidweb.com/~custardb/blog/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> </p>
<p>The reason for those <span style="color: red;">X</span>&#8217;s is due to the logic we have held in <code>list-controller</code> on save of an item: it checks it&#8217;s <code>name</code> property and removes it from the list if considered an invalid value &#8211; which an empty string is.</p>
<p>I sense some modification to such logic in the future, but for now we can get the tests back to passing by providing a <code>name</code> property value to the created item in our mark-item spec:</p>
<p>/tests/jasmine/spec/feature/markitem.spec.js</p>
<pre class="brush: jscript; first-line: 9; highlight: [11]; title: ;">
beforeEach( function() {
  item = listController.createNewItem();
  item.name = 'apples';
});
</pre>
<p><img src="http://custardbelly.com/blog/images/tdd_js/part_ix_6.png" alt="Passing on model property update" /></p>
<p>We&#8217;re green!</p>
<p>Tagged <strong>0.1.13</strong>: <a href="https://github.com/bustardcelly/grocery-ls/tree/0.1.13" target="_blank">https://github.com/bustardcelly/grocery-ls/tree/0.1.13</a></p>
<h3>Settle Down</h3>
<p>We have verified our expectations of <code>save-item</code> and <code>remove-item</code> events being dispatched from <code>list-controller</code> &#8211; new and model updates issuing the former, removal issuing the later. The work we have done was to separate concerns and not burden the <code>list-controller</code> itself with service communication for persisting the <strong>Grocery List</strong> items across browser sessions, but we have yet to address the actual service layer implementation that will take all these notifications.</p>
<h2>Storage Service</h2>
<p>The <code>storage-service</code> will provide a service layer for communication with storage &#8211; whether that be remote or local. It will serve as a facade to an existing storage of grocery list items persisted somewhere other than the current application session. For the purposes of this article, that persistence layer is going to be the <code>localStorage</code> of the browser.</p>
<p>While fleshing out the storage service and its API, we&#8217;ll <em>loosely</em> use the technique of <a href="http://coderetreat.org/facilitating/activities/tdd-as-if-you-meant-it" target="_blank">&#8216;TDD as if you meant it&#8217;</a>. I say <em>loosely</em> in part because to fully do it and explain each step would be a lot of noise for this article; the main practice point to take away &#8211; and I hope I express &#8211; is that the component you are testing is actually being built while you make the expectations for it pass.</p>
<h3>Tests</h3>
<p>To start, we&#8217;ll create a bare-bones module for our service layer:</p>
<p><em>/script/service/storage-service</em></p>
<pre class="brush: jscript; first-line: 1; title: ;">
define(['jquery'], function($) {

  var store = {};
  return store;

});
</pre>
<p>And let&#8217;s create the beginnings of our test:</p>
<p><em>/test/jasmine/spec/storage-service.spec.js</em></p>
<pre class="brush: jscript; first-line: 1; title: ;">
define(['jquery', 'script/service/storage-service', 'script/model/grocery-ls-item'],
        function($, store, modelFactory) {

  describe('Grocery List storage-service', function() {

    describe('getItems()', function() {

      it('should return of type array', function() {
        expect(false).toEqual(true);
      });

      it('should return array of grocery-ls-item types', function() {
        expect(false).toEqual(true);
      });

    });

  });

});
</pre>
<p>In the test we have set up some tests for the <code>getItems()</code> method for the service. Prior to any implementation, it should be known that communication with the <code>storage-service</code> will be considered asynchronous &#8211; meaning all operations will return a <a href="http://api.jquery.com/category/deferred-object/" target="_blank">jQuery Deferred</a>. This will abstract out the storage proxy that will be employed by the <code>storage-service</code> and will respond in an asynchronous manner regardless of whether the store is immediately accessible &#8211; as in the case of <code>localStorage</code> &#8211; or remote.</p>
<p><small>Truthfully, in practice, I should only do one tests at a time, but we are testing the expectations for access of the same item listing; to save you from reading the ramblings of adding another test, I declared them both at the start.</small></p>
<p>Let&#8217;s stub out the API and start testing and building the <code>storage-service</code>:</p>
<p><em>/test/jasmine/spec/storage-service.spec.js</em></p>
<pre class="brush: jscript; first-line: 6; highlight: [8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,31,32,36,37]; title: ;">
describe('getItems()', function() {

  var items,
      itemOne = modelFactory.create(),
      itemTwo = modelFactory.create(),
      async = new AsyncSpec(this);

  async.beforeEach( function(done) {
    var deferred = $.Deferred(),
        getStub = sinon.stub().returns(deferred);

    deferred.resolve([itemOne, itemTwo]);
    store.getItems = getStub;

    store.getItems().then(function(list) {
      items = list;
      done();
    });
  });

  afterEach( function() {
    //
  });

  it('should return of type array', function() {
    expect(Array.isArray(items)).toEqual(true);
    expect(items.length).toEqual(2);
  });

  it('should return array of grocery-ls-item types', function() {
    expect(items[0]).toBe(itemOne);
    expect(items[1]).toBe(itemTwo);
  });

});
</pre>
<p>In the <code>beforeEach()</code>, we&#8217;re using anonymous stubs from <a href="http://sinonjs.org/" target="_blank">SinonJS</a>, which allow us to stub out methods that may not necessarily already exist on an object. I have used it previously in this series, but we&#8217;ll be using it pretty much exclusively while we stub out the API for the <code>storage-service</code>.</p>
<p>Staying true to our idea that the service will provide an asynchronous communication layer, <code>getItems()</code> returns a deferred which has resolved to a listing of two <code>grocery-ls-item</code> instances in our tests.</p>
<p>Sometimes when working with a single feature, I like to isolate it out from my tests for a bit. Here is what the specrunner reports with running just <strong>storage-service.spec</strong>:<br />
<img src="http://custardbelly.com/blog/images/tdd_js/part_ix_7.png" alt="Passing on succss of getItems() in service" /></p>
<p>We could move that implementation to <code>storage-service</code> module now, but we are sort of in a <a href="http://en.wikipedia.org/wiki/Chicken_or_the_egg" target="_blank">chicken-or-the-egg</a> scenario. We&#8217;ve canned the resolved <code>grocery-ls-item</code> list in the test, but how does the list get filled up in an actual scenario for <code>storage-service</code>? It&#8217;s an excellent question, and something I often puzzle myself with. I mean, we&#8217;ll need a <code>saveItem()</code> method no doubt in order to add items to the store. But shouldn&#8217;t that method now be stubbed out in a new test? And how do I test that <code>saveItem()</code> works without <code>getItems()</code> being already tested and verified? I could go in circles&#8230;</p>
<p>Let&#8217;s just stub out an <code>saveItem()</code> method on <code>storage-service</code> and, afterward, set expectations in another spec suite:</p>
<p><em>/test/jasmine/spec/storage-service.spec.js</em></p>
<pre class="brush: jscript; first-line: 13; highlight: [14,15,18,19,20,21,23,26,27]; title: ;">
async.beforeEach( function(done) {
  var call = 0,
      tempList = [],
      deferred = $.Deferred(),
      getStub = sinon.stub().returns(deferred),
      saveStub = sinon.stub().callsArgOn(0, store),
      appendItem = function() {
        tempList.push((call++%2 === 0) ? itemOne : itemTwo);
      };

  store.saveItem = saveStub;
  store.getItems = getStub;

  store.saveItem(appendItem);
  store.saveItem(appendItem);
  store.getItems().then(function(list) {
    items = list;
    done();
  });
  deferred.resolve(tempList);
});
</pre>
<p>With these modifications, we have assigned an anonymous stub &#8211; <code>saveStub</code> &#8211; as the <code>saveItem</code> method on the <code>store</code> and specified that the function-local <code>appendItem</code> method should be invoked, appending items to the list prior to each of our tests. </p>
<p>A little more work in setup and slightly unrealistic in telling of the arguments to be given to <code>saveItem()</code>, but it kept us on green without having to hard code the result; it&#8217;s a litte truer to life than the previous setup, and still passes:</p>
<p><img src="http://custardbelly.com/blog/images/tdd_js/part_ix_7.png" alt="Passing on succss of getItems() in service" /></p>
<h3>Implementation</h3>
<p>Alright, so I think we should move this out to <code>storage-service</code> now and trash the stubbing in the test &#8211; we&#8217;ve got our expectations:</p>
<p><em>/script/service/storage-service.js</em></p>
<pre class="brush: jscript; first-line: 1; title: ;">
define(['jquery'], function($) {

  var itemCache = [],
      store = {
        saveItem: function(item) {
          var deferred = $.Deferred();
          itemCache[itemCache.length] = item;
          return deferred.resolve(item);
        },
        getItems: function() {
          var deferred = $.Deferred();
          deferred.resolve(itemCache);
          return deferred;
        }
      };

  return store;

});
</pre>
<p><em>/test/jasmine/spec/storage-service.spec.js</em></p>
<pre class="brush: jscript; first-line: 6; title: ;">
describe('getItems()', function() {

  var items,
      itemOne = modelFactory.create(),
      itemTwo = modelFactory.create(),
      async = new AsyncSpec(this);

  async.beforeEach( function(done) {
    store.saveItem(itemOne);
    store.saveItem(itemTwo);
    store.getItems().then(function(value) {
      items = value;
      done();
    });
  });

  afterEach( function() {
    //
  });

  it('should return of type array', function() {
    expect(Array.isArray(items)).toEqual(true);
    expect(items.length).toEqual(2);
  });

  it('should return array of grocery-ls-item types', function() {
    expect(items[0]).toBe(itemOne);
    expect(items[1]).toBe(itemTwo);
  });

});
</pre>
<p>Run that, and we are still green!<br />
<img src="http://custardbelly.com/blog/images/tdd_js/part_ix_7.png" alt="Passing on succss of getItems() in service" /></p>
<h3>Tests</h3>
<p>Now that we can verify that <code>saveItem()</code> is working enough for our <code>getItem</code> spec, let&#8217;s properly set the expectations for <code>saveItem</code>, as well, in our tests:</p>
<p><em>/test/jasmine/spec/storage-service.spec.js</em></p>
<pre class="brush: jscript; first-line: 0; title: ;">
describe('saveItem()', function() {

  var itemOne = modelFactory.create(),
      itemTwo = modelFactory.create(),
      async = new AsyncSpec(this);

  beforeEach( function() {
    store.saveItem(itemOne);
  });

  afterEach( function() {
    //
  });

  async.it('should be grow the length of items', function(done) {
    store.getItems().then( function(items) {
      expect(items.length).toEqual(1);
      done();
    });
  });

});
</pre>
<p>Simple enough. Back to the specrunner:<br />
<img src="http://custardbelly.com/blog/images/tdd_js/part_ix_8.png" alt="Failing on saveItem of storage-service" /></p>
<p>Oh noes! Our expectation is that the length of items is only 1. We have only specified one addition of an item in the setup&#8230; where did the length of 5 come from!? Put down the abacus &#8211; there are better things to throw. But before that, I have an explanation: we haven&#8217;t been cleaning up. We have let <code>afterEach()</code> just quietly be invoked without a job to do.</p>
<p>To do just enough in getting our tests pass, we can update the <code>afterEach()</code> declarations in each spec suite to the following:</p>
<pre class="brush: jscript; title: ;">
async.afterEach( function(done) {
  store.getItems().then(function(items) {
    items.length = 0;
    done();
  });
});
</pre>
<p>That will get us back to passing:<br />
<img src="http://custardbelly.com/blog/images/tdd_js/part_ix_9.png" alt="Passing on saveItem spec." /></p>
<p>I am not particularly fond of that solution, however. Mainly because I think it conveys a usage of the API on <code>storage-service</code> that I would not condone: directly mutating the underlying list of <code>storage-service</code> from another party. </p>
<p>I&#8217;m not gonna get crazy with the lock-down and privacy of properties and start introducing the latest-and-greatest framework that tries to tout that they really are just a library all in the attempt to stop someone from directly accessing the underlying array of items on <code>storage-service</code>. If some developers gonna go crazy and do so, hopefully we can find it in more tests later or they can look at our tests as a guideline of how to do what they want. </p>
<p>As such, I think we should add a method to <code>storage-service</code> that simply allows for emptying the list. First the expectation:</p>
<p><em>/test/jasmine/spec/storage-service.spec.js</em></p>
<pre class="brush: jscript; first-line: 61; title: ;">
describe('empty()', function() {

  var itemOne = modelFactory.create(),
      itemTwo = modelFactory.create(),
      async = new AsyncSpec(this);

  beforeEach( function() {
    store.saveItem(itemOne);
    store.saveItem(itemTwo);
  });

  afterEach( function() {
    store.empty();
  });

  async.it('should be appended to the list of items', function(done) {
    store.empty().then( function(items) {
      expect(items.length).toEqual(0);
      done();
    });
  });

});
</pre>
<p><img src="http://custardbelly.com/blog/images/tdd_js/part_ix_10.png" alt="Failing on empty()" /></p>
<p><em>/script/service/storage-service.js</em></p>
<pre class="brush: jscript; first-line: 1; highlight: [15,16,17,18,19,20]; title: ;">
define(['jquery'], function($) {

  var itemCache = [],
      store = {
        saveItem: function(item) {
          var deferred = $.Deferred();
          itemCache[itemCache.length] = item;
          return deferred.resolve(item);
        },
        getItems: function() {
          var deferred = $.Deferred();
          deferred.resolve(itemCache);
          return deferred;
        },
        empty: function() {
          var deferred = $.Deferred();
          itemCache.length = 0;
          deferred.resolve(itemCache);
          return deferred;
        }
      };

  return store;
});
</pre>
<p><img src="http://custardbelly.com/blog/images/tdd_js/part_ix_11.png" alt="Passing on empty()" /></p>
<p>Alright! We are passing expectations on three parts of the API for <code>storage-service</code>. Now let&#8217;s think of what else we need&#8230; I think only a <code>removeItem()</code> method will suffice. In working as we have previously in this article &#8211; stubbing out methods to be added to the <code>storage-service</code> implementation &#8211; we can add a spec suite for <code>removeItem()</code> such as the following:</p>
<p><em>/test/jasmine/spec/storage-service.spec.js</em></p>
<pre class="brush: jscript; first-line: 85; title: ;">
describe('removeItem()', function() {

  var items,
      itemOne = modelFactory.create(),
      itemTwo = modelFactory.create(),
      async = new AsyncSpec(this),
      deferred = $.Deferred(),
      removeItemFromList = function() {
        deferred.resolve(items.splice(0, 1));
      };

  async.beforeEach( function(done) {
    var removeItemStub = sinon.stub().returns(deferred).callsArgOn(0, store);

    store.saveItem(itemOne);
    store.saveItem(itemTwo);
    store.removeItem = removeItemStub;
    store.getItems().then( function(value) {
      items = value;
      done();
    });
  });

  afterEach( function() {
    store.empty();
  });

  async.it('should shorten length of the list', function(done) {
    store.removeItem(removeItemFromList).then( function(item) {
      store.getItems().then( function(items) {
        expect(items.length).toEqual(1);
        done();
      });
    });
  });

});
</pre>
<p><img src="http://custardbelly.com/blog/images/tdd_js/part_ix_12.png" alt="Passing on initial removeItem()" /></p>
<p>I think there are more expectations to assert for the <code>removeItem()</code> spec suite, but for now we are passing and we&#8217;ll move the implementation over to <code>storage-service</code>:</p>
<p><em>/script/service/storage-service.js</em></p>
<pre class="brush: jscript; first-line: 1; highlight: [10,11,12,13,14,15,16,17,18,19,20]; title: ;">
define(['jquery'], function($) {

  var itemCache = [],
      store = {
        saveItem: function(item) {
          var deferred = $.Deferred();
          itemCache[itemCache.length] = item;
          return deferred.resolve(item);
        },
        removeItem: function(item) {
          var deferred = $.Deferred(),
              itemIndex = itemCache.indexOf(item),
              removedItem;

          if(itemIndex &gt; -1) {
            itemCache.splice(itemIndex, 1);
            removedItem = item;
          }
          return deferred.resolve(removedItem);
        },
        getItems: function() {
          var deferred = $.Deferred();
          deferred.resolve(itemCache);
          return deferred;
        },
        empty: function() {
          var deferred = $.Deferred();
          itemCache.length = 0;
          deferred.resolve(itemCache);
          return deferred;
        }
      };

  return store;

});
</pre>
<p>Now, we&#8217;ll update the spec suite for <code>removeItem()</code> and add a few more expectations to ensure the item removal process is correct:</p>
<p><em>/test/jasmine/spec/storage-service.spec.js</em></p>
<pre class="brush: jscript; first-line: 85; title: ;">
describe('removeItem()', function() {

  var itemOne = modelFactory.create(),
      itemTwo = modelFactory.create(),
      async = new AsyncSpec(this);

  beforeEach( function() {
    itemOne.name = 'one';
    store.saveItem(itemOne);
    store.saveItem(itemTwo);
  });

  afterEach( function() {
    store.empty();
  });

  async.it('should shorten length of the list', function(done) {
    store.removeItem(itemOne).then( function(item) {
      store.getItems().then( function(items) {
        expect(items.length).toEqual(1);
        done();
      });
    });
  });

  async.it('should remove item specified from the list', function(done) {
    store.removeItem(itemOne).then( function(item) {
      store.getItems().then( function(items) {
        expect(items.indexOf(itemOne)).toEqual(-1);
        done();
      });
    });
  });

  async.it('should return the item removed if found', function(done) {
    store.removeItem(itemOne).then( function(item) {
      expect(item).toEqual(itemOne);
      done();
    });
  });

  async.it('should return undefined if item not found', function(done) {
    store.removeItem(modelFactory.create()).then( function(item) {
      expect(item).toBeUndefined();
      done();
    });
  });

});
</pre>
<p>&#8230; and we&#8217;re still in business!<br />
<img src="http://custardbelly.com/blog/images/tdd_js/part_ix_13.png" alt="Complete and passing removeItem specs" /></p>
<h3>Revisiting saveItem()</h3>
<p>When we setup the <code>saveItem</code> stub for our <code>getItem()</code> spec suite, we really only focused on getting the expectations to pass. To get back to <span style="color: green;">green</span> &#8211; at the time &#8211; we were only concerned with appending items to the list. I think this needs to be looked at again.</p>
<p>If we remember back to the notifications we set up for the <code>list-controller</code>, it will dispatch a <code>save-item</code> event upon the existence of a new item, as well as the modification to an existing item. So we will pass that item through the <code>storage-service</code> using <code>saveItem()</code> but we don&#8217;t want to continually append items that are previously stored to the list &#8211; if so, we&#8217;d be buying a lot of <del datetime="2013-02-07T10:18:31+00:00">spinich</del> <del datetime="2013-02-07T10:18:31+00:00">spinnash</del> spinach.</p>
<p><small>Normally I wouldn&#8217;t cut corners: a feature spec should be written up for what I have described here prior to modifying the tests. To save you some scrolling, however, I decided to not include walking through one and letting the expectations that we define in the following speak for the specification.</small></p>
<p><em>/test/jasmine/spec/storage-service.spec.js</em></p>
<pre class="brush: jscript; first-line: 38; highlight: [59,60,61,62,63,64,65,66,67]; title: ;">
describe('saveItem()', function() {

  var itemOne = modelFactory.create(),
      itemTwo = modelFactory.create(),
      async = new AsyncSpec(this);

  beforeEach( function() {
    store.saveItem(itemOne);
  });

  afterEach( function() {
    store.empty();
  });

  async.it('should grow the length of items on new item', function(done) {
    store.getItems().then( function(items) {
      expect(items.length).toEqual(1);
      done();
    });
  });

  async.it('should not grow the length of items on pre-existing item', function(done) {
    itemOne.name = 'oranges';
    store.saveItem(itemOne).then( function(item) {
      store.getItems().then( function(items) {
        expect(items.length).toEqual(1);
        done();
      });
    });
  });

});
</pre>
<p>We modified the description of the original expectation to state that the items list should only grow on new existence and added a new expectation that previously stored items do not get appended to the stored list:</p>
<p><img src="http://custardbelly.com/blog/images/tdd_js/part_ix_14.png" alt="Failing update to saveItem() specs." /></p>
<p>As expected <img src='http://darko.liquidweb.com/~custardb/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Let&#8217;s update <code>saveItem()</code> on the <code>storage-service</code> to account for this:</p>
<p><em>/script/service/storage-service.js</em></p>
<pre class="brush: jscript; first-line: 5; title: ;">
saveItem: function(item) {
  var deferred = $.Deferred(),
      index = itemCache.indexOf(item);
  if(index === -1) {
    itemCache[itemCache.length] = item;
  }
  return deferred.resolve(item);
}
</pre>
<p><img src="http://custardbelly.com/blog/images/tdd_js/part_ix_15.png" alt="Passing on new expectation for saveItem()" /></p>
<p>Not leaving any to chance, let&#8217;s add a couple more expectations as to how items are placed and how they remain in their places:</p>
<p><em>/test/jasmine/spec/storage-service.spec.js</em></p>
<pre class="brush: jscript; first-line: 71; title: ;">
describe('saveItem() multiples', function() {

  var itemOne = modelFactory.create(),
      itemTwo = modelFactory.create(),
      async = new AsyncSpec(this);

  beforeEach( function() {
    store.saveItem(itemOne);
    store.saveItem(itemTwo);
  });

  afterEach( function() {
    store.empty();
  });

  async.it('should append new items to the end of the list', function(done) {
    store.getItems().then( function(items) {
      expect(items[items.length-1]).toBe(itemTwo);
      done();
    });
  });

  async.it('should update existing item at position', function(done) {
    itemOne.name = 'oranges';
    store.saveItem(itemOne).then( function(item) {
      store.getItems().then( function(items) {
        expect(items.indexOf(itemOne)).toEqual(0);
        done();
      });
    });
  });

});
</pre>
<p>I had begun to add these expectations for multiple items in the list to the <code>saveItem()</code> spec suite, but I saw a similar setup for them both that differed from the origin setup for the <code>saveItem()</code> suite. As such, I moved these expectations to their own spec suite and particular setup.</p>
<p>Without any new modification to <code>storage-service</code> implementation, run that and we are still green!<br />
<img src="http://custardbelly.com/blog/images/tdd_js/part_ix_16.png" alt="Passing with new expectations for saveItem()" /></p>
<p>Tagged <strong>0.1.14</strong>: <a href="https://github.com/bustardcelly/grocery-ls/tree/0.1.14" target="_blank">https://github.com/bustardcelly/grocery-ls/tree/0.1.14</a></p>
<h2>This Is All Great But We Still Haven&#8217;t Done Anything</h2>
<p>In other words, what this subsection header is trying to say, the <code>storage-service</code> &#8211; even after we hook up communication to it from <code>list-controller</code> events &#8211; will do <em>nothing</em> but keep a session-cache of items: <strong>there still is no persistence across sessions</strong>.</p>
<p>Seeing as this is the case, let&#8217;s start integrating communication with <code>localStorage</code> into our <code>storage-service</code>. I am not going to modify the tests in order to verify the utilization of <code>localStorage</code> in relation to the operations available on <code>storage-service</code> &#8211; I am simply going to modify the <code>storage-service</code> and posible change expectations. The reason being that I do not really care about whether the storage-service relies on <code>localStorage</code> or a remote resource to read and write items to storage; I am only concerned with communication to <code>storage-service</code> being supported. </p>
<p><small>In truth, if this were a real world application and had to support occasional connectivity, i&#8217;d have two service modules: local-storage-service and remove-storage-service. They would both support the same API and there would be a service layer facade that would manage the &#8216;live&#8217; instance and sync of both. That is a little too much for this series, so we&#8217;ll stick with a proxy to <code>localStorage</code> without modifying our tests to assume that the <code>storage-service</code> requires communication with it.</small></p>
<h3>storage-service modification</h3>
<p>To begin with, a <code>String</code> value is used as a key to read and write to an object held on <a href="https://developer.mozilla.org/en-US/docs/DOM/Storage" target="_blank">localStorage</a>. The API of <code>localStorage</code> is fairly simple and we&#8217;ll only be concerned with <code>getItem()</code> and <code>setItem()</code> to read and write to the store, respectively. We&#8217;ll use a key that we hope is unique to our application and won&#8217;t overwrite any object stored previously by another and use that key to access the stored grocery list items:</p>
<p><em>/script/service/storage-service.js</em></p>
<pre class="brush: jscript; first-line: 1; highlight: [1,4,5,6,7,8,9,10,11,12,13,14,33,34,35,36,37,38,39,40,41,42,43,44]; title: ;">
define(['jquery', 'script/model/grocery-ls-item'], function($, modelFactory) {

  var itemCache,
      groceryListKey = 'com.custardbelly.grocerylist',
      parseToCollection = function(json) {
        var i,
            length,
            list = (json &amp;&amp; typeof json === 'string') ? JSON.parse(json) : [];
        length = list.length;
        for(i = 0; i &lt; length; i++) {
          list[i] = $.extend(modelFactory.create(), list[i]);
        }
        return list;
      },
      store = {
        saveItem: function(item) {
          var deferred = $.Deferred();
          return deferred.resolve(item);
        },
        removeItem: function(item) {
          var deferred = $.Deferred(),
              itemIndex = itemCache.indexOf(item),
              removedItem;

          if(itemIndex &gt; -1) {
            itemCache.splice(itemIndex, 1);
            removedItem = item;
          }
          return deferred.resolve(removedItem);
        },
        getItems: function() {
          var deferred = $.Deferred();
          if(itemCache === undefined) {
             try {
              itemCache = parseToCollection(window.localStorage.getItem(groceryListKey));
              deferred.resolve(itemCache);
            }
            catch(e) {
              deferred.reject('Could not access items: ' + e.message);
            }
          }
          else {
            deferred.resolve(itemCache);
          }
          return deferred;
        },
        empty: function() {
          var deferred = $.Deferred();
          itemCache.length = 0;
          deferred.resolve(itemCache);
          return deferred;
        }
      };

  return store;

});
</pre>
<p>That will light up our tests in pretty <span style="color: red;">red</span>&#8230; but that was expected. Actually, if it didn&#8217;t make our tests fail horribly, I would have been worried.<br />
<img src="http://custardbelly.com/blog/images/tdd_js/part_ix_23.png" alt="Failing on sotrage modification." /></p>
<p>There are a couple things going on in this modification to <code>storage-service</code> that we should go over, however &#8211; the first being <code>parseToCollection()</code>:</p>
<p><em>/script/service/storage-service.js</em></p>
<pre class="brush: jscript; first-line: 5; title: ;">
parseToCollection = function(json) {
  var i,
      length,
      list = (json &amp;&amp; typeof json === 'string') ? JSON.parse(json) : [];

  length = list.length;
  for(i = 0; i &lt; length; i++) {
    list[i] = $.extend(modelFactory.create(), list[i]);
  }
  return list;
}
</pre>
<p>This method is invoked from <code>getItems()</code> and is provided the value of the object held in <code>localStorage</code> with the key <code>com.custardbelly.grocerylist</code>. We&#8217;ll be saving our data down in <a href="http://www.json.org/" target="_blank">JSON</a> format, and as such, <code>parseCollection()</code> is responsible for parsing that data back out; as well, if it is the first time accessing the data it will be coming in as undefined so a new list is created. What is particularly important in this parsing is how the objects on the list held in <code>localStorage</code> are converted to instances of our <code>grocery-ls-item</code> model: we create a new instance using the <code>modelFactory</code> and extend it with the object values from the item held on the list. The reason for this is because <code>grocery-ls-items</code> are decorated with getters and setters to allow for <code>property-change</code> events to be notified. In serializing down to JSON, this object structure is not perserved &#8211; it is just a <strong>POJSO</strong>.</p>
<p>The <code>parseToCollection()</code> method is invoked from <code>getItems()</code>:</p>
<p><em>/script/service/storage-service.js</em></p>
<pre class="brush: jscript; first-line: 31; title: ;">
getItems: function() {
  var deferred = $.Deferred();
  if(itemCache === undefined) {
    try {
      itemCache = parseToCollection(window.localStorage.getItem(groceryListKey));
      deferred.resolve(itemCache);
    }
    catch(e) {
      deferred.reject('Could not access items: ' + e.message);
    }
  }
  else {
    deferred.resolve(itemCache);
  }
  return deferred;
}
</pre>
<p>When <code>getItems()</code> is first invoked in a session, it will go about trying to access and parse the data held on <code>localStorage</code>; any subsequent invocations will immediately return the currently held reference to the store. In essence, during a session of creating and curating a <strong>Grocery List</strong>, we are working with live and current data so there is no need to keep accessing the list of grocery items from local storage every time &#8211; we&#8217;ll just return the live record.</p>
<p>Speaking of which, a lot of the failing tests I suspect are due to not actually not saving the list down to <code>localStorage</code>. Let&#8217;s just modify <code>storage-service</code> a little to do so and see where that gets us:</p>
<p><em>/script/service/storage-service.js</em></p>
<pre class="brush: jscript; first-line: 1; highlight: [15,16,17,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34]; title: ;">
define(['jquery', 'script/model/grocery-ls-item'], function($, modelFactory) {

  var itemCache,
      groceryListKey = 'com.custardbelly.grocerylist',
      parseToCollection = function(json) {
        var i,
            length,
            list = (json &amp;&amp; typeof json === 'string') ? JSON.parse(json) : [];

        length = list.length;
        for(i = 0; i &lt; length; i++) {
          list[i] = $.extend(modelFactory.create(), list[i]);
        }
        return list;
      },
      serialize = function(key, data) {
        window.localStorage.setItem(key, JSON.stringify(data));
      },
      store = {
        saveItem: function(item) {
          var deferred = $.Deferred();
          $.when(this.getItems()).then(function(cache) {
            var index = cache.indexOf(item);
            try {
              if(index === -1) {
                cache[cache.length] = item;
              }
              serialize(groceryListKey, cache);
              deferred.resolve(item);
            }
            catch(e) {
              deferred.reject('Could not save item: ' + e.message);
            }
          });
          return deferred;
        },
        removeItem: function(item) {
          // implementation removed to reduce noise
        },
        getItems: function() {
          // implementation removed to reduce noise
        },
        empty: function() {
          // implementation removed to reduce noise
        }
      };

  return store;

});
</pre>
<p><code>saveItem()</code> was modified to access the held list using <code>getItems()</code>, operate on that list as it had done previously and then try to serialize the list back to storage. Fairly simple. It&#8217;s important to note that we don&#8217;t access the <code>itemCache</code> directly in saveItem(), the reason being that we can&#8217;t ensure that <code>saveItem()</code> will only be called after a request to <code>getItems()</code>. As such, we need to be sure we&#8217;re always working with the same data and do so by requesting that cached list from <code>getItems()</code> within <code>saveItem()</code>.</p>
<p>That gets us closer to <span style="color: green;">green</span>, but we still have some work to do&#8230;<br />
<img src="http://custardbelly.com/blog/images/tdd_js/part_ix_24.png" alt="Closer to green for storage-service modifications." /></p>
<p>Let&#8217;s modify <code>removeItem()</code> and <code>empty()</code> to work with the cached list returned from <code>getItems()</code> just as the modification to <code>saveItems()</code> has:</p>
<p><em>/script/service/storage-service.js</em></p>
<pre class="brush: jscript; first-line: 36; title: ;">
removeItem: function(item) {
  var deferred = $.Deferred();
  $.when(this.getItems()).then(function(cache) {
    var itemIndex = cache.indexOf(item),
        removedItem;
    try {
      if(itemIndex &gt; -1) {
        cache.splice(itemIndex, 1);
        removedItem = item;
        serialize(groceryListKey, cache);
      }
      deferred.resolve(removedItem);
    }
    catch(e) {
      cache.splice(itemIndex, 0, removedItem);
      deferred.reject('Could not remove item: ' + e.message);
    }
  });
  return deferred;
}
</pre>
<p><em>/script/service/storage-service.js</em></p>
<pre class="brush: jscript; first-line: 72; title: ;">
empty: function() {
  var deferred = $.Deferred();
  $.when(this.getItems()).then(function(cache) {
    try {
      cache.length = 0;
      serialize(groceryListKey, cache);
      deferred.resolve(cache);
    }
    catch(e) {
      deferred.reject('Could not empty cache: ' + e.message);
    }
  });
  return deferred;
}
</pre>
<p>That oughta do. Basically doing the same as we had done with <code>saveItem()</code>: accessing the cached list through <code>getItems()</code>, then modifying that list and serializing back done to <code>localStorage</code>.</p>
<p>Run those tests again, and we are back to <span style="color: green">green</span>!<br />
<img src="http://custardbelly.com/blog/images/tdd_js/part_ix_25.png" alt="Passing storage-service tests after modification!" /></p>
<p>&#8230; at least for our <code>storage-service</code>. Let&#8217;s turn on all our tests again and see if our previous expectations are met:<br />
<img src="http://custardbelly.com/blog/images/tdd_js/part_ix_26.png" alt="Passing tests!" /></p>
<p>Whoopie!</p>
<p>Tagged <strong>0.1.15</strong>: <a href="https://github.com/bustardcelly/grocery-ls/tree/0.1.15" target="_blank">https://github.com/bustardcelly/grocery-ls/tree/0.1.15</a></p>
<p>We&#8217;re not done yet: we have still to hook up <code>list-controller</code> notification to <code>storage-service</code> operations. However, I want to end this article here on a good note <img src='http://darko.liquidweb.com/~custardb/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h2>Conclusion</h2>
<p>We have yet to reach our goal of incorporating session persistence within our <strong>Grocery List</strong> application &#8211; but that is not to say we have gotten nowhere. We implemented our <code>storage-service</code> layer for <code>localStorage</code> communication and modified the <code>list-controller</code> to notify of change events to its collection related to <code>grocery-ls-item</code> existence. Not to shabby. </p>
<p>I know we want to get a finished product out the door, but we&#8217;ll get there&#8230; just a few more things to tie up in the next article&#8230;</p>
<p>Cheers! </p>
<p>&#8212;-</p>
<h1>Link Dump</h1>
<h2>Reference</h2>
<p><a href="http://tddjs.com/" target="_blank">Test-Driven JavaScript Development by Christian Johansen</a><br />
<a href="http://dannorth.net/introducing-bdd/" target="_blank">Introducing BDD by Dan North</a><br />
<a href="http://cumulative-hypotheses.org/2011/08/30/tdd-as-if-you-meant-it/">TDD as if you Meant it by Keith Braithwaite</a><br />
<a href="http://requirejs.org/" target="_blank">RequireJS</a><br />
<a href="https://github.com/amdjs/amdjs-api/wiki/AMD" target="_blank">AMD</a><br />
<a href="http://pivotal.github.com/jasmine/" target="_blank">Jasmine</a><br />
<a href="http://sinonjs.org/" target="_blank">Sinon</a><br />
<a href="https://github.com/derickbailey/jasmine.async" target="_blank">Jasmine.Async</a></p>
<h2>Post Series</h2>
<p><a href="https://github.com/bustardcelly/grocery-ls">grocery-ls github repo</a><br />
<a href="http://custardbelly.com/blog/2012/11/26/the-making-of-a-test-driven-grocery-list-application-in-javascript-part-i" target="_blank">Part I &#8211; Introduction</a><br />
<a href="http://custardbelly.com/blog/2012/11/26/the-making-of-a-test-driven-grocery-list-application-in-js-part-ii">Part II &#8211; Feature: Add Item</a><br />
<a href="http://custardbelly.com/blog/2012/12/06/the-making-of-a-test-driven-grocery-list-application-in-js-part-iii">Part III &#8211; Feature: Mark-Off Item</a><br />
<a href="http://custardbelly.com/blog/2012/12/17/the-making-of-a-test-driven-grocery-list-application-in-js-part-iv">Part IV &#8211; Feature: List-Item-Controller</a><br />
<a href="http://custardbelly.com/blog/2012/12/31/the-making-of-a-test-driven-grocery-list-application-in-js-part-v/">Part V &#8211; Feature: List-Controller Refactoring</a><br />
<a href="http://custardbelly.com/blog/2013/01/08/the-making-of-a-test-driven-grocery-list-application-in-js-part-vi/" target="_blank">Part VI &#8211; Back to Passing</a><br />
<a href="http://custardbelly.com/blog/2013/01/17/the-making-of-a-test-driven-grocery-list-application-in-js-part-vii/">Part VII &#8211; Remove Item</a><br />
<a href="http://custardbelly.com/blog/2013/01/22/the-making-of-a-test-driven-grocery-list-application-part-viii/">Part VIII &#8211; Bug Fixing</a><br />
<a href="http://custardbelly.com/blog/2013/02/15/the-making-of-a-test-driven-grocery-list-application-in-js-part-ix/">Part IX &#8211; Persistence</a><br />
<a href="http://custardbelly.com/blog/2013/03/06/the-making-of-a-test-driven-grocery-list-application-in-js-part-x/">Part X &#8211; It Lives!</a></p>
]]></content:encoded>
			<wfw:commentRss>http://custardbelly.com/blog/2013/02/15/the-making-of-a-test-driven-grocery-list-application-in-js-part-ix/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>madmin: for ease of creating and documenting RESTful service URIs</title>
		<link>http://custardbelly.com/blog/2013/02/04/madmin-for-ease-of-creating-and-documenting-restful-service-uris/</link>
		<comments>http://custardbelly.com/blog/2013/02/04/madmin-for-ease-of-creating-and-documenting-restful-service-uris/#comments</comments>
		<pubDate>Mon, 04 Feb 2013 14:28:05 +0000</pubDate>
		<dc:creator>todd anderson</dc:creator>
				<category><![CDATA[Infrared5]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[madmin]]></category>
		<category><![CDATA[node]]></category>

		<guid isPermaLink="false">http://custardbelly.com/blog/?p=782</guid>
		<description><![CDATA[My company, Infrared5, recently released an Open Source project called madmin, which I had the great pleasure of being a main part of. 
madmin is a node-based application that allows for generating immediately accessible RESTful URIs. Though it is possible to communicate with command line tools like cURL,  madmin also provides a client-side console [...]]]></description>
			<content:encoded><![CDATA[<p>My company, <a href="http://infrared5.com" target="_blank">Infrared5</a>, recently released an Open Source project called <a href="https://github.com/infrared5/madmin">madmin</a>, which I had the great pleasure of being a main part of. </p>
<p><strong>madmin</strong> is a node-based application that allows for generating immediately accessible RESTful URIs. Though it is possible to communicate with command line tools like cURL,  <strong>madmin</strong> also provides a client-side console to easily create the URIs and structure of JSON response(s). It was originally intended to solve a front-end development problem in maintaining two sets of code &#8211; a <em>fake</em> service layer and <em>production-level</em> service layer &#8211; during development, but has grown to be a proven way to facilitate communication between the server-side and client-side teams in discussing the requirements of the services for a project. It also proved to be pretty handy documentation, to boot, which could be easily discussed with clients.</p>
<p>Anyway, you can read a more detailed description of the project and how it came to fruition over at the <a href="http://blog.infrared5.com" target="_blank">Infrared5 blog</a>: <a href="http://blog.infrared5.com/2013/01/introducing-madmin-an-admin-console-for-generating-mock-services-with-restful-uris/">http://blog.infrared5.com/2013/01/introducing-madmin-an-admin-console-for-generating-mock-services-with-restful-uris/</a></p>
<p>If you check it out, I hope you find it useful in any way and please log issues for requests or fork it to add features! I intend to get more basic instructions up on the wiki at its <a href="https://github.com/infrared5/madmin">github location</a> and perhaps write a few blog posts as well.</p>
]]></content:encoded>
			<wfw:commentRss>http://custardbelly.com/blog/2013/02/04/madmin-for-ease-of-creating-and-documenting-restful-service-uris/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Making of a Test-Driven Grocery List Application: Part VIII</title>
		<link>http://custardbelly.com/blog/2013/01/22/the-making-of-a-test-driven-grocery-list-application-part-viii/</link>
		<comments>http://custardbelly.com/blog/2013/01/22/the-making-of-a-test-driven-grocery-list-application-part-viii/#comments</comments>
		<pubDate>Tue, 22 Jan 2013 11:46:46 +0000</pubDate>
		<dc:creator>todd anderson</dc:creator>
				<category><![CDATA[AMD]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[RequireJS]]></category>
		<category><![CDATA[grocery-ls]]></category>
		<category><![CDATA[jasmine]]></category>
		<category><![CDATA[unit-testing]]></category>

		<guid isPermaLink="false">http://custardbelly.com/blog/?p=747</guid>
		<description><![CDATA[This is the eighth installment in a series of building a Test-Driven Grocery List application using Jasmine and RequireJS. To learn more about the intent and general concept of the series please visit The Making of a Test-Driven Grocery List Application in JavaScript: Part I
&#8212;
Introduction
In the past several articles we have sort of have been [...]]]></description>
			<content:encoded><![CDATA[<p><em>This is the eighth installment in a series of building a Test-Driven Grocery List application using <a href="http://pivotal.github.com/jasmine/" target="_blank">Jasmine</a> and <a href="http://requirejs.org" target="_blank">RequireJS</a>. To learn more about the intent and general concept of the series please visit <a href="http://custardbelly.com/blog/2012/11/26/the-making-of-a-test-driven-grocery-list-application-in-javascript-part-i/">The Making of a Test-Driven Grocery List Application in JavaScript: Part I</a></em><br />
&#8212;</p>
<h1>Introduction</h1>
<p>In the past several articles we have sort of have been living in the spec runner. We fiddled about making it turn red and green, and &#8211; until <a href="http://custardbelly.com/blog/2013/01/17/the-making-of-a-test-driven-grocery-list-application-in-js-part-vii/" target="_blank">the last article</a> &#8211; we never really ran the <strong>Grocery List</strong> application we were building to give it a proper <em>User Testing</em>. If you did play around with the actual application we have been busy writing tests for, you may have found a bug. An unexpected result from supplying no grocery item name before saving it to the list:</p>
<p><img src="http://custardbelly.com/blog/images/tdd_js/part_viii_1.png" alt="Image for bug ticket with empty item." /></p>
<p>As you can see from the screenshot, there is an empty item in the third entry of the list. While I do think the act of walking into a store and picking up nothing is an accomplishment at times, this <em>Empty Item</em> bug is not an intended feature. In this article, I want to squash that bug&#8230; but &#8211; in keep with the theme of this series &#8211; we are going to do it through tests! Calm down. It is hard to read when you jump up and down like that.</p>
<h1>Bug Ticket</h1>
<p>Before we begin fixing the bug, let&#8217;s get it down in writing what we think the problem is and how we think the intended behavior should be. To start, we don&#8217;t want empty items added to the <strong>Grocery List</strong>. We are currently able to add them &#8211; and rather easily &#8211; so let&#8217;s list out the steps that allows us to do so:</p>
<p><em>Empty Item Added to List</em><br />
&#8212;<br />
<strong>Steps to Reproduce</strong></p>
<ol>
<li>Launch the Grocery List application</li>
<li>Click &#8216;add item&#8217; button</li>
<li>In focused input field, type the name of a grocery item, ie. &#8216;apples&#8217; (sans quotes)</li>
<li>Click the Tab button to save to list</li>
<li>Click &#8216;add item&#8217; button</li>
<li>Leave the focused input field blank</li>
<li>Click the Tab button</li>
</ol>
<p><strong>Result</strong><br />
Empty item is added to the list</p>
<p><strong>Expected Result</strong><br />
An item without any name value provided is not added to the list</p>
<p><strong>Additional Notes</strong><br />
It is not a requirement to first have a valid item added to the list in order to reproduce the issue. Steps 1-4 are intended to show expected behavior with a non-empty item.<br />
&#8212;</p>
<p><small>If you are out there reading this and file bug tickets, please, for the love of software, log a ticket with a structure similar to this. Most modern bug tracking systems have fields like this, but you&#8217;d be surprised (or maybe not) how tickets come in sometimes. My least favorite is explained bug in the title. I can only imagine that they are the same people who write the whole email in the Subject field.</small></p>
<p>Alright, so now we know what we are dealing with. We have clear steps to reproduce the issue we think is a bug and have explained the difference between the actual result and the intended/expected result. Let&#8217;s tackle it.</p>
<h1>Tests</h1>
<p>As the developer of the application, we probably know exactly where this is happening. Our initial response is to go write to the source and resolve this issue. But we&#8217;re not going to do that. Don&#8217;t give me that look. I know, I know. The less we have to be in bug-fixing-mode, the happier developer we be, but I think if we have a test that supports the validity of this claim then, when we do make changes to the application code and it still passes, we know we have not committed a regression. I think it is a confidence builder in relying on my code to work properly and takes away some stress when refactoring comes into play.</p>
<p>Before we begin, let&#8217;s think about where we will add the tests. We could append another spec suite to the <em>Add Item</em> specs &#8211; after all, this bug occurs upon the completion of the <em>Add Item</em> feature. But in thinking about how to reproduce the issue, it seems like it may be another feature, or at least could be discovered in a feature we haven&#8217;t addressed &#8211; <em>Edit Item</em>. Essentially, when we get to the 3rd step &#8211; <em>In focused input field, type the name of a grocery item, ie. &#8216;apples&#8217; (sans quotes)</em> &#8211; we have already added the item to the list. It has entered an edit mode, from which we need to ensure the validity of the value provided before saving it to the list. </p>
<p>Now, a true <strong>TDD</strong>&#8216;er probably would stop me right now and tell me I am thinking too much to get this resolved. And, in part, they would be correct in doing so. But it is not my intent to start dreaming up new features during bug fixing. I just want to properly think about where the tests make the most sense. I don&#8217;t think they belong as an addendum to the <em>Add Item</em> specs and should live in there own spec suite in a separate file:</p>
<p><em>/test/jasmine/spec/feature/saveitem.spec.js</em></p>
<pre class="brush: jscript; first-line: 1; title: ;">
define(['jquery', 'script/controller/list-controller', 'script/controller/list-item-controller'],
        function($, listController, itemControllerFactory) {

  describe('Save item to grocery list', function() {

    it('should not save an empty item to the list') {
      expect(true).toEqual(false);
    }

  }
}
</pre>
<p>Given the steps provided in the bug ticket, we could easily translate that into the setup for the spec suite:</p>
<p><em>/test/jasmine/spec/feature/saveitem.spec.js</em></p>
<pre class="brush: jscript; first-line: 1; highlight: [6,7,8,9,10,11,12,13,14,15,21,22,23,24]; title: ;">
define(['jquery', 'script/controller/list-controller', 'script/controller/list-item-controller'],
        function($, listController, itemControllerFactory) {

  describe('Save item to grocery list', function() {

    var item,
        itemName = 'apples',
        invalidName = '',
        itemRenderer,
        async = new AsyncSpec(this);

    beforeEach( function() {
      item = listController.createNewItem();
      itemRenderer = listController.getRendererFromItem(item);
    });

    it('should not save an empty item to the list', function() {
      expect(true).toEqual(false);
    });

    afterEach( function() {
      item = undefined;
      itemRenderer = undefined;
    });
  });

});
</pre>
<p>In the <code>beforeEach()</code> setup, we have progressed the application &#8211; or at least a list item &#8211; to essentially the 3rd step in the <em>Steps to Reproduce</em>: we have added a new item to the list, and internally upon addition of an item in the <code>list-controller</code>, it has entered edit-mode for that item. In the variable declarations, we have also defined what we know of as being valid and invalid item entry names: <em>&#8216;apples&#8217;</em> and <em>&#8221;</em>, respectively. </p>
<p>We should be ready to go in our specs now to define the rest of the steps and expected results:</p>
<p><em>/test/jasmine/spec/feature/saveitem.spec.js</em></p>
<pre class="brush: jscript; first-line: 17; highlight: [18,20,22]; title: ;">
it('should not save an empty item to the list', function() {
  var listLength = listController.getItemList().itemLength();

  item.name = invalidName;
  // save item... ?
  expect(listController.getItemList().itemLength()).toEqual(listLength);
});
</pre>
<p>Oh, boy. How do we actually save an item? There is no API on the <code>list-controller</code> that saves an item. There used to be, but we refactored that out when we handed over item management to the <code>list-item-controller</code>. Furthermore, an item is added and kept on the list since its request for creation &#8211; the actual reason for the bug, I suppose. I am fine with such functionality internally to the <code>list-controller</code> as it stands now and don&#8217;t intend to change the item creation. I think an additional event should be dispatched from a <code>list-item-controller</code> signifying a request to commit the item to the list after being edited. Let&#8217;s finish up this spec under such assumptions, then work our way through the failing test:</p>
<p><em>/test/jasmine/spec/feature/saveitem.spec.js</em></p>
<pre class="brush: jscript; first-line: 17; title: ;">
async.it('should not save an empty item to the list', function(done) {
  var listLength = listController.getItemList().itemLength();

  $(itemRenderer).on('commit', function(event) {
    expect(listController.getItemList().itemLength()).toEqual(listLength-1);
    done();
  });

  item.name = invalidName;
  itemRenderer.save();
});
</pre>
<p>We marked the spec as asynchronous to support events from the <code>list-item-controller</code> and placed the expectation within the <em>&#8216;commit&#8217;</em> event handler.</p>
<p>Run that, and we&#8217;ll be waiting for about 5 seconds until we are told that save() is not a method on the <code>list-item-controller</code> instance:</p>
<p><img src="http://custardbelly.com/blog/images/tdd_js/part_viii_2.png" alt="Failing save item test with timeout" /></p>
<p><small>I have temporarily commented out the other tests in order to remove any noise and focus solely on resolving this bug. This is for local testing and would not commit the spec runner in such a state when committing back to the repo and running latest on a CI server.</small></p>
<p>To resolve that, let&#8217;s open up <code>list-item-controller</code> and add that method:</p>
<p><em>/script/controller/list-item-controller.js</em></p>
<pre class="brush: jscript; first-line: 71; highlight: [111,112]; title: ;">
listItemController = {
  $editableView: undefined,
  $uneditableView: undefined,
  init: function() {
    ...
    return this;
  },
  save: function() {
  },
  dispose: function() {
    ...
  }
};
</pre>
<p>Run that again, and now we are down to just the timeout failure:</p>
<p><img src="http://custardbelly.com/blog/images/tdd_js/part_viii_3.png" alt="Timeout failure on list-item-controller save" /></p>
<p>To resolve that, we&#8217;ll first create a new event factory method and invoke it from <code>save()</code> to dispatch the <em>commit</em> event, of which we have assigned a handler for in the test:</p>
<p><em>/script/controller/list-item-controller.js</em></p>
<pre class="brush: jscript; first-line: 16; title: ;">
function createSaveEvent(controller) {
  var event = $.Event('commit');
  event.controller = controller;
  return event;
}
</pre>
<p>and&#8230;</p>
<pre class="brush: jscript; first-line: 111; highlight: [112]; title: ;">
save: function() {
  $(this).trigger(createSaveEvent(this));
},
</pre>
<p>No more timeout!</p>
<p><img src="http://custardbelly.com/blog/images/tdd_js/part_viii_4.png" alt="Failing expectation on list-item-controller save." /></p>
<p>But still failing. Reason is that the item had not been removed from the collection. In previous tests we have verified its addition to the collection from the <code>createNewItem()</code> method on <code>list-controller</code>. Now that we are saving the <code>list-item-controller</code> with a modified model that has an invalid name, we are expecting such an action to remove the item from the collection &#8211; the crux of our <em>Empty Item</em> bug.</p>
<p>Let&#8217;s modify the <code>list-controller</code> in order to handle the commit event from a <code>list-item-controller</code>:</p>
<p><em>/script/controller/list-controller.js</em></p>
<pre class="brush: jscript; first-line: 40; highlight: [54,55,56,57,58,69]; title: ;">
$collection.on('collection-change', function(event) {
  var model, itemController, $itemView;
  switch( event.kind ) {
    case EventKindEnum.ADD:
      $itemView = $('&lt;li&gt;');
      model = event.items.shift();
      itemController = itemControllerFactory.create($itemView, model);

      $itemView.appendTo(listController.$view);
      rendererList.addItem(itemController);
      itemController.state = itemControllerFactory.state.EDITABLE;
      $(itemController).on('remove', function(event) {
        listController.removeItem(model);
      });
      $(itemController).on('commit', function(event) {
        if(!isValidValue(model.name)) {
          listController.removeItem(model);
        }
      });
      break;
    case EventKindEnum.REMOVE:
      model = event.items.shift();
      itemController = listController.getRendererFromItem(model);

      if(itemController) {
        $itemView = itemController.parentView;
        $itemView.remove();
        itemController.dispose();
        $(itemController).off('remove');
        $(itemController).off('commit');
        rendererList.removeItem(itemController);
      }
      break;
    case EventKindEnum.RESET:
      break;
  }
});
</pre>
<p>We&#8217;ve added another event listener to the <code>list-item-controller</code> when it is added to the collection to handle the <em>commit</em> event. Within the handler we check for its validity &#8211; which we have predetermined as not being an empty string &#8211; and if it does not pass, then we remove it.<br />
<small>Note: In shipped code I would hold a single reference to a wrapped non-jQuery object and not wrap it multiple times as is shown here when adding and removing event handlers. I left it in this example to not add extra noise to the task at hand.</small></p>
<p>Run that, and we are back to green!<br />
<img src="http://custardbelly.com/blog/images/tdd_js/part_viii_5.png" alt="Passing test on commit event form list-item-controller" /></p>
<h2>User Test</h2>
<p>Let&#8217;s run the application and see if the issue is resolved:<br />
<img src="http://custardbelly.com/blog/images/tdd_js/part_viii_6.png" alt="Non-resolution of bug in live test" /><br />
I think that picture says it all&#8230;</p>
<p>The bug is still there because <code>save()</code> is not being called on the <code>list-item-controller</code>. In our test, we explicitly called it after a change to the model, but in the application itself it is not being invoked upon change to the model. </p>
<p>But before we start adding calls to <code>save()</code> in our code, let&#8217;s think about the steps to reproduce the bug&#8230; or at least the fourth step &#8211; <em>Click the Tab button to save to list</em>. The tab keystroke, internally to the <code>list-item-controller</code>, causes a blur to the input field. If we look at the code from <code>list-item-controller</code>, that <em>blur</em> event performs a change to state:</p>
<p><em>/script/controller/list-item-controller.js</em></p>
<pre class="brush: jscript; first-line: 91; title: ;">
$('input', this.$editableView).on('blur', (function(controller) {
  return function(event) {
    controller.model.name = $(this).val();
    controller.state = stateEnum.UNEDITABLE;
  };
}(this)));
</pre>
<p>This snippet is taken from the event handler assignment in the <code>init()</code> function. When in edit mode of the <code>list-item-controller</code>, once focus is lost from the input field &#8211; which happens upon tab &#8211; the model is updated and state changed to non-edit mode. My first inkling is to put it here. It is true that, in doing so, it will pass and get rid of the bug&#8230; but the real commit of changes to the <code>list-item-controller</code> and its underlying model I feel lie in its change from edit mode to non-edit mode. I would argue that <code>save()</code> should be called from that occurrence. But before we add that to the code, let&#8217;s write up an expectation of that behavior.</p>
<h2>More Tests</h2>
<p><em>&#8216;WHAT?!? The bug was in our sights. We know how to get rid of it, and you want to write more tests?!?&#8217;</em><br />
That is the voice in my head most of the time when I decide to go back to tests. It has lessened, and the swearing really has decreased. And when I finally do get around to passing tests, it goes away and is replaced with: <em>&#8216;Nice job! You deserve a raise.. or at least an egg sandwich!&#8217;</em></p>
<p>Anyway, let&#8217;s get to <em>Egg Sandwich Status</em> and add another test to ensure that upon change to non-edit mode, if the model properties are not valid, that the item is not saved:</p>
<p><em>/test/jasmine/spec/feature/saveitem.spec.js</em></p>
<pre class="brush: jscript; first-line: 29; title: ;">
async.it('should not save an empty item upon change to non-edit mode', function(done) {
   var listLength = listController.getItemList().itemLength();

  $(itemRenderer).on('commit', function(event) {
    expect(listController.getItemList().itemLength()).toEqual(listLength - 1);
    done();
  });

  item.name = invalidName;
  itemRenderer.state = itemControllerFactory.state.UNEDITABLE;
});
</pre>
<p>We have already verified the expectation that a <code>list-item-controller</code> is entered into an <code>EDITABLE</code> state from our <em>additem.spec.js</em> tests, so we don&#8217;t need to test for that here &#8211; just know that setting the <code>list-item-controller</code> instance to an <code>UNEDITABLE</code> state will trigger it to go into non-edit mode.</p>
<p>Run that, and we get the timeout failure from that test:<br />
<img src="http://custardbelly.com/blog/images/tdd_js/part_viii_7.png" alt="Timeout failure on non-edit mode commit" /></p>
<p>Good! Before you slap me&#8230; save that hand for modifying the <code>list-item-controller</code> to invoke the save() method from its state-change handler:</p>
<p><em>/script/controller/list-item-controller.js</em></p>
<pre class="brush: jscript; highlight: [48]; title: ;">
function handleStateChange(controller, event) {
  // remove state-based item.
  if( typeof event.oldState !== 'undefined') {
    if(event.oldState === stateEnum.UNEDITABLE) {
      controller.$uneditableView.detach();
    }
    else if(event.oldState === stateEnum.EDITABLE) {
      controller.$editableView.detach();
    }
  }
  // append state-based item.
  if(event.newState === stateEnum.UNEDITABLE) {
    controller.parentView.append(controller.$uneditableView);
    controller.save();
  }
  else if(event.newState === stateEnum.EDITABLE) {
    var inputTimeout = setTimeout( function()  {
      clearTimeout(inputTimeout);
      $('input', controller.$editableView).focus();
    }, 100);
    controller.parentView.append(controller.$editableView);
  }
}
</pre>
<p>One little addition. Now run the tests:<br />
<img src="http://custardbelly.com/blog/images/tdd_js/part_viii_8.png" alt="Passing tests on change to non-edit mode and save." /></p>
<p><em>Hooray!</em> Now use that hand you were gonna slap me with and high-five yourself. Now look at yourself&#8230; you look silly. Run the application you crazy solo-high-fiver:<br />
<img src="http://custardbelly.com/blog/images/tdd_js/part_viii_9.png" alt="Application does not save empty item" /></p>
<p>That picture doesn&#8217;t say much, but &#8211; if all has gone well &#8211; it conveys that we are no longer able to save an item to the list when nothing has been provided in the input field and we can close the bug.</p>
<h3>Can&#8217;t Stop. Won&#8217;t Stop</h3>
<p>I would normally stop there, but I do like to sew things up nicely and verify all expectations. Such as:</p>
<p>1. Item controller view is not retained in list view if not valid:<br />
<em>/test/jasmine/spec/feature/saveitem.spec.js</em></p>
<pre class="brush: jscript; first-line: 43; title: ;">
async.it('should not add an empty item to list view upon change to non-edit mode', function(done) {
   var listViewLength = $listView.children().length;

  $(itemRenderer).on('commit', function(event) {
    expect($listView.children().length).toEqual(listViewLength - 1);
    done();
  });

  item.name = invalidName;
  itemRenderer.state = itemControllerFactory.state.UNEDITABLE;
});
</pre>
<p>2. When going from edit to non-edit mode, valid items are retained:<br />
<em>/test/jasmine/spec/feature/saveitem.spec.js</em></p>
<pre class="brush: jscript; first-line: 55; title: ;">
async.it('should save a valid item upon change to non-edit mode', function(done) {
   var listLength = listController.getItemList().itemLength();

  $(itemRenderer).on('commit', function(event) {
    expect(listController.getItemList().itemLength()).toEqual(listLength);
    done();
  });

  item.name = itemName;
  itemRenderer.state = itemControllerFactory.state.UNEDITABLE;
});

async.it('should add a valid item to list view upon change to non-edit mode', function(done) {
   var listViewLength = $listView.children.length;

  $(itemRenderer).on('commit', function(event) {
    expect($listView.children().length).toEqual(listViewLength);
    done();
  });

  item.name = itemName;
  itemRenderer.state = itemControllerFactory.state.UNEDITABLE;
});
</pre>
<p>Those additional specs will pass with flying colors and without having to modify any more application code:<br />
<img src="http://custardbelly.com/blog/images/tdd_js/part_viii_10.png" alt="Finishing up all expectations for Save Item feature" /></p>
<p>Tagged <strong>0.1.12</strong>: <a href="https://github.com/bustardcelly/grocery-ls/tree/0.1.12" target="_blank">https://github.com/bustardcelly/grocery-ls/tree/0.1.12</a></p>
<h1>Conclusion</h1>
<p>In this article we tested our way to closing a bug.</p>
<p>Just as we had done in the <a href="http://custardbelly.com/blog/2013/01/17/the-making-of-a-test-driven-grocery-list-application-in-js-part-vii/" target="_blank">previous article</a>, we adhered more closely to the principles of <strong>TDD</strong> and trudge along making things turn <span style="color: red;">red</span> before <span style="color: green;">green</span> &#8211; even when we found the reason and knew the resolution for the <em>Empty Item</em> bug. In doing so, we sort of verified and documented in test a <em>Save Item</em> feature. Now we know where to add or modify tests if the usability in committing an item to the list is changed in our requirements.</p>
<h2>Todd can&#8217;t leave well enough alone</h2>
<p>The application is pretty much ready to use as is to boot! There is just one more thing that is nagging me &#8211; persistence. No pun intended. We can create a list of all the items we need at the grocery store just fine, but if we close the browser window&#8230; oh-noes. It&#8217;s lost. I gotta fix that&#8230; next.</p>
<p>Cheers for sticking around!</p>
<p>&#8212;-</p>
<h1>Link Dump</h1>
<h2>Reference</h2>
<p><a href="http://tddjs.com/" target="_blank">Test-Driven JavaScript Development by Christian Johansen</a><br />
<a href="http://dannorth.net/introducing-bdd/" target="_blank">Introducing BDD by Dan North</a><br />
<a href="http://cumulative-hypotheses.org/2011/08/30/tdd-as-if-you-meant-it/">TDD as if you Meant it by Keith Braithwaite</a><br />
<a href="http://requirejs.org/" target="_blank">RequireJS</a><br />
<a href="https://github.com/amdjs/amdjs-api/wiki/AMD" target="_blank">AMD</a><br />
<a href="http://pivotal.github.com/jasmine/" target="_blank">Jasmine</a><br />
<a href="http://sinonjs.org/" target="_blank">Sinon</a><br />
<a href="https://github.com/derickbailey/jasmine.async" target="_blank">Jasmine.Async</a></p>
<h2>Post Series</h2>
<p><a href="https://github.com/bustardcelly/grocery-ls">grocery-ls github repo</a><br />
<a href="http://custardbelly.com/blog/2012/11/26/the-making-of-a-test-driven-grocery-list-application-in-javascript-part-i" target="_blank">Part I &#8211; Introduction</a><br />
<a href="http://custardbelly.com/blog/2012/11/26/the-making-of-a-test-driven-grocery-list-application-in-js-part-ii">Part II &#8211; Feature: Add Item</a><br />
<a href="http://custardbelly.com/blog/2012/12/06/the-making-of-a-test-driven-grocery-list-application-in-js-part-iii">Part III &#8211; Feature: Mark-Off Item</a><br />
<a href="http://custardbelly.com/blog/2012/12/17/the-making-of-a-test-driven-grocery-list-application-in-js-part-iv">Part IV &#8211; Feature: List-Item-Controller</a><br />
<a href="http://custardbelly.com/blog/2012/12/31/the-making-of-a-test-driven-grocery-list-application-in-js-part-v/">Part V &#8211; Feature: List-Controller Refactoring</a><br />
<a href="http://custardbelly.com/blog/2013/01/08/the-making-of-a-test-driven-grocery-list-application-in-js-part-vi/" target="_blank">Part VI &#8211; Back to Passing</a><br />
<a href="http://custardbelly.com/blog/2013/01/17/the-making-of-a-test-driven-grocery-list-application-in-js-part-vii/">Part VII &#8211; Remove Item</a><br />
<a href="http://custardbelly.com/blog/2013/01/22/the-making-of-a-test-driven-grocery-list-application-part-viii/">Part VIII &#8211; Bug Fixing</a><br />
<a href="http://custardbelly.com/blog/2013/02/15/the-making-of-a-test-driven-grocery-list-application-in-js-part-ix/">Part IX &#8211; Persistence</a><br />
<a href="http://custardbelly.com/blog/2013/03/06/the-making-of-a-test-driven-grocery-list-application-in-js-part-x/">Part X &#8211; It Lives!</a></p>
]]></content:encoded>
			<wfw:commentRss>http://custardbelly.com/blog/2013/01/22/the-making-of-a-test-driven-grocery-list-application-part-viii/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Making of a Test-Driven Grocery List Application in JS: Part VII</title>
		<link>http://custardbelly.com/blog/2013/01/17/the-making-of-a-test-driven-grocery-list-application-in-js-part-vii/</link>
		<comments>http://custardbelly.com/blog/2013/01/17/the-making-of-a-test-driven-grocery-list-application-in-js-part-vii/#comments</comments>
		<pubDate>Thu, 17 Jan 2013 11:58:58 +0000</pubDate>
		<dc:creator>todd anderson</dc:creator>
				<category><![CDATA[AMD]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[RequireJS]]></category>
		<category><![CDATA[grocery-ls]]></category>
		<category><![CDATA[jasmine]]></category>
		<category><![CDATA[unit-testing]]></category>

		<guid isPermaLink="false">http://custardbelly.com/blog/?p=742</guid>
		<description><![CDATA[This is the seventh installment in a series of building a Test-Driven Grocery List application using Jasmine and RequireJS. To learn more about the intent and general concept of the series please visit The Making of a Test-Driven Grocery List Application in JavaScript: Part I
&#8212;
Introduction
In the previous article we resolved tests for the Mark Off [...]]]></description>
			<content:encoded><![CDATA[<p><em>This is the seventh installment in a series of building a Test-Driven Grocery List application using <a href="http://pivotal.github.com/jasmine/" target="_blank">Jasmine</a> and <a href="http://requirejs.org" target="_blank">RequireJS</a>. To learn more about the intent and general concept of the series please visit <a href="http://custardbelly.com/blog/2012/11/26/the-making-of-a-test-driven-grocery-list-application-in-javascript-part-i/">The Making of a Test-Driven Grocery List Application in JavaScript: Part I</a></em><br />
&#8212;</p>
<h2>Introduction</h2>
<p>In the <a href="http://custardbelly.com/blog/2013/01/08/the-making-of-a-test-driven-grocery-list-application-in-js-part-vi/" target="_blank">previous article</a> we resolved tests for the <em>Mark Off Item</em> feature that were left in a failing state after refactoring the list-controller. The test are all green now and the application usable, but we are not done with implementing the required features. In this article I plan to address another &#8211; the <em>Remove Item</em> feature.</p>
<p>Before we begin, let&#8217;s drum up a quick story and scenario(s) for the <em>Remove Item</em> feature. I know the feature seems a little simple &#8211; just remove an item from the list &#8211; and going through and adding stories and scenarios may appear like adding complexity to the situation, but since I have begun to incorporate such a workflow, I feel like it actually gives me more time to think about not only the necessity of the feature but the design; in result, <em>hopefully*</em> cutting down on the complexity of the code.</p>
<p><em>// story</em><br />
<strong>Feature:</strong> remove item from grocery list</p>
<p><strong>In order to</strong> not buy an item previous on a grocery list<br />
<strong>As a</strong> grocery shopper<br />
<strong>I want to</strong> remove the existence of the item on the grocery list<br />
&#8212;</p>
<p>That may be worded rather harshly, but I shop angry. It&#8217;s how I keep the cantelope in check. <em>&#8216;I see you looking at me, you lousy melon.&#8217;</em> All kidding aside, I tend to be a little more terse in describing stories so as not to mince words (no pun intended) and leave as little vagueness as possible. Sometimes, I&#8217;ll admit, there is no avoiding having the story lead to a lot of assumptions &#8211; but that is where scenarios come in.</p>
<p><em>// spec</em><br />
<strong>Scenario 1:</strong> Item removed from grocery list<br />
<strong>Given</strong> an item has been added to the list<br />
<strong>When</strong> a user requests to remove the item<br />
<strong>Then</strong> the list decreases in size by one</p>
<p>Hmm. Pretty straight forward. Well, it all seems rather easy going to implement this feature. Looks like it might be a short blog post, for once; we&#8217;ll see how much rambling I can pack in. At least we have something to show somebody who doesn&#8217;t want/need to read code when they ask, <em>&#8216;But, what does it do?&#8217;</em>.</p>
<h2>Tests</h2>
<p>As always, before we get into adding code to the components of the application to implement the new feature, let&#8217;s get some failing tests to pass. We&#8217;ll start of with defining a new spec suite for the <em>Remove Item</em> feature, with the setup (<code>beforeEach()</code>) being the <strong>Given</strong> describe above:</p>
<p><em>/test/jasmine/spec/feature/removeitem.spec.js</em></p>
<pre class="brush: jscript; first-line: 1; title: ;">
define(['jquery', 'script/controller/list-controller'], function($, listController) {

  describe('Remove item', function() {

    var $listView = $('&lt;ul/&gt;'),
        groceryItem;

    beforeEach( function() {
      listController.setView($listView);
      groceryItem = listController.createNewItem();
    });

    it('should remove existing item from the collection', function() {
      expect(false).toEqual(true);
    });

    afterEach( function() {
      groceryItem = undefined;
    });

  });

});
</pre>
<p>Don&#8217;t mind the expectation declared in the spec. <a href="http://pivotal.github.com/jasmine/" target="_blank">Jasmine</a> does not check empty specs and automatically fail them. In fact, if we ran it without any expectations defined, it would be all green. So, I usually drop a failing expectation in quickly when creating new specs in cases where someone/thing comes and interrupts me, I know where to pick back up when i come back. It&#8217;s habit. Maybe a little paranoia. Don&#8217;t know if it&#8217;s right or wrong <img src='http://darko.liquidweb.com/~custardb/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
<small><br />
If you have been following along in the articles of this series, I typically do my implementation in the tests then move them to their respective modules. It&#8217;s a nice workflow for me, and in most cases I feel it gets me more focused on design. In this case, I am just going to declare my expectations, see them fail and move over to implementing the code right in the module, running the spec runner as we go until we see green.<br />
</small></p>
<p>Anyway, first on the agenda is to verify that the Remove API from <code>list-controller</code> is expected to remove the item from the underlying collection of grocery list items:</p>
<p><em>/test/jasmine/spec/feature/removeitem.spec.js</em></p>
<pre class="brush: jscript; highlight: [14,15,17,19,20]; title: ;">
it('should remove existing item from the collection', function() {
  var collection = listController.getItemList(),
      removedItem;

  removedItem = listController.removeItem(groceryItem);

  expect(removedItem).toBe(groceryItem);
  expect(collection.getItemIndex(groceryItem)).toBe(-1);
});
</pre>
<p>Add the new spec to the spec runner:<br />
<em>/test/jasmine/specrunner.html</em></p>
<pre class="brush: jscript; first-line: 34; highlight: [34]; title: ;">
require( ['spec/feature/additem.spec.js', 'spec/feature/markitem.spec.js', 'spec/feature/removeitem.spec.js',
          'spec/list-controller.spec.js', 'spec/list-item-controller.spec.js', 'spec/grocery-ls-item.spec.js',
          'spec/collection.spec.js'], function() {

  var jasmineEnv = jasmine.getEnv(),
      ...
  jasmineEnv.execute();

});
</pre>
<p>Run that, and we have a big honking failure:<br />
<img src="http://custardbelly.com/blog/images/tdd_js/part_vii_1.png" alt="Failing remove spec on collection." /><br />
Good!</p>
<p>In looking at the expectations of the <code>removeItem()</code> method on <code>list-controller</code>, we are expecting that the item is removed from the collection and returned on invocation. Let&#8217;s implement <code>removeItem</code> on <code>list-controller</code> with this understanding:</p>
<p><em>/script/controller/list-controller.js</em></p>
<pre class="brush: jscript; first-line: 6; highlight: [25,26,27]; title: ;">
listController = {
  $view: undefined,
  getItemList: function() {
    return collection;
  },
  getRendererFromItem: function(item) {
    var i = rendererList.itemLength();
    while( --i &gt; -1 ) {
      if(rendererList.getItemAt(i).model === item) {
        return rendererList.getItemAt(i);
      }
      return undefined;
    }
  },
  createNewItem: function() {
    var model = modelFactory.create();
    collection.addItem(model);
    return model;
  },
  removeItem: function(item) {
    return collection.removeItem(item);
  },
  setView: function(view) {
    this.$view = (view instanceof $) ? view : $(view);
  }
};
</pre>
<p>Run it, and we pass!<br />
<img src="http://custardbelly.com/blog/images/tdd_js/part_vii_2.png" alt="Passing tests on remove from collection." /><br />
Well, that was sort of easy and anti-climatic. No drama. A little boring, if I may say so.</p>
<p>But&#8230; there&#8217;s more! The <code>list-controller</code> isn&#8217;t just some dumb facade to the underlying <strong>Grocery List</strong> collection &#8211; it also manages the associated renderers to the <code>grocery-ls-item</code> models. Let&#8217;s get back to our tests and add a new spec:</p>
<p><em>/test/jasmine/spec/feature/removeitem.spec.js</em></p>
<pre class="brush: jscript; first-line: 23; title: ;">
it('should remove item renderer from view', function() {
  listController.removeItem(groceryItem);

  expect($listView.children().length).toEqual(0);
});
</pre>
<p>Just as we had done for the <em>Add Item</em> feature specification, we are inspecting the view reference held by list-controller that is updated based on change to the model. In this case, we are expecting that the list item renderer is removed upon <code>removeItem()</code> as well.</p>
<p>Run that, and failure!<br />
<img src="http://custardbelly.com/blog/images/tdd_js/part_vii_3.png" alt="Failure of test on removl of item views." /><br />
It might be important to note the actual print out from the failing expectation. It says that the length of children on the list view is 2 &#8211; that is because we now have 2 specs that are defining the expectations of <code>removeItem()</code> that are failing to remove the item view from the list.</p>
<p>Let&#8217;s switch over the list-controller and get this sorted and back to green. But before we do, let&#8217;s think about the relationship of the <code>list-controller</code> and its underlying collection. The <code>list-controller</code> responds to collection event for <code>EventKindEnum.ADD</code> in order to modify the view. So, we will respond to <code>EventKindEnum.REMOVE</code> accordingly to modify the view on removal of an item as well, instead of adding more logic to the <code>removeItem()</code> method on <code>list-controller</code>:</p>
<p><em>/script/controller/list-controller.js</em></p>
<pre class="brush: jscript; first-line: 40; highlight: [53,54,55,56,57,58,59,60]; title: ;">
$collection.on('collection-change', function(event) {
  var model, itemController, $itemView;
  switch( event.kind ) {
    case EventKindEnum.ADD:
      $itemView = $('&lt;li&gt;');
      model = event.items.shift();
      itemController = itemControllerFactory.create($itemView, model);

      $itemView.appendTo(listController.$view);
      rendererList.addItem(itemController);
      itemController.state = itemControllerFactory.state.EDITABLE;
      break;
    case EventKindEnum.REMOVE:
      model = event.items.shift();
      itemController = listController.getRendererFromItem(model);

      if(itemController) {
        $itemView = itemController.parentView;
        $itemView.remove();
        rendererList.removeItem(itemController);
      }
      break;
    case EventKindEnum.RESET:
      break;
  }
});
</pre>
<p>In the <code>EventKindEnum.REMOVE</code> case, we are grabbing the model provided on the event, using it to access the associated <code>list-item-controller</code> instance, and &#8211; if defined &#8211; removing the list item renderer view from the DOM and the controller from the renderer collection.</p>
<p>Run that, and we are back to green!<br />
<img src="http://custardbelly.com/blog/images/tdd_js/part_vii_4.png" alt="Passing tests on removal of item from view." /></p>
<p>Tagged <strong>0.1.10</strong>: <a href="https://github.com/bustardcelly/grocery-ls/tree/0.1.10" target="_blank">https://github.com/bustardcelly/grocery-ls/tree/0.1.10</a></p>
<h2>Back to Reality</h2>
<p>We&#8217;ve got test for the removal of a grocery list item working. We are currently feature complete. Let&#8217;s ship it! But hold up, does the <strong>Grocery List</strong> application &#8211; the thing we are actually building for someone like myself to Use in real life &#8211; actually use the new Remove API. We defined a business feature that was a requirement to have, and met that expectation, but we really didn&#8217;t address how an item is removed, or under what circumstances&#8230;</p>
<p>Without getting to crazy on discussing how to handle swipe gestures and implementing press-and-hold menu actions, let&#8217;s just start with saying that the <code>list-item-controller</code> will dispatch a new event &#8211; <code>remove</code>. How we decide on the usability of an item being deleted could easily be another whole discussion on User Experience. For now, we want to verify that when a <code>list-item-controller</code> dispatches a <code>remove</code> event, that it is handled properly.</p>
<h3>Tests</h3>
<p>We&#8217;ll start with the specs for the <code>list-controller</code>. We are not going to be adding any new specs to the <em>Remove Item</em> feature to accomplish the implementation of <code>list-item-controller</code> notifying of a <code>remove</code> event; it seems a little odd to me as well, but we have already established that the <em>Remove</em> API performs as expected. We need to verify that the <code>list-controller</code> uses that API in response to a <code>list-item-controller</code> &#8211; less of a feature and more of an integration point.</p>
<p><em>/test/jasmine/spec/list-controller.spec.js</em></p>
<pre class="brush: jscript; first-line: 0; title: ;">
describe('list-item-controller remove event response', function() {

  it('should invoke list-controller:removeItem()', function() {
    var newItem = listController.createNewItem(),
        itemRenderer = listController.getRendererFromItem(newItem);

    spyOn(listController, 'removeItem');
    $(itemRenderer).trigger('remove');
    expect(listController.removeItem).toHaveBeenCalledWith(newItem);
  });

});
</pre>
<p>In this spec, we set up a <a href="https://github.com/pivotal/jasmine/wiki/Spies" target="_blank">spy</a> to verify that the <code>removeItem()</code> method is invoked upon dispatch of <code>remove</code> from a <code>list-item-controller</code> instance.</p>
<p>Run that and we are back to red, with a message letting us know that <code>removeItem()</code> was never called.<br />
<img src="http://custardbelly.com/blog/images/tdd_js/part_vii_5.png" alt="Failing implementation of remove event." /><br />
Good. Let&#8217;s open up <code>list-controller</code> and implement a <code>remove</code> event response:</p>
<p>/script/controller/list-controller.js</p>
<pre class="brush: jscript; first-line: 40; highlight: [51,52,53,63]; title: ;">
$collection.on('collection-change', function(event) {
  var model, itemController, $itemView;
  switch( event.kind ) {
    case EventKindEnum.ADD:
      $itemView = $('&lt;li&gt;');
      model = event.items.shift();
      itemController = itemControllerFactory.create($itemView, model);

      $itemView.appendTo(listController.$view);
      rendererList.addItem(itemController);
      itemController.state = itemControllerFactory.state.EDITABLE;
      $(itemController).on('remove', function(event) {
        listController.removeItem(model);
      });
      break;
    case EventKindEnum.REMOVE:
      model = event.items.shift();
      itemController = listController.getRendererFromItem(model);

      if(itemController) {
        $itemView = itemController.parentView;
        $itemView.remove();
        itemController.dispose();
        $(itemController).off('remove');
        rendererList.removeItem(itemController);
      }
      break;
    case EventKindEnum.RESET:
      break;
  }
});
</pre>
<p>We added the remove handler delegation in the <code>ADD</code> case when the collection changes, along with the other implementation of item renderer establishment. And, for good measure and memory management, we are sure to remove the event handler in the <code>REMOVE</code> case from the collection change, as well.</p>
<p>Run the test now and we are back to green!<br />
<img src="http://custardbelly.com/blog/images/tdd_js/part_vii_6.png" alt="Passing remove event response." /></p>
<h3>list-item-controller Modification</h3>
<p>That&#8217;s great, but we are still glazing over the usability aspect: <em>How does a User delete an item?</em></p>
<p>Again, we could go into a lengthy discussion of UX and code implementations, but to save yourself from scrolling just to read me ramble off topic, we&#8217;ll keep it simple: <em>add a delete button</em>! I don&#8217;t know why I got excited there. I&#8217;ll show the implementation in piecemeal just to see how it all comes together. First we&#8217;ll start with the markup we declared for the <code>list-item-controller</code> views:</p>
<p><em>/script/controller/list-item-controller.js</em></p>
<pre class="brush: jscript; first-line: 56; highlight: [56,57,58,59]; title: ;">
uneditableItemFragment  = '&lt;p class=&quot;grocery-item&quot;&gt;' +
                                             '&lt;span class=&quot;grocery-item-label&quot; /&gt;' +
                                             '&lt;button class=&quot;delete-item-button&quot;&gt;delete&lt;/button&gt;' +
                                           '&lt;/p&gt;',
editableItemFragment    = '&lt;p class=&quot;editable-grocery-item&quot;&gt;' +
                                            '&lt;input name=&quot;editableItem&quot; ' +
                                              'class=&quot;editable-item&quot; placeholder=&quot;Enter item name...&quot;&gt;' +
                                            '&lt;/input&gt;' +
                                         '&lt;/p&gt;'
</pre>
<p>The <code>uneditableItemFragment</code> markup has changed slightly to support a label and a button. It was previously just a <code>p</code> element all by its lonesome, but with several references for modification and event <code>click</code> event handling. We&#8217;ll need to update those, as well as add another event handler for the <code>button</code> element:</p>
<p><em>/script/controller/list-item-controller.js</em></p>
<pre class="brush: jscript; first-line: 68; highlight: [73,74,75,76,77,78,79,80,81,82]; title: ;">
init: function() {
  this.$editableView = $(editableItemFragment);
  this.$uneditableView = $(uneditableItemFragment);

  // view handlers.
  $('span.grocery-item-label', this.$uneditableView).on('click', (function(controller) {
    return function(event) {
      var toggled = $(this).css('text-decoration') === 'line-through';
      controller.model.marked = !toggled;
    };
  }(this)));
  $('button.delete-item-button', this.$uneditableView).on('click', (function(controller) {
    return function(event) {
      $(controller).trigger(createRemoveEvent(controller));
    };
  }(this)));
  ...
}
</pre>
<p>As seen previously, we are using <a href="http://benalman.com/news/2010/11/immediately-invoked-function-expression/" target="_blank">IIFE</a>s here as a factory method in order to pass in a reference to the <code>list-item-controller</code> instance instead of declaring the old:</p>
<pre class="brush: jscript; title: ;">
var self = this;
</pre>
<p>and then passing <code>self</code> around which always makes me cringe. In any event (no pun intended), we have transferred the <em>click</em> handling previously assigned to the <code>p</code> element over the <code>span</code> element in order to support the usability of marking off an item. As well, we added handling of delete <code>button</code> <em>click</em> to trigger a new event:</p>
<p><em>/script/controller/list-item-controller.js</em></p>
<pre class="brush: jscript; first-line: 10; title: ;">
function createRemoveEvent(controller) {
  var event = $.Event('remove');
  event.controller = controller;
  return event;
}
</pre>
<p>Pretty straight forward in how we have create factory methods for our <a href="http://jquery.org" target="_blank">jQuery</a> events previously in this series. Next we need to modify the references that respond to model changes, such as the <code>marked</code> property value:</p>
<p><em>/script/controller/list-item-controller.js</em></p>
<pre class="brush: jscript; first-line: 16; highlight: [20,24,25]; title: ;">
function handlePropertyChange(controller, event) {
  if(event.property === &quot;name&quot;) {
    // update view based on model change.
    $('input', controller.$editableView).val(controller.model.name);
    $('span.grocery-item-label', controller.$uneditableView).text(event.newValue);
  }
  else if(event.property === &quot;marked&quot;) {
    // update view based on model change.
    $('span.grocery-item-label', controller.$uneditableView)
        .css('text-decoration', ( event.newValue ) ? 'line-through' : 'none');
  }
}
</pre>
<p>Alright. That should just about do it. Now you may be saying to yourself, <em>&#8216;Why haven&#8217;t we modified any tests in order to support this change in UI and event handling?&#8217;</em> To which I will respond, <em>&#8216;Stop bringing that up!&#8217;</em> In all seriousness, we perhaps should be writing tests to support these changes, however those will get pretty fine grained on the UI design aspect of the application. As you can see, it is constantly changing at this time and we are more concerned with the logical points of how the <strong>Grocery List</strong> application should behave. </p>
<p><small>Like with most of my code, future me may look back and shake his head at past me for such a statement &#8211; but for right now, present me will live with it</small> <img src='http://darko.liquidweb.com/~custardb/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h3>Using the Grocery List Application</h3>
<p>Let&#8217;s actually <em>run</em> the application and use it. We spend all this time making our tests turn red and green, we barely get to use what we are building.<br />
<img src="http://custardbelly.com/blog/images/tdd_js/part_vii_7.png" alt="Grocery list application" /></p>
<p>Oh my&#8230; that is ugly to look at. But it works! And it&#8217;s backed by tests!</p>
<p>Because I can&#8217;t leave well enough alone, I added some quick styling just to make it a little more pleasant on the eyes. I am not designer, so it might not be any more pleasant to you <img src='http://darko.liquidweb.com/~custardb/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  I won&#8217;t go into the styling of the application as that could be a whole &#8216;nother article and discussion of box model, but feel free to mess around with the styling on your own&#8230;<br />
<img src="http://custardbelly.com/blog/images/tdd_js/part_vii_8.png" alt="Prettier Grocery List application" /></p>
<p>Tagged <strong>0.1.11</strong>: <a href="https://github.com/bustardcelly/grocery-ls/tree/0.1.11" target="_blank">https://github.com/bustardcelly/grocery-ls/tree/0.1.11</a></p>
<h2>Conclusion</h2>
<p>In this article of the series, we took more of a traditional approach to <a href="http://en.wikipedia.org/wiki/Test-driven_development" target="_blank">TDD</a> and went along making things turn <span style="color: red;">red</span> before they turn <span style="color: green;">green</span>, one spec at a time, and all the while implementing the <em>Remove Item</em> feature. </p>
<p>The <strong>Grocery List</strong> application is also coming along pretty nicely and, as always, is easy and ready to use. But I can&#8217;t leave well enough alone and there are a few more items on my list (no pun intended) that I wish to address before ending this series, most importantly persistence. Our grocery list only last within the session of the page &#8211; once closed, our list is gone. We&#8217;ll get to that, but there might be some other things to address beforehand.</p>
<p>Cheers for sticking around!</p>
<p>&#8212;</p>
<h1>Link Dump</h1>
<h2>Reference</h2>
<p><a href="http://tddjs.com/" target="_blank">Test-Driven JavaScript Development by Christian Johansen</a><br />
<a href="http://dannorth.net/introducing-bdd/" target="_blank">Introducing BDD by Dan North</a><br />
<a href="http://requirejs.org/" target="_blank">RequireJS</a><br />
<a href="https://github.com/amdjs/amdjs-api/wiki/AMD" target="_blank">AMD</a><br />
<a href="http://pivotal.github.com/jasmine/" target="_blank">Jasmine</a><br />
<a href="http://sinonjs.org/" target="_blank">Sinon</a><br />
<a href="https://github.com/derickbailey/jasmine.async" target="_blank">Jasmine.Async</a></p>
<h2>Post Series</h2>
<p><a href="https://github.com/bustardcelly/grocery-ls">grocery-ls github repo</a><br />
<a href="http://custardbelly.com/blog/2012/11/26/the-making-of-a-test-driven-grocery-list-application-in-javascript-part-i" target="_blank">Part I &#8211; Introduction</a><br />
<a href="http://custardbelly.com/blog/2012/11/26/the-making-of-a-test-driven-grocery-list-application-in-js-part-ii">Part II &#8211; Feature: Add Item</a><br />
<a href="http://custardbelly.com/blog/2012/12/06/the-making-of-a-test-driven-grocery-list-application-in-js-part-iii">Part III &#8211; Feature: Mark-Off Item</a><br />
<a href="http://custardbelly.com/blog/2012/12/17/the-making-of-a-test-driven-grocery-list-application-in-js-part-iv">Part IV &#8211; Feature: List-Item-Controller</a><br />
<a href="http://custardbelly.com/blog/2012/12/31/the-making-of-a-test-driven-grocery-list-application-in-js-part-v/">Part V &#8211; Feature: List-Controller Refactoring</a><br />
<a href="http://custardbelly.com/blog/2013/01/08/the-making-of-a-test-driven-grocery-list-application-in-js-part-vi/" target="_blank">Part VI &#8211; Back to Passing</a><br />
<a href="http://custardbelly.com/blog/2013/01/17/the-making-of-a-test-driven-grocery-list-application-in-js-part-vii/">Part VII &#8211; Remove Item</a><br />
<a href="http://custardbelly.com/blog/2013/01/22/the-making-of-a-test-driven-grocery-list-application-part-viii/">Part VIII &#8211; Bug Fixing</a><br />
<a href="http://custardbelly.com/blog/2013/02/15/the-making-of-a-test-driven-grocery-list-application-in-js-part-ix/">Part IX &#8211; Persistence</a><br />
<a href="http://custardbelly.com/blog/2013/03/06/the-making-of-a-test-driven-grocery-list-application-in-js-part-x/">Part X &#8211; It Lives!</a></p>
]]></content:encoded>
			<wfw:commentRss>http://custardbelly.com/blog/2013/01/17/the-making-of-a-test-driven-grocery-list-application-in-js-part-vii/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Making of a Test-Driven Grocery List Application in JS: Part VI</title>
		<link>http://custardbelly.com/blog/2013/01/08/the-making-of-a-test-driven-grocery-list-application-in-js-part-vi/</link>
		<comments>http://custardbelly.com/blog/2013/01/08/the-making-of-a-test-driven-grocery-list-application-in-js-part-vi/#comments</comments>
		<pubDate>Tue, 08 Jan 2013 15:31:35 +0000</pubDate>
		<dc:creator>todd anderson</dc:creator>
				<category><![CDATA[AMD]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[RequireJS]]></category>
		<category><![CDATA[grocery-ls]]></category>
		<category><![CDATA[jasmine]]></category>
		<category><![CDATA[unit-testing]]></category>

		<guid isPermaLink="false">http://custardbelly.com/blog/?p=725</guid>
		<description><![CDATA[This is the sixth installment in a series of building a Test-Driven Grocery List application using Jasmine and RequireJS. To learn more about the intent and general concept of the series please visit The Making of a Test-Driven Grocery List Application in JavaScript: Part I
&#8212;
Introduction
We left the previous post with failing tests! 
I don&#8217;t necessarily [...]]]></description>
			<content:encoded><![CDATA[<p><em>This is the sixth installment in a series of building a Test-Driven Grocery List application using <a href="http://pivotal.github.com/jasmine/" target="_blank">Jasmine</a> and <a href="http://requirejs.org" target="_blank">RequireJS</a>. To learn more about the intent and general concept of the series please visit <a href="http://custardbelly.com/blog/2012/11/26/the-making-of-a-test-driven-grocery-list-application-in-javascript-part-i/">The Making of a Test-Driven Grocery List Application in JavaScript: Part I</a></em><br />
&#8212;</p>
<h2>Introduction</h2>
<p>We left the <a href="http://custardbelly.com/blog/2012/12/31/the-making-of-a-test-driven-grocery-list-application-in-js-part-v/" target="_blank">previous post</a> with <span style="color:#ff0000;">failing tests</span>! </p>
<p>I don&#8217;t necessarily condone leaving a master branch in such a state, so don&#8217;t give my name to your managers <img src='http://darko.liquidweb.com/~custardb/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  I, however, have no problem with leaving a feature or developer branch at the end of the day with failing tests &#8211; within reason. As long as the errors are from unimplemented behavior and the branch is not being monitored by some CI server feeding reports to your client(s), I see no problem. Sometimes I will write out the tests I plan to resolve the following day at 5:30 just so I can get a refresher the next morning as to the task at hand.</p>
<p>In the article I plan to get your tests all green again by modifying the <em>Mark Off Item</em> tests and possibly add a few new features.</p>
<h2>Mark Off Item Feature</h2>
<p>Way back in the <a href="http://custardbelly.com/blog/2012/12/06/the-making-of-a-test-driven-grocery-list-application-in-js-part-iii/" target="_blank">third article in this series</a>, we wrote up a story and some feature specs around the usability of marking off an item already existant in the list of item of the <strong>Grocery List</strong> application. In getting this feature implemented, we added a basic mark-item API to the <code>list-controller</code>, which allowed us to pass in a <code>grocery-ls-item</code> model to the <code>list-controller</code> which would then modify its state. </p>
<p>In the previous couple posts, we have refactored <code>list-controller</code> to not be responsible for item state and to respond to changes on a collection model &#8211; this is what led us to <span style="color: #ff0000;">failing tests</span>. We still want to keep the <em>Mark Off Item</em> feature, but instead of having specs that tested the mark-item API of the <code>list-controller</code>, we&#8217;re going to change the specs to verify that the <code>grocery-ls-item</code> model that is being modified updates its state and is retained in the collection held by the <code>list-controller</code>.</p>
<h3>Tests</h3>
<p>When I start creating the tests, I take some time in thinking about the <strong>Given</strong>s. Typically, the <strong>Given</strong>s are what make up the <code>beforeEach()</code> setup of a spec suite, but they can also lead to address some design concerns about components involved in getting the tests to pass. Such is the case in modifying our <em>Mark Off Item</em> feature specs.</p>
<p>We are not necessarily going to test the UI changes related to the action of marking off an item from the <strong>Grocery List</strong>. We could, but it is more important to me to test that the <code>grocery-ls-item</code> model that holds that state value of being marked is properly retaining that value and accessible from not only the collection, but from the associated <code>list-item-controller</code> instance, as well &#8211; after all, it is the <code>list-item-controller</code> that is responsible for responding to changes to an item being marked-off; i want to ensure that, in the very least, it has the opportunity, not actually what it does with the opportunity. </p>
<p><small>That statement may sound foolish, i&#8217;ll admit. If it was an expectation that the action of marking off an item was to trigger a reaction that defined another feature specification, then certainly I would write up tests accordingly. But as it stands, it changes a style on the <code>list-item-controller</code> view. I am not so concerned with that implementation at the moment &#8211; if it becomes a real business issue and it was a requirement to have the text shown with a strike-through, then yes.</small></p>
<p>Let&#8217;s start with the setup and teardown for the <em>Mark Off Item</em> feature specs:</p>
<p><em>/test/jasmine/spec/feature/markitem.spec.js</em></p>
<pre class="brush: jscript; first-line: 1; title: ;">
define(['jquery', 'script/controller/list-controller', 'script/controller/list-item-controller'],
        function($, listController, itemControllerFactory) {

  describe('Existing item is marked-off', function() {

    var item,
        itemController,
        getRendererStub;

    beforeEach( function() {
      item = listController.createNewItem();

      itemController = itemControllerFactory.create($('&lt;li/&gt;'), item);
      getRendererStub = sinon.stub();
      getRendererStub.returns(itemController);
      listController.getRendererFromItem = getRendererStub;
    });

    afterEach( function() {
      item = undefined;
      itemController = undefined;
      getRendererStub = undefined;
    });

  });

});
</pre>
<p>In the <code>beforeEach()</code>, we&#8217;ve stubbed out a new method on <code>list-controller</code> that allows us to access the associated <code>list-item-controller</code> with a model: <code>getRendererFromItem()</code>.</p>
<p>If you remember <a href="http://custardbelly.com/blog/2012/12/31/the-making-of-a-test-driven-grocery-list-application-in-js-part-v/" target="_blank">from the last article</a>, we also did some stubbing of methods before moving to implementation on <code>list-controller</code>. We are doing the same here and using the <a href="http://sinonjs.org" target="_blank">SinonJS</a> <code>stub</code> API to stub a method that currently does not exist on <code>list-controller</code>. To do so, and not have exceptions thrown in your tests regarding the existence of the method on the object being stubbed, you create an anonymous stub and assign it to the target object:</p>
<p><em>/test/jasmine/spec/feature/markitem.spec.js</em></p>
<pre class="brush: jscript; first-line: 14; title: ;">
getRendererStub = sinon.stub();
getRendererStub.returns(itemController);
listController.getRendererFromItem = getRendererStub;
</pre>
<p>The stub is sort of a fub, seeing as it is not really accessing the <code>list-item-controller</code> created by the <code>list-controller</code> in response to change on the collection &#8211; but it does provide some basis of design in that <code>getRendererFromItem()</code> is expected to return a <code>list-item-controller</code> which in turn responds to the provided model. Anyway, once we remove the stub and implement the API on the <code>list-controller</code> itself, we&#8217;ll certainly have to write more tests for that integration as we are not necessarily concerned in this specification of <code>getRendererFromItem()</code> returning the correct <code>list-item-controller</code> instance&#8230; so you have that to look forward to <img src='http://darko.liquidweb.com/~custardb/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Right now, we only care about the preservation of state and model existence within the application.</p>
<p>First we&#8217;ll test that setting an item as marked is preserved in the model and held on the item controller:<br />
<em>/test/jasmine/spec/feature/markitem.spec.js</em></p>
<pre class="brush: jscript; first-line: 19; title: ;">
it('should denote item as being in possession', function() {
  var itemRenderer = listController.getRendererFromItem(item);
      savedItemSpy = sinon.spy();

  savedItemSpy(itemRenderer.model);
  item.marked = true;

  expect(item.marked).toEqual(true);
  sinon.assert.calledWith(savedItemSpy, sinon.match.hasOwn('marked', true));
});
</pre>
<p>Then, I want to ensure that marking off an item does not mean that it is removed from the overall collection:<br />
<em>/test/jasmine/spec/feature/markitem.spec.js</em></p>
<pre class="brush: jscript; first-line: 31; title: ;">
it('should retain the item in the grocery list collection', function() {
  var itemIndex = listController.getItemList().getItemIndex(item);

  item.marked = true;
  expect(listController.getItemList().getItemIndex(item)).toEqual(itemIndex);
});
</pre>
<p>And finally, just to be sure that we can safely toggle the marked off state and it be retained:<br />
<em>/test/jasmine/spec/feature/markitem.spec.js</em></p>
<pre class="brush: jscript; first-line: 39; title: ;">
it('should retain item in renderer listing regardless of marked-off status', function() {
  var itemRenderer = listController.getRendererFromItem(item),
      itemIndex = listController.getItemList().getItemIndex(item);

  item.marked = true;
  item.marked = false;

  expect(itemRenderer.model.marked).toEqual(false);
  expect(listController.getItemList().getItemIndex(item)).toEqual(itemIndex);
});
</pre>
<p>Perhaps the last one is out of a little paranoia, but it also describes the behavior of the <em>Mark Off Item</em> feature as being togglable from a User standpoint &#8211; meaning, marking off an item is not considered deleting it from the list. Also, a little paranoia sprinkled on some tests can save you from fret when working with the implementation code. </p>
<p>Speaking of implementation&#8230;</p>
<h3>list-controller Implementation</h3>
<p>Moving the <code>getRendererFromItem()</code> method over to the <code>list-controller</code> will involve holding and maintaining a list of <code>list-item-renderers</code>. We&#8217;ll use the <em>Collection</em> object we created previously for the models and place the job of curation between both collections on the <code>list-controller</code>:</p>
<p><em>/script/controller/list-controller</em></p>
<pre class="brush: jscript; first-line: 4; highlight: [5,11,12,13,14,15,16,17,18,19]; title: ;">
var collection = collectionFactory.create(),
    rendererList = collectionFactory.create(),
    listController = {
      $view: undefined,
      getItemList: function() {
        return collection;
      },
      getRendererFromItem: function(item) {
        var i = rendererList.itemLength();
        while( --i &gt; -1 ) {
          if(rendererList.getItemAt(i).model === item) {
            return rendererList.getItemAt(i);
          }
          return undefined;
        }
      },
      createNewItem: function() {
        var model = modelFactory.create();
        collection.addItem(model);
        return model;
      },
      setView: function(view) {
        this.$view = (view instanceof $) ? view : $(view);
      }
    };
</pre>
<p>If an associated <code>list-item-controller</code> cannot be found from the provided <code>grocery-ls-item</code> model, then undefined is returned. We will ensure this and other expectations in a new integration test for the <code>list-controller</code> in a bit, but for now we have a little more work to do in order for the list-controller to behave as described in the <em>Mark Off Item</em> feature specs.</p>
<p>Next step is to have the tests fail by removing the stub for the <code>getRendererFromItem()</code> method now on the <code>list-controller</code>:<br />
<em>/test/jasmine/spec/feature/markitem.spec.js</em></p>
<pre class="brush: jscript; first-line: 1; title: ;">
define(['jquery', 'script/controller/list-controller'],
        function($, listController) {

  describe('Existing item is marked-off', function() {

    var item;

    beforeEach( function() {
      item = listController.createNewItem();
    });

    it('should denote item as being in possession', function() {
      var itemRenderer = listController.getRendererFromItem(item);
          savedItemSpy = sinon.spy();

      savedItemSpy(itemRenderer.model);
      item.marked = true;

      expect(item.marked).toEqual(true);
      sinon.assert.calledWith(savedItemSpy, sinon.match.hasOwn('marked', true));
    });

    it('should retain the item in the grocery list collection', function() {
      var itemIndex = listController.getItemList().getItemIndex(item);

      item.marked = true;
      expect(listController.getItemList().getItemIndex(item)).toEqual(itemIndex);
    });

    it('should retain item in renderer listing regardless of marked-off status', function() {
      var itemRenderer = listController.getRendererFromItem(item),
          itemIndex = listController.getItemList().getItemIndex(item);

      item.marked = true;
      item.marked = false;
      expect(itemRenderer.model.marked).toEqual(false);
      expect(listController.getItemList().getItemIndex(item)).toEqual(itemIndex);
    });

    afterEach( function() {
      item = undefined;
    });

  });

});
</pre>
<p>Run the tests, and we&#8217;ll get failures related to the <code>getRendererFromItem()</code> method returning undefined with each call:<br />
<img src="http://custardbelly.com/blog/images/tdd_js/part_vi_1.png" alt="Failing tests on getRendererFromItem invocation" /></p>
<p>Good. That sort of assures us that <code>getRendererFromItem()</code> works as expected. This little mid-implementation failure won&#8217;t save us from writing proper tests for <code>list-controller</code>, but it&#8217;s a warm feeling for now <img src='http://darko.liquidweb.com/~custardb/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>The reason that <code>getRendererForItem()</code> is returning undefined on each call is that we have not modified <code>list-controller</code> to add the <code>list-item-controller</code> renderer to the underlying <code>rendererList</code> collection. Let&#8217;s add the maintenance to the <em>collection-change</em> response on the model collection:</p>
<p><em>/script/controller/list-controller</em></p>
<pre class="brush: jscript; first-line: 37; highlight: [38,42,43,46]; title: ;">
$collection.on('collection-change', function(event) {
  var model, itemController, $itemView;
  switch( event.kind ) {
    case EventKindEnum.ADD:
      $itemView = $('&lt;li&gt;');
      model = event.items.shift();
      itemController = itemControllerFactory.create($itemView, model);

      $itemView.appendTo(listController.$view);
      rendererList.addItem(itemController);
      itemController.state = itemControllerFactory.state.EDITABLE;
      break;
    case EventKindEnum.REMOVE:
      break;
    case EventKindEnum.RESET:
      break;
  }
});
</pre>
<p>We&#8217;ve moved the variable declarations out of the <em>switch..case</em> for the <code>ADD</code> event type; they are hoisted by the interpreter, anyway, but I like a little more clarity. More importantly, we are adding the newly created <code>list-item-controller</code> to he <code>renderList</code>.</p>
<p>Run the tests and we&#8217;ll be back to green!<br />
<img src="http://custardbelly.com/blog/images/tdd_js/part_vi_2.png" alt="Passing tests on getRendererFromItem implementation" /></p>
<p>Hold on! Before you run out the door and down the street singing my praises&#8230; you need pants. I don&#8217;t know why you are reading this article without pants, but you probably will get a fine. Plus, we really need to add some tests for the <code>list-controller</code>.</p>
<h2>list-controller Tests</h2>
<p>The <em>Mark Off Item</em> specs we just got to pass are great in describing that feature and the usability, but they don&#8217;t necessarily test all the expectations we have of the <code>list-controller</code> and its API. Perhaps we should have wrote up the tests for <code>list-controller</code> and, specifically, the <code>getRendererFromItem()</code> method prior to modifying the <em>Mark Off Item</em> specs and getting them to pass. I would agree with that, but I am also not a stickler&#8230; as long as we get some integration tests in for <code>list-controller</code>, I won&#8217;t hold it against myself <img src='http://darko.liquidweb.com/~custardb/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>There are more tests regarding the <code>list-controller</code> API in the repository tagged later in this article, but for now I wanted to create a new spec suite for <code>list-controller</code> and test the expectations we had previously described for the <code>getRendererFromItem()</code> method:</p>
<p><em>/test/jasmine/spec/list-controller.spec.js</em></p>
<pre class="brush: jscript; first-line: 1; title: ;">
define(['jquery', 'script/controller/list-controller', 'script/model/grocery-ls-item'],
        function($, listController, modelFactory) {

  describe('Grocery List list-controller', function() {

    describe('getRendererItem()', function() {

      it('should return renderer associated with model', function() {
        var itemModel, renderer;

        itemModel = listController.createNewItem();
        renderer = listController.getRendererFromItem(itemModel);
        expect(renderer).not.toBeUndefined();
        expect(renderer.model).toBe(itemModel);
      });

      it('should return undefined with no associated model', function() {
        var itemModel, renderer;

        itemModel = modelFactory.create();
        renderer = listController.getRendererFromItem(itemModel);
        expect(renderer).toBeUndefined();
      });

    });

  });

});
</pre>
<p>We have defined two tests for the <code>getRendererFromItem()</code> method on <code>list-controller</code> to ensure that it <strong>1)</strong> does return the associated renderer when available and <strong>2)</strong> does return undefined when an associated renderer is not available.</p>
<p>Let&#8217;s add that to the specrunner:<br />
<em>/test/jasmine/specrunner.html</em></p>
<pre class="brush: jscript; first-line: 34; highlight: [35]; title: ;">
require( ['spec/feature/additem.spec.js', 'spec/feature/markitem.spec.js',
          'spec/list-controller.spec.js', 'spec/list-item-controller.spec.js', 'spec/grocery-ls-item.spec.js',
          'spec/collection.spec.js'], function() {

  var jasmineEnv = jasmine.getEnv(),
      ...
  jasmineEnv.execute();

});
</pre>
<h4>aside</h4>
<p>You may be wondering why it seems like I am doubling up on tests; after all, we have verified that the <code>getRendererFromItem()</code> method does as expected from within the <em>Mark Off Item</em> specs. This is true. However, I think of this spec suite, <em>list-controller.spec.js</em>, as more unit tests in that we are verifying how the component behaves. Within the <em>Mark Off Item</em> specs, I feel it is closer to how the component behaves in the system and reveals more of an expectation of the features of the <strong>Grocery List</strong> application. If I was to do further work in modifying the <code>list-controller</code>, I would start with this spec, and if it impacted the <em>Mark Off Item</em> feature, get that passing afterward. Not stuck in my way of thinking on this, but it my current workflow. Let me know if you have any better strategies.</p>
<p>Actually, that brings up a good point. We should revisit the <em>Add Item</em> specs and add a test to ensure that the newly created item returned from <code>createNewItem()</code> will return an associated list-item-controller instance from <code>getRendererFromItem()</code>&#8230;</p>
<h2>Add Item Feature Update</h2>
<p>We&#8217;ll add a spec to the current suite that verifies that the new created <code>grocery-ls-item</code> is properly paired with the <code>list-item-controller</code> and that they associated view is the one made available on the <strong>Grocery List</strong> UI:</p>
<p><em>/test/jasmine/spec/feature/additem.spec.js</em></p>
<pre class="brush: jscript; first-line: 33; title: ;">
it('should enable associated item renderer as editable', function() {
  var newItem = listController.createNewItem(),
      itemRenderer = listController.getRendererFromItem(newItem);

    expect(itemRenderer).not.toBeUndefined();
    expect(itemRenderer.model).toBe(newItem);
    expect(itemRenderer.state).toEqual(itemControllerFactory.state.EDITABLE);
    expect($listView.children()[0]).toBe(itemRenderer.parentView.get(0));
});
</pre>
<p>The last expectation in there utilizes some of the access API from <a href="jquery.org" target="_blank">jQuery</a>. If you are unfamiliar with it, it is basically testing that the first item in the parent list view is that of the <code>parentView</code> managed by the associated <code>list-item-controller</code>. If you take a look at the <a href="https://github.com/bustardcelly/grocery-ls/blob/0.1.8/test/jasmine/spec/feature/newitem.spec.js" target="_blank">previous spec</a>, we had already verified that the child list of the list view had been changed to include a new item; now we are ensuring that the new item is the correct one, accessible from <code>getRendererFromItem()</code>.</p>
<p>I think that pretty much shores up the proper testing in describing the <em>Add Item</em> and <em>Mark Off Item</em> features. Run the tests and all are green!<br />
<img src="http://custardbelly.com/blog/images/tdd_js/part_vi_3.png" alt="Passing tests for Add Item and Mark Off Item Features" /></p>
<p>Tagged <strong>0.1.9</strong> : <a href="https://github.com/bustardcelly/grocery-ls/tree/0.1.9" target="_blank">https://github.com/bustardcelly/grocery-ls/tree/0.1.9</a></p>
<h2>Conclusion</h2>
<p>We got the <em>Mark Off Item</em> specs running green again after we had left the application in a failing state from the <a href="http://custardbelly.com/blog/2012/12/31/the-making-of-a-test-driven-grocery-list-application-in-js-part-v/" target="_blank">last article</a>. Hooray! But, we are still only addressing half of the usability features I envision for the <strong>Grocery List</strong> application. Sometimes it is easy to forget that we are still building an application. If you ran it, you would see that it still works as expected, which I think is rather cool; I mean, we have been busying ourselves ensuring that our code will support our understanding of the system, and at the end of the day, it actually does. We have been running the test runner much more than the actual application. That is not to say that we shouldn&#8217;t be doing more User testing&#8230;</p>
<p>Anyway, in the next article I think we should address a new feature &#8211; Removal. Cheers for sticking around!</p>
<p>&#8212;</p>
<h1>Link Dump</h1>
<h2>Reference</h2>
<p><a href="http://tddjs.com/" target="_blank">Test-Driven JavaScript Development by Christian Johansen</a><br />
<a href="http://dannorth.net/introducing-bdd/" target="_blank">Introducing BDD by Dan North</a><br />
<a href="http://requirejs.org/" target="_blank">RequireJS</a><br />
<a href="https://github.com/amdjs/amdjs-api/wiki/AMD" target="_blank">AMD</a><br />
<a href="http://pivotal.github.com/jasmine/" target="_blank">Jasmine</a><br />
<a href="http://sinonjs.org/" target="_blank">Sinon</a><br />
<a href="https://github.com/derickbailey/jasmine.async" target="_blank">Jasmine.Async</a></p>
<h2>Post Series</h2>
<p><a href="https://github.com/bustardcelly/grocery-ls">grocery-ls github repo</a><br />
<a href="http://custardbelly.com/blog/2012/11/26/the-making-of-a-test-driven-grocery-list-application-in-javascript-part-i" target="_blank">Part I &#8211; Introduction</a><br />
<a href="http://custardbelly.com/blog/2012/11/26/the-making-of-a-test-driven-grocery-list-application-in-js-part-ii">Part II &#8211; Feature: Add Item</a><br />
<a href="http://custardbelly.com/blog/2012/12/06/the-making-of-a-test-driven-grocery-list-application-in-js-part-iii">Part III &#8211; Feature: Mark-Off Item</a><br />
<a href="http://custardbelly.com/blog/2012/12/17/the-making-of-a-test-driven-grocery-list-application-in-js-part-iv">Part IV &#8211; Feature: List-Item-Controller</a><br />
<a href="http://custardbelly.com/blog/2012/12/31/the-making-of-a-test-driven-grocery-list-application-in-js-part-v/">Part V &#8211; Feature: List-Controller Refactoring</a><br />
<a href="http://custardbelly.com/blog/2013/01/08/the-making-of-a-test-driven-grocery-list-application-in-js-part-vi/" target="_blank">Part VI &#8211; Back to Passing</a><br />
<a href="http://custardbelly.com/blog/2013/01/17/the-making-of-a-test-driven-grocery-list-application-in-js-part-vii/">Part VII &#8211; Remove Item</a><br />
<a href="http://custardbelly.com/blog/2013/01/22/the-making-of-a-test-driven-grocery-list-application-part-viii/">Part VIII &#8211; Bug Fixing</a><br />
<a href="http://custardbelly.com/blog/2013/02/15/the-making-of-a-test-driven-grocery-list-application-in-js-part-ix/">Part IX &#8211; Persistence</a><br />
<a href="http://custardbelly.com/blog/2013/03/06/the-making-of-a-test-driven-grocery-list-application-in-js-part-x/">Part X &#8211; It Lives!</a></p>
]]></content:encoded>
			<wfw:commentRss>http://custardbelly.com/blog/2013/01/08/the-making-of-a-test-driven-grocery-list-application-in-js-part-vi/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Making of a Test-Driven Grocery List Application in JS: Part V</title>
		<link>http://custardbelly.com/blog/2012/12/31/the-making-of-a-test-driven-grocery-list-application-in-js-part-v/</link>
		<comments>http://custardbelly.com/blog/2012/12/31/the-making-of-a-test-driven-grocery-list-application-in-js-part-v/#comments</comments>
		<pubDate>Mon, 31 Dec 2012 20:13:40 +0000</pubDate>
		<dc:creator>todd anderson</dc:creator>
				<category><![CDATA[AMD]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[RequireJS]]></category>
		<category><![CDATA[grocery-ls]]></category>
		<category><![CDATA[jasmine]]></category>
		<category><![CDATA[unit-testing]]></category>

		<guid isPermaLink="false">http://custardbelly.com/blog/?p=686</guid>
		<description><![CDATA[This is the fifth installment in a series of building a Test-Driven Grocery List application using Jasmine and RequireJS. To learn more about the intent and general concept of the series please visit The Making of a Test-Driven Grocery List Application in JavaScript: Part I
&#8212;
Introduction
The previous article was prefaced to be a refactoring effort to [...]]]></description>
			<content:encoded><![CDATA[<p><em>This is the fifth installment in a series of building a Test-Driven Grocery List application using <a href="http://pivotal.github.com/jasmine/" target="_blank">Jasmine</a> and <a href="http://requirejs.org" target="_blank">RequireJS</a>. To learn more about the intent and general concept of the series please visit <a href="http://custardbelly.com/blog/2012/11/26/the-making-of-a-test-driven-grocery-list-application-in-javascript-part-i/">The Making of a Test-Driven Grocery List Application in JavaScript: Part I</a></em><br />
&#8212;</p>
<h2>Introduction</h2>
<p>The <a href="http://custardbelly.com/blog/2012/12/17/the-making-of-a-test-driven-grocery-list-application-in-js-part-iv" target="_blank">previous article</a> was prefaced to be a refactoring effort to remove responsibilities of item management from the <em>list-controller</em> to instances of a <em>list-item-controller</em>. We designed the list-item-controller through specs, moved the factory to its own AMD and modified not only the <em>grocery-ls-item</em> model, but how the <em>list-item-controller</em> responded to changes of it.</p>
<p>All important and &#8211; in my view &#8211; much needed changes. However, we fell short on our goal. Sure, the tests still passed, but we modified nothing within the <em>list-controller</em> to reflect this transfer of responsibility. Part of the reason for this is my attempt at not overloading each article in this series with information. The other part is that I wanted a little time to stew over how I actually saw the revision of <em>list-controller</em>.</p>
<p>We still want to keep our feature specs of <em>Add Item</em> and <em>Mark Item</em> (and we have a few more features still to address), but I begin to question if it is really necessary to expose that functionality on the API of the <em>list-controller</em>. I am starting to see that those features are really part of a collection of <em>grocery-ls-item</em> models, and the controllers are just responders to changes on the collection and models themselves &#8211; the basis of MVC design.</p>
<p>Just as we implemented <em>list-item-controller</em> in the previous article with a design to respond to changes on a provided <em>grocery-ls-item</em> model and update its state accordingly, I propose so should we refactor the <em>list-controller</em> to respond to changes on a collection of <em>grocery-ls-item</em> models.</p>
<h2>Collection</h2>
<p>A generic collection is basically an object that provides a higher-level API to interact with an array of items. The API can provide a more readable way of adding and removing items on an underlying <a href="https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array" target="_blank">Array</a> instance instead of using methods like <em>push</em> or <em>splice</em> &#8211; which are base level and don&#8217;t use a nomenclature that is best suited for the action taken &#8211; but more importantly, the API provides a facade to operations on an array of items from which it can internally have stricter rules over such actions. </p>
<p>There are various libraries and frameworks out there that support collections, and even different type of collections &#8211; ie, sets, linked lists, etc. As has been mentioned in previous posts, I am trying not to introduce new libraries into this series as it may add unnecessary noise to the task at hand. This also allows for us to keep the <em>Collection</em> implementation lean and customizable for the <strong>Grocery List</strong> application; we&#8217;re also going to support event notification from the collection, which is not inherent in the JavaScript <a href="https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array" target="_blank">Array</a> object.</p>
<h3>Tests</h3>
<p>We will create the design of a <em>Collection</em> object piecemeal as we write the specs for it. To start, we know that it is to be a wrapper around an Array source:</p>
<p><em>/test/jasmine/spec/collection.spec.js</em></p>
<pre class="brush: jscript; first-line: 1; title: ;">
define( ['jquery'], function($) {

  var collectionImpl = {
        itemLength: function() {
          return this.list.length;
        }
      },
      collectionFactory = {
        create: function(source) {
          var instance = Object.create(collectionImpl, {
              &quot;list&quot;: {
                  value: Array.isArray(source) ? source : [],
                  writable: true,
                  enumerable: true
          });
          return instance;
        }
      };

  describe('Collection', function() {

    describe('collection factory instance creation', function() {

      it('should create unique instances of collection from create()', function() {
        var collectionOne = collectionFactory.create(),
            collectionTwo = collectionFactory.create();
        expect(collectionOne).not.toBe(collectionTwo);
      });

      it('should create an empty collection without source array provided', function() {
        var collection = collectionFactory.create();
        expect(collection).not.toBeUndefined();
        expect(collection.itemLength()).toBe(0);
      });

      it('should create a collection from source array provided', function() {
        var items = ['apples', 'oranges'],
            collection = collectionFactory.create(items);
        expect(collection.itemLength()).toBe(2);
      });

    });

  });

});
</pre>
<p>We have defined two specs that involve testing the wrapped Array source for a collection. Upon creation, the array should be empty if no source array supplied or filled with items if source provided. Pretty straight forward.<br />
<small>Again, we are only concerned with the latest-and-greatest browsers, so you may notice the use of  <a href="https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/isArray" target="_blank">Array.isArray</a> when the <em>list</em> property is defined within the check the <em>source</em> argument on the <em>collectionFactory.create()</em> call.</small></p>
<h4>aside</h4>
<p>We could get into a lengthy discussion about the design of <em>collectionImpl</em>, and in particular that the <em>list</em> property is publicly accessible &#8211; i mean, after all, are we not defeating the point of providing an API to manipulate the list if some developer could just come along and access it directly? A valid point, and one I struggle with often. We could &#8211; and I would recommend, at times &#8211; using the functional inheritance pattern to &#8216;privately&#8217; hold the underlying list within the collection. For example:</p>
<pre class="brush: jscript; title: ;">
var collectionImpl = (function(source) {
  var list = source;
  return {
    itemLength: function() {
      return list.length;
    }
  };
});
var instance = collectionImpl([]);
</pre>
<p>That would &#8216;<em>conveniently</em>&#8216; make the underlying array &#8216;private&#8217;, but there are an arguable list of pros and cons to this approach &#8211; the biggest con is the creation of a new object with new functions and new properties each call, rather then a shared inheritance. In essence, each new instance of collection created using this pattern could then modify, add and/or remove methods so that the API is not the same across all &#8216;instances&#8217; of the collection &#8211; that&#8217;s a big con for me.</p>
<p>For our implementation, let&#8217;s just take it with a grain of salt that we don&#8217;t expect anyone to maliciously access the source array of the collection and use the API we are defining in our tests <img src='http://darko.liquidweb.com/~custardb/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h4>end aside</h4>
<p>Even though in the last spec, we aren&#8217;t concerned with the underlying list being strictly equal to the provided source, we should probably check that the list has the correct items and is in the correct order:</p>
<p><em>/test/jasmine/spec/collection.spec.js</em></p>
<pre class="brush: jscript; first-line: 3; highlight: [7,8,9,10,11,12]; title: ;">
var collectionImpl = {
  itemLength: function() {
    return this.list.length;
  },
  getItemAt: function( index ) {
    if( index &lt; 0 || (index &gt; this.itemLength() - 1) ) {
      return undefined;
    }
    return this.list[index];
  }
}
</pre>
<p>The <em>getItemAt()</em> method first verifies that the supplied index within the range of the wrapped array and returns undefined if not or the item held in the array at the supplied index. We can ensure that method works properly by adding a couple tests to the spec we already have for verifying the source provided on creation:</p>
<p><em>/test/jasmine/spec/collection.spec.js</em></p>
<pre class="brush: jscript; first-line: 35; highlight: [36,37,38,40,41]; title: ;">
it('should create a collection from source array', function() {
  var itemOne = 'apples',
      itemTwo = 'oranges',
      collection = collectionFactory.create([itemOne, itemTwo]);
  expect(collection.itemLength()).toBe(2);
  expect(collection.getItemAt(0)).toEqual(itemOne);
  expect(collection.getItemAt(1)).toEqual(itemTwo);
});
</pre>
<p>Let&#8217;s go ahead and add some useful methods that will aid in adding and removing items to and from the collection:</p>
<p><em>/test/jasmine/spec/collection.spec.js</em></p>
<pre class="brush: jscript; first-line: 3; highlight: [7,8,9,10,11,12,13,14,15,16,17,18,19,20,21]; title: ;">
  var collectionImpl = {
    itemLength: function() {
      return this.list.length;
    },
    addItem: function(item) {
      this.list.push(item);
      return item;
    },
    removeItem: function(item) {
      var index = this.list.indexOf(item);
      if( index &gt; -1 ) {
        this.list.splice(index, 1);
        return item;
      }
      return undefined;
    },
    removeAll: function() {
      this.list.length = [];
    },
    getItemAt: function( index ) {
      if( index &lt; 0 || (index &gt; this.itemLength() - 1) ) {
        return undefined;
      }
      return this.list[index];
    }
  }
</pre>
<p>We could add some specs for <em>addItem()</em> to ensure that the list does grow with each item appended to the end:</p>
<p><em>/test/jasmine/spec/collection.spec.js</em></p>
<pre class="brush: jscript; first-line: 69; title: ;">
describe('collection item addition', function() {

  var collection;

  beforeEach( function() {
    collection = collectionFactory.create();
  });

  it('should append item to list from addItem()', function() {
    var item = 'grapes';
    collection.addItem(item);
    expect(collection.itemLength()).toBe(1);
    expect(collection.getItemAt(0)).toEqual(item);
  });

  it('should maintain order during multiple additions', function() {
    var itemOne = 'grapes',
        itemTwo = 'grapefruit';
    collection.addItem(itemOne);
    collection.addItem(itemTwo);
    expect(collection.itemLength()).toBe(2);
    expect(collection.getItemAt(1)).toEqual(itemTwo);
  });

  afterEach( function() {
    collection = undefined;
  });

});
</pre>
<p>&#8230; and throw in a spec suite for testing the removal API on the <em>Collection</em>:</p>
<p><em>/test/jasmine/spec/collection.spec.js</em></p>
<pre class="brush: jscript; first-line: 99; title: ;">
describe('collection item removal', function() {

  var collection,
      itemOne = 'pineapple',
      itemTwo = 'pear';

  beforeEach( function() {
    collection = collectionFactory.create();
    collection.addItem(itemOne);
  });

  it('should remove only specified item and report length of 0 from removeItem()', function() {
    collection.removeItem(itemOne);
    expect(collection.itemLength()).toBe(0);
  });

  it('should remove specified item from proper index', function() {
    collection.addItem(itemTwo);
    collection.removeItem(itemOne);
    expect(collection.itemLength()).toBe(1);
    expect(collection.getItemAt(0)).toEqual(itemTwo);
  });

  it('should retain items in collection if item provided to removeItem() is not found', function() {
    collection.addItem(itemTwo);
    collection.removeItem('watermelon');
    expect(collection.itemLength()).toBe(2);
  });

  it('should empty the list on removeAll()', function() {
    collection.addItem(itemTwo);
    collection.removeAll();
    expect(collection.itemLength()).toBe(0);
  });

  afterEach( function() {
    collection = undefined;
  });

});
</pre>
<p>With that, we have roughly designed and verified the API for our custom <em>Collection</em> object. Let&#8217;s add it to our list of specs to run:</p>
<p><em>/test/jasmine/specrunner.html</em></p>
<pre class="brush: jscript; first-line: 34; highlight: [36]; title: ;">
require( ['spec/newitem.spec.js', 'spec/markitem.spec.js',
          'spec/item-controller.spec.js', 'spec/grocery-ls-item.spec.js',
          'spec/collection.spec.js'], function() {

  var jasmineEnv = jasmine.getEnv(),
     ...
  jasmineEnv.execute();

});
</pre>
<p>Run it and all is green!<br />
<img src="http://custardbelly.com/blog/images/tdd_js/part_v_1.png" alt="Passing collection suite" /></p>
<p>Whoa. Settle down&#8230; we&#8217;re not done yet <img src='http://darko.liquidweb.com/~custardb/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h4>Collection Events</h4>
<p>If we think back to why we even started down this path of creating a Collection object, we&#8217;ll remember that its role in the <strong>Grocery List</strong> application is to serve as the model for the <em>list-controller</em>. It is the intention to eventually modify the <em>list-controller</em> to not only offload the responsibility of managing the relationship and interaction between individual <em>grocery-ls-item</em> models to their views, but also to respond to changes on the collection of <em>grocery-ls-item</em>s accordingly. As such, we will incorporate event notification into our <em>Collection</em> object, from which the <em>list-controller</em> can assign response delegates to changes on the collection.</p>
<p>Using <a href="http://api.jquery.com/category/Events/?rdfrom=http%3A%2F%2Fdocs.jquery.com%2Fmw%2Findex.php%3Ftitle%3DAPI%2F1.3%2FEvents%26redirect%3Dno" target="_blank">jQuery Event</a> as we have previously in the development of this application throughout this series, we&#8217;ll create a factory method that returns an event object based provided arguments. If you are familiar with collections from the <a href="http://www.adobe.com/devnet/flex/flex-sdk-download.html" target="_blank">Flex SDK</a>, you might notice something similar <img src='http://darko.liquidweb.com/~custardb/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  :</p>
<p><em>/test/jasmine/spec/collection.spec.js</em></p>
<pre class="brush: jscript; title: ;">
function createEvent(kind, items) {
  var event = new $.Event('collection-change');
  event.kind = kind;
  event.items = items;
  return event;
}
</pre>
<p>Basically, any event dispatched from the collection object will be of the same type, and its operation can be differentiated from the <em>kind</em> property. The items affected upon the associated operation (<em>kind</em>) are provided in an array as some operations may involve multiple items.</p>
<p>With the API we have defined for the collection, there are three operations that can modify the the list of items:</p>
<ul>
<li>add</li>
<li>remove</li>
<li>reset</li>
</ul>
<p>The methods associated with add and remove are pretty self-explanatory and we will consider <em>removeAll()</em> as a reset on the collection. With this in mind, let&#8217;s append a couple tests to our spec suites for these event notifications:</p>
<p><em>/test/jasmine/spec/collection.spec.js</em></p>
<pre class="brush: jscript; first-line: 121; title: ;">
describe('collection item addition', function() {
...
    async.it('should notify on addition of item', function(done) {
      var item = 'grapes';
      $(collection).on('collection-change', function(event) {
        expect(event.kind).toBe('add');
        expect(event.items.length).toBe(1);
        expect(event.items[0]).toEqual(item);
        $(collection).off('collection-change');
        done();
      });
      collection.addItem(item);
    });
...
});
...
describe('collection item removal', function() {
...
  async.it('should notify on removal of item', function(done) {
    collection.addItem(itemTwo);
    $(collection).on('collection-change', function(event) {
      expect(event.kind).toBe('remove');
      expect(event.items.length).toBe(1);
      expect(event.items[0]).toEqual(itemOne);
      $(collection).off('collection-change');
      done();
    });
    collection.removeItem(itemOne);
  });

  async.it('should notify on reset of collection', function(done) {
    $(collection).on('collection-change', function(event) {
      expect(event.kind).toBe('reset');
      expect(event.items.length).toBe(0);
      $(collection).off('collection-change');
      done();
    });
    collection.removeAll();
  });

  afterEach( function() {
    collection = undefined;
  });
...
});
</pre>
<p>If you were to run the tests now, you would see a couple execute then hang intermittently as it waits for the async tests to timeout&#8230; because we haven&#8217;t implemented the dispatching of events from the collection yet <img src='http://darko.liquidweb.com/~custardb/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><em>/test/jasmine/spec/collection.spec.js</em></p>
<pre class="brush: jscript; first-line: 10; highlight: [16,23,30]; title: ;">
var collectionImpl = {
  itemLength: function() {
    return this.list.length;
  },
  addItem: function(item) {
    this.list.push(item);
    $(this).trigger(createEvent('add', [item]));
    return item;
  },
  removeItem: function(item) {
    var index = this.list.indexOf(item);
    if( index &gt; -1 ) {
      this.list.splice(index, 1);
      $(this).trigger(createEvent('remove', [item]));
      return item;
    }
    return undefined;
  },
  removeAll: function() {
    this.list.length = [];
    $(this).trigger(createEvent('reset', this.list));
  },
  getItemAt: function( index ) {
    if( index &lt; 0 || (index &gt; this.itemLength() - 1) ) {
      return undefined;
    }
    return this.list[index];
  }
}
</pre>
<p>Now, if you were to run the tests, all should be happy.</p>
<h3>Collection Module Implementation</h3>
<p>Just as we have done with the <em>list-item-controller</em> from the <a href="http://custardbelly.com/blog/2012/12/17/the-making-of-a-test-driven-grocery-list-application-in-js-part-iv/" target="_blank">previous article</a>, we are going to take the work we had done in implementing the collection object within our tests and move it to an AMD module. This way, if we <em>ever</em> get around to refactoring the <em>list-controller</em>, we&#8217;ll be able to utilize the collection module:</p>
<p><em>/script/collection/collection.js</em></p>
<pre class="brush: jscript; first-line: 1; title: ;">
define(['jquery'], function($) {

  function createEvent(kind, items) {
    var event = $.Event('collection-change');
    event.kind = kind;
    event.items = items;
    return event;
  }

  var _collectionEventKind = {
        ADD: 'add',
        REMOVE: 'remove',
        RESET: 'reset'
      },
      collection = {
        itemLength: function() {
          return this.list.length;
        },
        addItem: function(item) {
          this.list.push(item);
          $(this).trigger(createEvent(_collectionEventKind.ADD, [item]));
          return item;
        },
        removeItem: function(item) {
          var index = this.getItemIndex(item);
          if( index &gt; -1 ) {
            this.list.splice(index, 1);
            $(this).trigger(createEvent(_collectionEventKind.REMOVE, [item]));
            return item;
          }
          return undefined;
        },
        removeAll: function() {
          this.list.length = 0;
          $(this).trigger(createEvent(_collectionEventKind.RESET, this.list));
        },
        getItemAt: function(index) {
          if( index &lt; 0 || (index &gt; this.itemLength() - 1) ) {
            return undefined;
          }
          return this.list[index];
        },
        getItemIndex: function(item) {
          return this.list.indexOf(item);
        },
        contains: function(item) {
          return this.getItemIndex(item) != -1;
        }
      };

  return {
    collectionEventKind: _collectionEventKind,
    create: function(source) {
      var instance = Object.create(collection);
      Object.defineProperty(instance, &quot;list&quot;, {
          value: Array.isArray(source) ? source : [],
          writable: true,
          enumerable: true
      });
      return instance;
    }
  };

});
</pre>
<p>We have basically ripped the collection and factory out from our test implementation and dropped it into its own file, returning the event kind enumeration object and the <em>create()</em> factory method to generate new collections for this AMD module.</p>
<p>To verify that our <em>Collection</em> module works correctly, let&#8217;s replace the implementation in the test with this module reference and run our tests again:</p>
<p><em>/test/jasmine/spec/collection.spec.js</em></p>
<pre class="brush: jscript; first-line: 1; highlight: [1]; title: ;">
define( ['jquery', 'script/collection/collection'], function($, collectionFactory) {

  describe('Collection', function() {
     ...
  });

});
</pre>
<p><img src="http://custardbelly.com/blog/images/tdd_js/part_v_2.png" alt="Passing collection tests on AMD module" /></p>
<p>Tagged: <strong>0.1.6</strong> <a href="https://github.com/bustardcelly/grocery-ls/tree/0.1.6" target="_blank">https://github.com/bustardcelly/grocery-ls/tree/0.1.6</a></p>
<h2>list-controller Refactoring</h2>
<p>Passing tests are great! But currently, they are lying to us. Well&#8230; not <em>really</em>,  but we have gone about all these new additions to our application and have yet still to refactor <em>list-controller</em> to utilize them. However, before we just start chopping out and inserting code from <em>list-controller</em>, I want to go over the API and specs currently defined and see if they still hold water &#8211; meaning we might be able to cut some tests out. We might not. We might even add more. Let&#8217;s see&#8230;</p>
<h3>newitem.spec</h3>
<p>As we designed the <a href="https://github.com/bustardcelly/grocery-ls/blob/0.1.3/script/controller/list-controller.js" target="_blank"><em>list-controller</em></a> from a <a href="http://custardbelly.com/blog/2012/12/06/the-making-of-a-test-driven-grocery-list-application-in-js-part-iii" target="_blank">previous article</a>, it oversaw the state of list items, list item views, and sort of supported a quasi-state of <em>&#8216;editability&#8217;</em>. While this provided an API to create a new item, it was forced into exposing an <em>editableItem</em> that was then mutable based on other parts of its API &#8211; ie, <em>editFocusedItem()</em> and <em>saveFocusedItem()</em>. All well and good to support the feature requirements at the time, but we have now moved the item and item view management &#8211; as well as the editable state &#8211; to the latest <em>list-item-controller</em> as can be seen in the repo <a href="https://github.com/bustardcelly/grocery-ls/blob/0.1.5/script/controller/list-item-controller.js" target="_blank">tagged at 0.1.5</a>. As such, I feel not only the <em>list-controller</em>, itself, should change to reflect these modifications, but also its API.</p>
<p>We are going to stick with our feature request to be able to add a new item to the <strong>Grocery List</strong> application through the <em>list-controller</em>, but will revisit how that is done in accordance to the new functionality of both the <em>list-item-controller</em> and <em>list-controller</em>; mainly we want to keep in mind that both should be driven by their respective model: <em>grocery-ls-item</em> and <em>collection</em>.</p>
<p>Let&#8217;s first revisit the specs we defined for new item feature from <a href="http://custardbelly.com/blog/2012/11/26/the-making-of-a-test-driven-grocery-list-application-in-js-part-ii/" target="_blank">the second post</a> in this series:</p>
<p><em>// spec</em><br />
&#8212;<br />
<strong>Scenario 1:</strong> Item added to list<br />
<strong>Given</strong> a user requests to add an item to the list<br />
<strong>And</strong> has provided a name for the item<br />
<strong>When</strong> she requests to save the item<br />
<strong>Then</strong> the list has grown by one item<br />
<strong>And</strong> the list contains the item appended at the end<br />
&#8212;</p>
<p><em>// spec</em><br />
&#8212;<br />
<strong>Scenario 2:</strong> Item not added to list<br />
<strong>Given</strong> the list has a single item<br />
<strong>And</strong> a user requests to add an item to the list<br />
<strong>And</strong> has not provided a name for the item<br />
<strong>When</strong> she requests to save the item<br />
<strong>Then</strong> the list has the same items as stored previously<br />
<strong>And</strong> the list does not add an empty-named item<br />
&#8212;</p>
<p>In looking at them now, I feel that the actual <em>Add Item</em> feature is hidden in the <strong>Given</strong>s. A slight oversight now that we have progressed &#8211; perhaps one at the time as well, but we were delivering to features using TDD, so I have no qualms with features and implementations revisited and revised as the functionality of the application is fleshed out. In any event, I feel like these feature specs are more for a <em>Save Item</em> story, especially seeing as a User can edit an existing item. We&#8217;ll tackle the <em>Save Item</em> specifications for a later post, for now I want to revise the specifications for the <em>Add Item</em> feature.</p>
<h4>Tests</h4>
<p>The original story does not change, but we want to ensure that a <em>grocery-ls-item</em> model is returned on the API to create a new item from <em>list-controller </em>. With such a drastic refactor to the functionality of <em>list-controller</em>, I tend to do my thinking and designing within the tests and move to implementation &#8211; just as I have done previously with other components. Let&#8217;s take a look at the change to <em>newitem.spec.js</em> as a whole and then discuss the specs singularly:</p>
<p><em>/test/jasmine/spec/feature.newitem.spec.js</em></p>
<pre class="brush: jscript; first-line: 1; title: ;">
define(['jquery', 'script/controller/list-controller', 'script/controller/list-item-controller',
        'script/collection/collection', 'script/model/grocery-ls-item'],
        function($, listController, itemControllerFactory, collectionFactory, modelFactory) {

  describe('New item creation from listController.createNewItem()', function() {

    var newModel,
        newItemController,
        listControllerStub,
        $listView = $('&lt;ul/&gt;'),
        itemCollection = collectionFactory.create();

    beforeEach( function() {
      var $itemView = $('&lt;li&gt;');

      newModel = modelFactory.create();
      newItemController = itemControllerFactory.create($itemView, newModel);

      listControllerStub = sinon.stub(listController, 'createNewItem', function() {
        listController.getItemList().addItem(newModel);
        $itemView.appendTo($listView);
        return newModel;
      });
      listController.getItemList = sinon.stub().returns(itemCollection);
      listController.setView($listView);
    });

    it('should return newly created model', function() {
      var newItem = listController.createNewItem();
      // loosely (duck-ly) verifying grocery-ls-item type.
      expect(newItem).toEqual(jasmine.any(Object));
      expect(newItem.hasOwnProperty('name')).toBe(true);
      expect(newItem.hasOwnProperty('id')).toBe(true);
      expect(newItem.id).not.toBeUndefined();
    });

    it('should add newly created item to collection', function() {
      var newItem = listController.createNewItem(),
          itemList = listController.getItemList();
      expect(itemList.itemLength()).not.toBe(0);
      expect(itemList.getItemAt(itemList.itemLength()-1)).toEqual(newItem);
    });

    it('should add new item controller to view', function() {
      listController.createNewItem();
      expect($listView.children().length).toBe(1);
    });

    afterEach( function() {
      $listView.empty();
      newModel = undefined;
      newItemController = undefined;
      itemCollection.removeAll();
      listController.createNewItem.restore();
    });

  });

});
</pre>
<p>First off, you may notice that we are pulling in, as dependencies, every component we have basically created up to this point. Then, within the <em>beforeEach()</em> of the spec suite, using <a href="http://sinonjs.org/" target="_blank">SinonJS</a> we stub out the redesign and addition(s) to the API of <em>list-controller</em>; we are redefining the functionality of <em>createNewItem()</em> (which currently exists on <em>list-controller</em>) to return a <em>grocery-ls-item</em> instance and stubbing the <em>getItemList(</em>) method which will return the underlying collection model.</p>
<p>You may notice that i am using sinon.stub in two different ways:</p>
<pre class="brush: jscript; first-line: 19; title: ;">
listControllerStub = sinon.stub(listController, 'createNewItem', function() {
</pre>
<pre class="brush: jscript; first-line: 24; title: ;">
listController.getItemList = sinon.stub().returns(itemCollection);
</pre>
<p>The former allows for you to redefine the function invoked upon the public method &#8211; in this case &#8216;<em>createNewItem</em>&#8216;. In order to properly define a stub in such a manner without being shown errors in executing the tests, the method must already be available on the object you are stubbing. The latter allows you to stub a method that is not currently on the object. As you may notice, the instantiation of the two different stubs are different in their assignment on the object being stubbed. The operations within these stubs shouldn&#8217;t be taken as set in stone &#8211; they may change once we get to implementation in <em>list-controller</em> &#8211; but they setup our expectations that will be verified in the specifications. The first of which ensures the return of a <em>grocery-ls-item</em> through property assertions:</p>
<p><em>/test/jasmine/spec/feature/newitem.spec.js</em></p>
<pre class="brush: jscript; first-line: 28; title: ;">
it('should return newly created model', function() {
  var newItem = listController.createNewItem();
  // loosely (duck-ly) verifying grocery-ls-item type.
  expect(newItem).toEqual(jasmine.any(Object));
  expect(newItem.hasOwnProperty('name')).toBe(true);
  expect(newItem.hasOwnProperty('id')).toBe(true);
  expect(newItem.id).not.toBeUndefined();
});
</pre>
<p>The second spec tests that the newly created item is added to the collection exposed on list-controller:<br />
<em>/test/jasmine/spec/feature/newitem.spec.js</em></p>
<pre class="brush: jscript; first-line: 37; title: ;">
it('should add newly created item to collection', function() {
  var newItem = listController.createNewItem(),
      itemList = listController.getItemList();
  expect(itemList.itemLength()).not.toBe(0);
  expect(itemList.getItemAt(itemList.itemLength()-1)).toEqual(newItem);
});
</pre>
<p>And the third spec&#8230; well, it starts to address some of the expectations a User may have when using the <strong>Grocery List</strong> application, something we really haven&#8217;t tested for as of yet &#8211; you have to start somewhere, though, right? We are testing that in addition to a new model added to the collection, there is an associated view in the UI (or at least presumably):<br />
<em>/test/jasmine/spec/feature/newitem.spec.js</em></p>
<pre class="brush: jscript; first-line: 44; title: ;">
it('should add new item controller to view', function() {
  listController.createNewItem();
  expect($listView.children().length).toBe(1);
});
</pre>
<p>I think we will start to see more of these type of tests as we start fleshing out the features more. </p>
<p>Actually, I have started taking steps in moving the separation of <em>integration tests</em> from <em>feature tests</em>, if you haven&#8217;t already noticed the update to the location of <em>newitem.spec.js</em>. In my mind, the difference is between what I consider tests of how a component behaves itself (and with others) and test which describe the actual use of the application, respectively.</p>
<p>Run the tests just as you have before with the updates to the feature spec locations:<br />
<em>/test/jasmine/specrunner.html</em></p>
<pre class="brush: jscript; first-line: 34; highlight: [34]; title: ;">
require( ['spec/feature/additem.spec.js', 'spec/feature/markitem.spec.js',
          'spec/item-controller.spec.js', 'spec/grocery-ls-item.spec.js',
          'spec/collection.spec.js'], function() {

  var jasmineEnv = jasmine.getEnv(),
       ...
  jasmineEnv.execute();

});
</pre>
<p>And all is green! <img src='http://darko.liquidweb.com/~custardb/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Tagged <strong>0.1.7</strong> &#8211; <a href="https://github.com/bustardcelly/grocery-ls/tree/0.1.7" target="_blank">https://github.com/bustardcelly/grocery-ls/tree/0.1.7</a></p>
<h3>list-controller Revisted</h3>
<p>It&#8217;s great that the tests still pass, but we have yet to <strong>still</strong> modify <em>list-controller</em>. I can&#8217;t put it off any longer. If you have put up with the last couple posts and promises to get somewhere, you are very kind. The wait is over! &#8230; but it is also just the tip of the iceberg. sorry to be a downer <img src='http://darko.liquidweb.com/~custardb/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>In looking at the API on <em>list-controller</em> we stubbed out from the <em>beforeEach()</em> of the <em>newitem.spec</em> and the expectations of its functionality verified in the specs, we are basically boiling down the responsibilities of the <em>list-controller</em> to:</p>
<ul>
<li>Create a new item</li>
<li>Add item views to a provided element</li>
<li>Manage and respond to changes on a collection of <em>grocery-ls-item</em></li>
</ul>
<p>As a start, we can include the new dependencies and refactor the <em>list-controller</em> component to support these requirements:<br />
<em>/script/controller/list-controller.js</em></p>
<pre class="brush: jscript; title: ;">
define(['jquery', 'script/controller/list-item-controller', 'script/collection/collection', 'script/model/grocery-ls-item'],
        function($, itemControllerFactory, collectionFactory, modelFactory) {

  var collection = collectionFactory.create(),
      listController = {
        $view: undefined,
        getItemList: function() {
          return collection;
        },
        createNewItem: function() {
          var model = modelFactory.create();
          collection.addItem(model);
          return model;
        },
        setView: function(view) {
          this.$view = (view instanceof $) ? view : $(view);
        }
      };

  return listController;

});
</pre>
<p>Differing from the stub created for <em>createNewItem()</em> in the <em>newitem.spec</em>, the <em>list-controller</em> is only concerned with updating the collection model here. This is because the change to the collection will drive updates to the UI and we don&#8217;t want to have the UI operations within the <em>createNewItem()</em> method &#8211; that will basically create a doubling-up of efforts. It will be the responsibility of this module to observe changes to the collection and update state. That is done by adding an event handler to <em>collection-change</em> and operating accordingly based on event <em>kind</em>:</p>
<p><em>/script/controller/list-controller.js</em></p>
<pre class="brush: jscript; first-line: 1; highlight: [20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41]; title: ;">
define(['jquery', 'script/controller/list-item-controller', 'script/collection/collection', 'script/model/grocery-ls-item'],
        function($, itemControllerFactory, collectionFactory, modelFactory) {

  var collection = collectionFactory.create(),
      listController = {
        $view: undefined,
        getItemList: function() {
          return collection;
        },
        createNewItem: function() {
          var model = modelFactory.create();
          collection.addItem(model);
          return model;
        },
        setView: function(view) {
          this.$view = (view instanceof $) ? view : $(view);
        }
      };

  (function assignCollectionHandlers($collection) {

    var EventKindEnum = collectionFactory.collectionEventKind;

    $collection.on('collection-change', function(event) {
      switch( event.kind ) {
        case EventKindEnum.ADD:
          var model = event.items.shift(),
              $itemView = $('&lt;li&gt;'),
              itemController = itemControllerFactory.create($itemView, model);

          $itemView.appendTo(listController.$view);
          itemController.state = itemControllerFactory.state.EDITABLE;
          break;
        case EventKindEnum.REMOVE:
          break;
        case EventKindEnum.RESET:
          break;
      }
    });

  }($(collection)));

  return listController;

});
</pre>
<p>We are calling an <strong><a href="http://benalman.com/news/2010/11/immediately-invoked-function-expression/" target="_blank">IIFE</a></strong> with the <a href="http://jquery.org" target="_blank">jQuery</a> wrapped collection object and assigning an event handler to <em>collection-change</em> on the collection. Depending on the kind of <em>collection-change</em> event that has occurred, defined clauses with specified operations are entered &#8211; for the purposes of the current task and tests at hand, that is only the <em>ADD</em> event.</p>
<p>In the <em>EventKindEnum.ADD</em> switch..case you will see the UI modification, with the addition of the list item view and the editability state of its associated <em>list-item-controller</em> set to allow the User to edit the new item.</p>
<p>Now, with the implementation of the <em>Add Item</em> feature moved to <em>list-controller</em>, we can clean up our <em>newitem.spec.js</em>:<br />
<em>/test/jasmine/spec/feature/newitem.spec.js</em></p>
<pre class="brush: jscript; first-line: 1; highlight: [1,2,6,9,34]; title: ;">
define(['jquery', 'script/controller/list-controller'],
        function($, listController) {

  describe('New item creation from listController.createNewItem()', function() {

    var $listView = $('&lt;ul/&gt;');

    beforeEach( function() {
      listController.setView($listView);
    });

    it('should return newly created model', function() {
      var newItem = listController.createNewItem();
      // loosely (duck-ly) verifying grocery-ls-item type.
      expect(newItem).toEqual(jasmine.any(Object));
      expect(newItem.hasOwnProperty('name')).toBe(true);
      expect(newItem.hasOwnProperty('id')).toBe(true);
      expect(newItem.id).not.toBeUndefined();
    });

    it('should add newly created item to collection', function() {
      var newItem = listController.createNewItem(),
          itemList = listController.getItemList();
      expect(itemList.itemLength()).not.toBe(0);
      expect(itemList.getItemAt(itemList.itemLength()-1)).toEqual(newItem);
    });

    it('should add new item controller to view', function() {
      listController.createNewItem();
      expect($listView.children().length).toBe(1);
    });

    afterEach( function() {
      $listView.empty();
    });

  });

});
</pre>
<p>And we&#8217;ll modify the main application module to reflect the change to the <em>list-controller</em> now only governing over a list DOM element and not to manage events from the add button on the DOM:</p>
<p><em>/script/grocery-ls.js</em></p>
<pre class="brush: jscript; first-line: 1; highlight: [12,13,14,15,16,17,18,19,20]; title: ;">
(function(window, require) {

  require.config({
    baseUrl: &quot;.&quot;,
    paths: {
      &quot;lib&quot;: &quot;./lib&quot;,
      &quot;script&quot;: &quot;./script&quot;,
      &quot;jquery&quot;: &quot;./lib/jquery-1.8.3.min&quot;
    }
  });

  require( ['jquery', 'script/controller/list-controller', 'script/collection/collection'],
            function($, listController, collectionFactory) {

    listController.setView($('section.groceries ul'));
    $('section.groceries #add-item-button').on('click', function(event) {
      listController.createNewItem();
    });

  });

}(window, requirejs));
</pre>
<p>Run the tests&#8230; and it will fail! Yay!<br />
<img src="http://custardbelly.com/blog/images/tdd_js/part_v_3.png" alt="Failing tests on list-controller refactor" /></p>
<p><em>wait, what?!</em></p>
<p>Actually, most will pass &#8211; including the <em>newitem.spec</em> tests. It is the <em>markitem.spec</em> tests that will fail. We have modified the <em>list-controller</em> to accomodate the changes to the <em>Add Item</em> feature, but have not addressed the <em>Mark Off Item</em> feature in our refactoring.</p>
<p><img src="http://custardbelly.com/blog/images/tdd_js/part_v_4.png" alt="Mark-Off Item failure on list-controller refactor" /></p>
<p>However, run the application and it will be just as usable as it was before &#8211; no change will be perceived by the end-user. The only thing that will change is now I have a <span style="color: red;">nagging feeling knowing my tests are failing</span>. Some naysayers may interject here and half-heartedly tell me to get rid of the tests, then. To them I say, &#8216;<em>pfffft</em>&#8216; <img src='http://darko.liquidweb.com/~custardb/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  </p>
<p>I hate to see the tests in such a state, but this post is rather long as it is. Also, I like to joke that sometimes having failing tests to look at first thing in the morning is the best way to pick up from where you left off. I promise we&#8217;ll get these to go green in the next article of this series, and invite you to get them to pass if you are for it.</p>
<p>Tagged <strong>0.1.8</strong> &#8211; <a href="https://github.com/bustardcelly/grocery-ls/tree/0.1.8" target="_blank">https://github.com/bustardcelly/grocery-ls/tree/0.1.8</a></p>
<h2>Conclusion</h2>
<p>We finally got around to refactoring the <em>list-controller</em> to relieve it of item model management and state. In the course of doing so, we created a <em>Collection</em> object that will serve as the model for the <em>list-controller</em>. </p>
<p>This post was a lengthy one, and I appreciate you sticking through my yackity-yack. I think we are in fine shape now to approach previously defined and new features, get our tests passing again, and finalize the <strong>Grocery List</strong> application&#8230; in as far as first iteration deliverables go <img src='http://darko.liquidweb.com/~custardb/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>&#8216;Til next time&#8230;</p>
<p>&#8212;</p>
<h1>Link Dump</h1>
<h2>Reference</h2>
<p><a href="http://tddjs.com/" target="_blank">Test-Driven JavaScript Development by Christian Johansen</a><br />
<a href="http://dannorth.net/introducing-bdd/" target="_blank">Introducing BDD by Dan North</a><br />
<a href="http://requirejs.org/" target="_blank">RequireJS</a><br />
<a href="https://github.com/amdjs/amdjs-api/wiki/AMD" target="_blank">AMD</a><br />
<a href="http://pivotal.github.com/jasmine/" target="_blank">Jasmine</a><br />
<a href="http://sinonjs.org/" target="_blank">Sinon</a><br />
<a href="https://github.com/derickbailey/jasmine.async" target="_blank">Jasmine.Async</a></p>
<h2>Post Series</h2>
<p><a href="https://github.com/bustardcelly/grocery-ls">grocery-ls github repo</a><br />
<a href="http://custardbelly.com/blog/2012/11/26/the-making-of-a-test-driven-grocery-list-application-in-javascript-part-i" target="_blank">Part I &#8211; Introduction</a><br />
<a href="http://custardbelly.com/blog/2012/11/26/the-making-of-a-test-driven-grocery-list-application-in-js-part-ii">Part II &#8211; Feature: Add Item</a><br />
<a href="http://custardbelly.com/blog/2012/12/06/the-making-of-a-test-driven-grocery-list-application-in-js-part-iii">Part III &#8211; Feature: Mark-Off Item</a><br />
<a href="http://custardbelly.com/blog/2012/12/17/the-making-of-a-test-driven-grocery-list-application-in-js-part-iv">Part IV &#8211; Feature: List-Item-Controller</a><br />
<a href="http://custardbelly.com/blog/2012/12/31/the-making-of-a-test-driven-grocery-list-application-in-js-part-v/">Part V &#8211; Feature: List-Controller Refactoring</a><br />
<a href="http://custardbelly.com/blog/2013/01/08/the-making-of-a-test-driven-grocery-list-application-in-js-part-vi/" target="_blank">Part VI &#8211; Back to Passing</a><br />
<a href="http://custardbelly.com/blog/2013/01/17/the-making-of-a-test-driven-grocery-list-application-in-js-part-vii/">Part VII &#8211; Remove Item</a><br />
<a href="http://custardbelly.com/blog/2013/01/22/the-making-of-a-test-driven-grocery-list-application-part-viii/">Part VIII &#8211; Bug Fixing</a><br />
<a href="http://custardbelly.com/blog/2013/02/15/the-making-of-a-test-driven-grocery-list-application-in-js-part-ix/">Part IX &#8211; Persistence</a><br />
<a href="http://custardbelly.com/blog/2013/03/06/the-making-of-a-test-driven-grocery-list-application-in-js-part-x/">Part X &#8211; It Lives!</a></p>
]]></content:encoded>
			<wfw:commentRss>http://custardbelly.com/blog/2012/12/31/the-making-of-a-test-driven-grocery-list-application-in-js-part-v/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Making of a Test-Driven Grocery List Application in JS: Part IV</title>
		<link>http://custardbelly.com/blog/2012/12/17/the-making-of-a-test-driven-grocery-list-application-in-js-part-iv/</link>
		<comments>http://custardbelly.com/blog/2012/12/17/the-making-of-a-test-driven-grocery-list-application-in-js-part-iv/#comments</comments>
		<pubDate>Mon, 17 Dec 2012 21:01:20 +0000</pubDate>
		<dc:creator>todd anderson</dc:creator>
				<category><![CDATA[AMD]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[RequireJS]]></category>
		<category><![CDATA[grocery-ls]]></category>
		<category><![CDATA[jasmine]]></category>
		<category><![CDATA[unit-testing]]></category>

		<guid isPermaLink="false">http://custardbelly.com/blog/?p=655</guid>
		<description><![CDATA[This is the fourth installment in a series of building a Test-Driven Grocery List application using Jasmine and RequireJS. To learn more about the intent and general concept of the series please visit The Making of a Test-Driven Grocery List Application in JavaScript: Part I
&#8212;
Introduction
In the previous article we developed a new feature for the [...]]]></description>
			<content:encoded><![CDATA[<p><em>This is the fourth installment in a series of building a Test-Driven Grocery List application using <a href="http://pivotal.github.com/jasmine/" target="_blank">Jasmine</a> and <a href="http://requirejs.org" target="_blank">RequireJS</a>. To learn more about the intent and general concept of the series please visit <a href="http://custardbelly.com/blog/2012/11/26/the-making-of-a-test-driven-grocery-list-application-in-javascript-part-i/">The Making of a Test-Driven Grocery List Application in JavaScript: Part I</a></em><br />
&#8212;</p>
<h1>Introduction</h1>
<p>In the <a href="http://custardbelly.com/blog/2012/12/06/the-making-of-a-test-driven-grocery-list-application-in-js-part-iii/" target="_blank">previous</a> article we developed a new feature for the <strong>Grocery List</strong> application: <em>Mark Off Item</em>. In the process of doing so, or at least when we went from the tests to implementation, we added more responsibility to the <em>list-controller</em> as it pertained to individual view and model items.</p>
<p>In this article, we are going to refactor out that responsibility into its own <em>list-item-controller</em> that will be responsible for managing the relationship of a list item view to a single <em>grocery-ls-item</em> model.</p>
<h2>Refactoring</h2>
<p>As it stands , I think the design of the <em>list-controller</em> is fine: exposing an API to modify the list. It&#8217;s the internals that are starting to bug me. If the current behaviour and responsibilities were all that was needed, I suppose we could walk away and feel confident about our application as is. However, in forward thinking other operations that could involve list items &#8211; such as deletion &#8211; I feel the responsibilities of the <em>list-controller</em> will quickly outgrow its intent. </p>
<p>I suppose, some would argue, that if the responsibilities of the list-controller grow to more operations that are tightly coupled with singular pieces of data, then we could just write more tests to verify its soundness. Not entirely a bad argument &#8211; i mean that is what we are trying to justify in this series, essentially. But it is not a 1:1 correlation of more tests to better design. It is preferred to separate concerns as much as possible in order to properly test. The maintenance of complex tests can be a bigger burden than the maintenance of complex code &#8211; so much so that testing stops all together.</p>
<h3>list-item-controller</h3>
<p>Before we dive in to creating a <em>list-item-controller</em>, let&#8217;s take a look at what concerns within <em>list-controller</em> we want to move out. Looking from the <a href="https://github.com/bustardcelly/grocery-ls/blob/0.1.3/script/controller/list-controller.js" target="_blank">0.1.3 tagged list-controller</a>, we mainly want to cut out the item view creation &#8211; so the following node declarations and any associated item creation and item management:</p>
<p><em>/script/controller/list-controller.js tagged at 0.1.3</em></p>
<pre class="brush: jscript; first-line: 6; title: ;">
itemFragment          = '&lt;li class=&quot;grocery-item&quot; /&gt;',
editableItemFragment  = '&lt;li class=&quot;editable-grocery-item&quot;&gt;' +
                                           '&lt;input id=&quot;editableItem&quot; name=&quot;editableItem&quot; ' +
                                               'class=&quot;editable-item&quot; placeholder=&quot;Enter item name...&quot;&gt;' +
                                          '&lt;/input&gt;' +
                                        '&lt;/li&gt;'
</pre>
<p>These declarations and management of view will be moved to the <em>list-item-controller</em>. The UI and usability of a list item will be driven by the model and should provide an API that is a level of abstraction from the model for any outside parties (ie, the <em>list-controller</em>). As well, the model drives the internal state of edit-ability and marked-off-ed-ness (<em>they&#8217;re words, alright</em>!), and the <em>list-item-controller</em> will dispatch events related to its change of state. Lofty goals, but let&#8217;s see if we can&#8217;t address them.</p>
<h4>a bit of uncertainty</h4>
<p>We currently created specs for <em>Add Item</em> and <em>Mark Off Item</em> features. These were a little high-level in that they described features using the BDD syntax of <a href="http://pivotal.github.com/jasmine/" target="_blank">Jasmine</a> but did involve tests around how to interact with the <em>list-controller</em> API; so they do involve integration to some respect &#8211; we kind of ignore the whole UI and User Interaction aspect within the tests. </p>
<p>Now here is where I have an internal struggle with writing specs: should the tests we need for the <em>list-item-controller</em> be added to these specs? Or should a new spec focused on <em>list-item-controller</em> API and usability be born? I ask, because from outside-looking-in, the creation, editability and mark-off of an item will still be feasible through the <em>list-controller</em> and to any other third parties &#8211; that API provides a facade to modifying a grocery list. So, the current specs we have serve as a nice example of how to interact with the application from the outside&#8230; and if they are passing, we know that from higher-level things <em>should</em>* work <img src='http://darko.liquidweb.com/~custardb/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  </p>
<p>When we get down to the implementation of the <em>list-item-controller</em>, from a design perspective we know that a dependency will be introduced: <em>list-controller</em> will have n-number of <em>list-item-controller</em> instances, and will be responsible for the creation and maintenance of each <em>list-item-controller</em>. The state and <em>grocery-ls-item</em> model maintenance which we established in the previous articles as the responsibility of the <em>list-controller</em> will, as well, become the responsibility of the <em>list-item-controller</em>.</p>
<p>Knowing this, I start to feel that this is closer to testing the implementation and behaviour of a component, rather then one of the &#8217;system&#8217;, and would push for its own spec. But I am very much open to ideas, so please leave a comment.</p>
<h3>list-item-controller design</h3>
<p>In my <em>bit of uncertainty</em>, I basically described the design of the <em>list-item-controller</em>. Now, we&#8217;ll flesh out its behaviour and API in a spec and eventually move it to its own AMD implementation. To start out slowly we&#8217;ll create a new spec suite and define the <em>list-item-controller</em> attributes:</p>
<p><em>/test/jasmine/spec/list-item-controller.spec.js</em></p>
<pre class="brush: jscript; first-line: 1; title: ;">
define(['jquery', 'script/model/grocery-ls-item'], function($, modelFactory) {

  describe('list-item-controller', function() {

    function createStateEvent(oldState, newState) {
        var event = new $.Event('state-change');
        event.oldState = oldState;
        event.newState = newState;
        return event;
    }

    var itemControllerFactory = {
        create: function(node, model) {
          var itemController = Object.create(Object.prototype);

          (function(controller, stateEventCreator) {
            var _state = 'normal';
            Object.defineProperties(controller, {
              &quot;model&quot;: {
                value: model,
                writable: false,
                enumerable: true
              },
              &quot;parentView&quot;: {
                value: node,
                writable: false,
                enumerable: true
              },
              &quot;state&quot;: {
                set: function(value) {
                  var event = stateEventCreator.call(this, this.state, value);
                  _state = value;
                  $(this).trigger(event);
                },
                get: function() {
                  return _state;
                }
              }
            });
          }(itemController, createStateEvent));

          return itemController;
        }
      };
  });
});
</pre>
<p>The object declared &#8211; <em>itemControllerFactory</em> &#8211; is a factory instance that will generate new instances of a <em>list-item-controller</em>. The factory pattern should be familiar to you if you look at the <em>grocery-ls-item</em> AMD we created in the second article in the series. When creating an instance of a <em>list-item-controller</em>, we have defined that a parent DOM node and a model should be passed in during creation, as can be seen in <em>itemControllerFactory:create()</em>. If we look at the <em>defineProperties</em>, we have also defined a few characteristics of the <em>list-item-controller</em> here. It has:</p>
<ul>
<li>Parent Node reference &#8211; DOM instance of which to modify view state.</li>
<li>Model reference &#8211; Model of which the View is driven by.</li>
<li>State &#8211; State of View within the DOM representing the Model.</li>
</ul>
<p>We have designed the <em>state</em> property a little differently than you may have seen before, at least in this series. We declared the implicit getter/setters so as to keep track of state internally and dispatch an event of <em>&#8217;state-change&#8217;</em>. By &#8216;<em>internally</em>&#8216;, I mean I used an <a href="http://benalman.com/news/2010/11/immediately-invoked-function-expression/" target="_blank">IIFE</a> to enclose a &#8216;<em>private</em>&#8216; member storing state.</p>
<p>If you know of event-driven design &#8211; whether or not you are familiar with <a href="http://api.jquery.com/category/Events/?rdfrom=http%3A%2F%2Fdocs.jquery.com%2Fmw%2Findex.php%3Ftitle%3DAPI%2F1.3%2FEvents%26redirect%3Dno" target="_blank">jQuery Events</a>, which the <em>state</em> property employs &#8211; then this will look familiar. Essentially, we want to allow any client who wants to know about the change of state to a <em>list-item-controller</em> instance to be notified through an event of <em>&#8217;state-change&#8217;</em>. This will become more apparent later on in development, but just keep in mind that it is the responsibility of the <em>list-controller</em> to maintain n-number of <em>list-item-controller</em>s; and part of that maintenance is being aware of each <em>list-item-controller</em>&#8217;s state &#8211; and since binding is not inherently available in JavaScript, and I don&#8217;t want to introduce any new libraries that could handle binding, listening on events is an easy way to go about tracking state. <em>You feel adventurous enough, we can build a binding mechanism on top of this event system&#8230; just make sure it&#8217;s got tests <img src='http://darko.liquidweb.com/~custardb/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </em></p>
<h2>Tests</h2>
<p>Before we begin creating the tests for the <em>list-item-controller</em>, you may be wondering where the feature stories and scenarios are. We could definitely define those, however &#8211; and of course, I can always be wrong &#8211; I feel those are more business-facing&#8230; well, stories at least. They are used to define some type of behaviour that is accepted as part of the software, with scenarios describing the various outcomes of a behaviour. Still valid for the case in hand of integrating the <em>list-item-controller</em>, but I tend to think this closer to testing on the implementation of behaviour. It&#8217;s a gray area to me, as well, if this all sounds confusing &#8211; I invite someone to step in and either clarify my understanding to set me straight. </p>
<p>Basically, our goal here is to verify the design and implementation of <em>list-item-controller</em>. If done properly this will pass, as well as the specs for the <em>Add Item</em> and <em>Mark Off Item</em> features we created in <a href="http://custardbelly.com/blog/2012/11/26/the-making-of-a-test-driven-grocery-list-application-in-js-part-ii/" target="_blank">previous</a> <a href="http://custardbelly.com/blog/2012/12/06/the-making-of-a-test-driven-grocery-list-application-in-js-part-iii/" target="_blank">articles</a>.</p>
<p>That said, let&#8217;s flesh out some tests that verify:</p>
<ol>
<li>Factory generates unique instances of list-item-controller</li>
<li>Model is preserved and immutable on list-item-controller</li>
<li>State is mutable through implicit getter/setters</li>
<li>Change to state is dispatched</li>
</ol>
<p><em>/test/jasmine/spec/list-item-controller.spec.js</em></p>
<pre class="brush: jscript; first-line: 45; title: ;">
describe('Grocery list-item-controller', function() {

  var model,
      newController,
      async = new AsyncSpec(this);

  beforeEach( function() {
    model = modelFactory.create();
    newController = itemControllerFactory.create(parentNode, model);
  });

  describe('list-item-controller factory creation', function() {

    it('should return a new instance of list-item-controller', function() {
      expect(newController).not.toBeUndefined();
    });

    it('should return unique instances of list-item-controllers', function() {
      var nextController = itemControllerFactory.create(parentNode, model);
      nextController.state = 'testing';
      expect(nextController).not.toBe(newController);
      expect(nextController.state).not.toBe(newController.state);
    });

  });

  describe('new list-item-controller instance', function() {

    it('should expose model provided in creation', function() {
      expect(newController.model).not.toBeUndefined();
      expect(newController.model).toBe(model);
    });

    it('should expose non-writable model', function() {
      var newModel = modelFactory.create();
      newController.model = newModel;
      expect(newController.model).not.toBe(newModel);
      expect(newController.model).toBe(model);
    });

  describe('list-item-controller notifies on state-change', function() {

    async.it('should provide old and new state values on state-change', function(done) {
      var previousState = newController.state,
          newState = 'editable';

      $(newController).on('state-change', function(event) {
        $(newController).off('state-change');

        expect(event.oldState).toBe(previousState);
        expect(event.newState).toBe(newState);
        expect(newController.state).toBe(newState);
        done();
      });
      newController.state = newState;
    });

  });

  });

  afterEach( function() {
    model = undefined;
    newController = undefined;
  });

});
</pre>
<p>The last spec declared, as you may notice, runs asynchronously in order to test the state notification:</p>
<pre class="brush: jscript; title: ;">
async.it('should provide old and new state values on state-change', function(done) {
</pre>
<p> The <em>AsyncSpec</em> object comes from the <a href="https://github.com/derickbailey/jasmine.async" target="_blank">jasmine.async library</a> we&#8217;ve previously included in the specrunner page. By invoking the spec (<em>it()</em>) through an instance of <em>AsyncSpec</em>, the spec is suspended until either it fails or the <em>done</em> delegate method is invoked. Since notification of state change is event-based, we use it in the spec to verify that the <em>list-item-controller</em> does dispatch that event.</p>
<p>Add that spec to the list:<br />
<em>/test/jasmine/specrunner.html</em></p>
<pre class="brush: jscript; first-line: 34; highlight: [34]; title: ;">
require( ['spec/newitem.spec.js', 'spec/markitem.spec.js', 'spec/list-item-controller.spec.js'], function() {

  var jasmineEnv = jasmine.getEnv(),
     ...
  jasmineEnv.execute();

});
</pre>
<p><img src="http://custardbelly.com/blog/images/tdd_js/part_iv_1.png" alt="passing list-item-controller spec" /></p>
<h2>list-item-controller implementation</h2>
<p>We&#8217;ve verified our design for the <em>list-item-controller</em> with passing tests, but we have yet to incorporate it into our system and offload the responsibilities (addressed earlier in this article) from the <em>list-controller</em> to it. Before we get there, however, let&#8217;s move the implementation of the <em>list-item-controller</em> (and the factory) out into its own AMD module. To start we&#8217;ll just move the <em>itemControllerFactory</em> declaration into a new file:</p>
<p><em>/script/controller/list-item-controller.js</em></p>
<pre class="brush: jscript; first-line: 1; title: ;">
define(['jquery'], function($) {

  function createStateEvent(oldState, newState) {
    var event = new $.Event('state-change');
    event.oldState = oldState;
    event.newState = newState;
    return event;
  }

  return {
    create: function(node, model) {
      var itemController = Object.create(Object.prototype);

      (function(controller, stateEventCreator) {
        var _state;
        Object.defineProperties(controller, {
          &quot;model&quot;: {
            value: model,
            writable: false,
            enumerable: true
          },
          &quot;parentView&quot;: {
            value: node,
            writable: false,
            enumerable: true
          },
          &quot;state&quot;: {
            set: function(value) {
              var event = stateEventCreator.call(this, this.state, value);
              _state = value;
              $(this).trigger(event);
            },
            get: function() {
              return _state;
            }
          }
        });
      }(itemController, createStateEvent));

      return itemController.init();
    }
  };

});
</pre>
<p>With that in place, we could modify the <em>list-item-controller.spec.js</em> file to include the <em>list-item-controller</em> dependency for testing:</p>
<p><em>/test/jasmine/spec/list-item-controller.spec.js</em></p>
<pre class="brush: jscript; first-line: 1; highlight: [1,2,3]; title: ;">
define(['jquery', 'script/model/grocery-ls-item', 'script/controller/list-item-controller'],
          function($, modelFactory, itemControllerFactory) {
  // moved to script/controller/list-item-controller.js

  describe('Grocery list-item-controller', function() {
    ...
  });
});
</pre>
<p>And our tests still pass! But&#8230; we want to move all the view and item management out of <em>list-controller</em> and have that handled by a <em>list-item-controller</em>. So let&#8217;s transfer over those view fragments and flesh out the <em>list-item-controller</em> object that is generated from the factory:</p>
<p><em>/script/controller/list-item-controller.js</em></p>
<pre class="brush: jscript; first-line: 1; highlight: [10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,34,36,64]; title: ;">
define(['jquery'], function($) {

  function createStateEvent(oldState, newState) {
    var event = new $.Event('state-change');
    event.oldState = oldState;
    event.newState = newState;
    return event;
  }

   var stateEnum = {
        UNEDITABLE: 0,
        EDITABLE: 1
      },
      uneditableItemFragment  = '&lt;p class=&quot;grocery-item&quot; /&gt;',
      editableItemFragment    = '&lt;p class=&quot;editable-grocery-item&quot;&gt;' +
                                                  '&lt;input name=&quot;editableItem&quot; ' +
                                                      'class=&quot;editable-item&quot; placeholder=&quot;Enter item name...&quot;&gt;' +
                                                  '&lt;/input&gt;' +
                                               '&lt;/p&gt;',
      listItemController = {
        $editableView: undefined,
        $uneditableView: undefined,
        init: function() {
          this.$editableView = $(editableItemFragment);
          this.$uneditableView = $(uneditableItemFragment);

          // default to undeditable state.
          this.state = stateEnum.UNEDITABLE;
          return this;
        }
      };

  return {
    state: stateEnum,
    create: function(node, model) {
      var itemController = Object.create(listItemController);

      (function(controller, stateEventCreator) {
        var _state = 'normal';
        Object.defineProperties(controller, {
          &quot;model&quot;: {
            value: model,
            writable: false,
            enumerable: true
          },
          &quot;parentView&quot;: {
            value: node,
            writable: false,
            enumerable: true
          },
          &quot;state&quot;: {
            set: function(value) {
              var event = stateEventCreator.call(this, this.state, value);
              _state = value;
              $(this).trigger(event);
            },
            get: function() {
              return _state;
            }
          }
        });
      }(itemController, createStateEvent));

      return itemController.init();
    }
  };

});
</pre>
<p>The <em>init()</em> method of a new <em>list-item-controller</em> is invoked upon creation and return in order to define the view references and default state. The fragment declarations have changed slightly as well &#8211; the list item wrappers have been removed. Basically, even though the name suggest that the view will reside in a list, we don&#8217;t want to tie the idea that they need to be <em>li</em> DOM elements since they also have no concept of what type of DOM element the <em>parentView</em> is.</p>
<p>As it stands with <a href="https://github.com/bustardcelly/grocery-ls/blob/0.1.3" target="_blank">our current work from the previous article</a>, the <em>list-controller</em> was responsible for listening on UI events of a list item &#8211; such as <em>&#8216;blur&#8217;</em> on input and <em>&#8216;click&#8217;</em>. It is the intent to relive the <em>list-controller</em> of such responsibility so we&#8217;ll transfer that over, as well:</p>
<p><em>/script/controller/list-item-controller.js</em></p>
<pre class="brush: jscript; first-line: 20; highlight: [27,28,29,30,31,32,33,34,35,36,37,38,39]; title: ;">
listItemController = {
  $editableView: undefined,
  $uneditableView: undefined,
  init: function() {
    this.$editableView = $(editableItemFragment);
    this.$uneditableView = $(uneditableItemFragment);

    // view handlers.
    this.$uneditableView.on('click', (function(controller) {
      return function(event) {
        var toggled = controller.$uneditableView.css('text-decoration') === 'line-through';
        controller.model.marked = !toggled;
      };
    }(this)));
    $('input', this.$editableView).on('blur', (function(controller) {
      return function(event) {
        controller.model.name = $(this).val();
        controller.state = stateEnum.UNEDITABLE;
      };
    }(this)));

    // default to undeditable state.
    this.state = stateEnum.UNEDITABLE;
    return this;
  }
};
</pre>
<p>Again, we are using an <strong>IIFE</strong>, and in this case to pass in a reference to the controller instance. I could have easily defined a new variable like</p>
<pre class="brush: jscript; title: ;">
var self = this;
</pre>
<p>but that always makes me cry a little inside. Anyway, so we are listening on click of the uneditable view item in order to update value of the <em>marked</em> property on the model and we have assigned a <em>blur</em> handler on the input of the editable view item that updates the value of the <em>name</em> property of the model and flips the state. Now we have to respond to those changes <img src='http://darko.liquidweb.com/~custardb/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><em>/script/controller/list-item-controller.js</em></p>
<pre class="brush: jscript; first-line: 23; highlight: [41,42,43,44,45,46,47,48,49,50]; title: ;">
init: function() {
  this.$editableView = $(editableItemFragment);
  this.$uneditableView = $(uneditableItemFragment);

  // view handlers.
  this.$uneditableView.on('click', (function(controller) {
    return function(event) {
      var toggled = controller.$uneditableView.css('text-decoration') === 'line-through';
      controller.model.marked = !toggled;
    };
  }(this)));
  $('input', this.$editableView).on('blur', (function(controller) {
    return function(event) {
      controller.model.name = $(this).val();
      controller.state = stateEnum.UNEDITABLE;
    };
  }(this)));
  // state &amp; model handlers.
  $(this).on('state-change',  (function(controller) {
    return function(event) {
      handleStateChange.call(null, controller, event);
    };
  }(this)));
  $(this.model).on('property-change', (function(controller) {
    return function(event) {
      handlePropertyChange.call(null, controller, event);
    };
  }(this)));
  // default to undeditable state.
  this.state = stateEnum.UNEDITABLE;
  return this;
}
</pre>
<p>The <em>handleStateChange</em> delegate is responsible for updating the view based on a change to state: either <em>EDITABLE</em> or <em>UNEDITABLE</em> from the <em>stateEnum</em> object:</p>
<pre class="brush: jscript; title: ;">
function handleStateChange(controller, event) {
  // remove state-based item.
  if( typeof event.oldState !== 'undefined') {
    if(event.oldState === stateEnum.UNEDITABLE) {
      controller.$uneditableView.detach();
    }
    else if(event.oldState === stateEnum.EDITABLE) {
      controller.$editableView.detach();
    }
  }
  // append state-based item.
  if(event.newState === stateEnum.UNEDITABLE) {
    controller.parentView.append(controller.$uneditableView);
  }
  else if(event.newState === stateEnum.EDITABLE) {
    var inputTimeout = setTimeout( function()  {
      clearTimeout(inputTimeout);
      $('input', controller.$editableView).focus();
    }, 100);
    controller.parentView.append(controller.$editableView);
  }
}
</pre>
<p>The <em>handlePropertyChange</em> delegate is responsible for updating the views based on the <em>model</em> property values:</p>
<pre class="brush: jscript; title: ;">
function handlePropertyChange(controller, event) {
  if(event.property === &quot;name&quot;) {
    // update view based on model change.
    $('input', controller.$editableView).val(controller.model.name);
    controller.$uneditableView.text(event.newValue);
  }
  else if(event.property === &quot;marked&quot;) {
    // update view based on model change.
    controller.$uneditableView.css('text-decoration', (event.newValue) ? 'line-through' : 'none');
  }
}
</pre>
<p>That pretty much shores up the implementation for the <em>list-item-controller</em> taking on the responsibilities of view creation and management based on state and model updates. But running the tests from this point will fail. The reason being a change to design on the model.</p>
<h2>grocery-ls-item Modification</h2>
<p>One particular change to design introduced in the implementation for <em>list-item-controller</em> is response to <em>&#8216;property-change&#8217;</em> event from the model. In our work up to this point, the <em>grocery-ls-item</em> is a basic object; we&#8217;ll use the same paradigm that we implemented for notification of state for the <em>grocery-ls-item</em> in order to respond to changes on model properties. Although a simple change, we need to first test our design before modifying the code for the <em>grocery-ls-item</em>. Lets create a new spec file for our model:</p>
<p><em>/test/jasmine/spec/grocery-ls-item.spec.js</em></p>
<pre class="brush: jscript; first-line: 1; title: ;">
define(['jquery', 'script/model/grocery-ls-item'], function($, modelFactory) {

  describe('Grocery grocery-ls-item model', function() {

    var model,
        name = 'grapes',
        async = new AsyncSpec(this);

    beforeEach( function() {
      model = modelFactory.create();
      model.name = name;
      model.marked = false;
    });

    describe('grocery-ls-item factory model creation', function() {

      it('should generate unique instances of model', function() {
        var newModel = modelFactory.create();
        expect(model).not.toBeUndefined();
        expect(newModel).not.toBeUndefined();
        expect(model).not.toBe(newModel);
      });

      async.it('should auto generate unique ids on models', function(done) {
        var newModel,
            creationTimeout;

        // Offload creation because ids are generated based on time.
        // This allows for timestamp to progess.
        creationTimeout = setTimeout(function() {
          clearTimeout(creationTimeout);
          newModel = modelFactory.create();
          expect(model.id).not.toBeUndefined();
          expect(typeof model.id).toBe('number');
          expect(model.id).not.toEqual(newModel.id);
          done();
        }, 100);
      });

    });

    describe('grocery-ls-item properties', function() {

      it('should contain an immutable id property, created at instantiation', function() {
        var newID = 1234567;
        model.id = newID;

        expect(model.id).not.toEqual(newID);
      });

    });

    describe('grocery-ls-item property change notification', function() {

      async.it('should notify with \'property-change\' upon change to name property', function(done) {
        var oldName = model.name,
            newName = 'apples';
        $(model).on('property-change', function(event) {
          expect(event.property).toEqual('name');
          expect(event.oldValue).toEqual(oldName);
          expect(event.newValue).toEqual(newName);
          $(model).off('property-change');
          done();
        });
        model.name = newName;
      });

      async.it('should notify with \'property-change\' upon change to marked property', function(done) {
        var oldValue = model.marked,
            newValue = true;
        $(model).on('property-change', function(event) {
          expect(event.property).toEqual('marked');
          expect(event.oldValue).toEqual(oldValue);
          expect(event.newValue).toEqual(newValue);
          $(model).off('property-change');
          done();
        });
        model.marked = newValue;
      });

    });

    afterEach( function() {
      model = undefined;
    });

  });

});
</pre>
<p>We have a few suites there to verify:</p>
<ol>
<li>Model generation from factory produces unique items</li>
<li>Model property immutability for auto-assigned IDs</li>
<li>Event notification on property change</li>
</ol>
<p>We add that to our spec runner:</p>
<pre class="brush: jscript; first-line: 34; highlight: [34,35]; title: ;">
require( ['spec/newitem.spec.js', 'spec/markitem.spec.js',
          'spec/item-controller.spec.js', 'spec/grocery-ls-item.spec.js'], function() {

  var jasmineEnv = jasmine.getEnv(),
     ...
  jasmineEnv.execute();

});
</pre>
<p>&#8230; and it fails. Whoopee! It&#8217;s supposed to. Now we just take the knowledge we know of wiring up event notification on state of the <em>list-item-controller</em>, and apply it to <em>property-change</em> on the model:</p>
<p><em>/script/model/grocery-ls-item.js</em></p>
<pre class="brush: jscript; first-line: 1; highlight: [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42]; title: ;">
define(['jquery'], function($) {

  var propertyEvent = {
      create: function(property, oldValue, newValue) {
        var event = $.Event('property-change');
        event.property = property;
        event.oldValue = oldValue;
        event.newValue = newValue;
        return event;
      }
    },
    properties = function(id) {
      return {
        &quot;id&quot;: {
          value: id,
          writable: false,
          enumerable: true
        },
        &quot;name&quot;: {
          enumerable: true,
          set: function(value) {
            var oldValue = this._name;
            this._name = value;
            $(this).trigger(propertyEvent.create('name', oldValue, value));
          },
          get: function() {
            return this._name;
          }
        },
        &quot;marked&quot;: {
          enumerable: true,
          set: function(value) {
            var oldValue = this._marked;
            this._marked = value;
            $(this).trigger(propertyEvent.create('marked', oldValue, value));
          },
          get: function() {
            return this._marked;
          }
        }
      };
    };

  return {
    create: function() {
      return Object.create(Object.prototype, properties(new Date().getTime()));
    }
  };

});
</pre>
<p>The modification to <em>grocery-ls-item</em> was perhaps our first introduction to writing failing tests due to a change in design prior to actually modifying the implementation. That feeling you&#8217;re feeling right now&#8230; that&#8217;s what makes this all worth it <img src='http://darko.liquidweb.com/~custardb/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Anyway&#8230; hold on to that feeling until the next post, because we are not done and it will go away quickly&#8230; just kidding <img src='http://darko.liquidweb.com/~custardb/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><strong>Tagged</strong>: 0.1.5 <a href="https://github.com/bustardcelly/grocery-ls/tree/0.1.5">https://github.com/bustardcelly/grocery-ls/tree/0.1.5</a></p>
<h2>Blinders</h2>
<p>If you were to run the tests again&#8230; they still pass!<br />
<img src="http://custardbelly.com/blog/images/tdd_js/part_iv_2.png" alt="passing grocery-ls-item spec" /></p>
<p>That is because we have not changed <em>list-controller</em> at all <img src='http://darko.liquidweb.com/~custardb/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  </p>
<p>Our <em>list-item-controller.spec.js</em> is happily oblivious to our recent additions and modifications, and the tests we wrote previously for the <em>Add Item</em> and <em>Mark Off Item</em> features still pass. </p>
<p>Before we just start chopping out and inserting code from <em>list-controller</em>, I want to go over the API and specs currently defined and see if they still hold water &#8211; meaning we might be able to cut some tests out. We might not. We might even add more&#8230; That&#8217;s what i plan to address in the next article of this series.</p>
<p>&#8212;</p>
<h1>Link Dump</h1>
<h2>Reference</h2>
<p><a href="http://tddjs.com/" target="_blank">Test-Driven JavaScript Development by Christian Johansen</a><br />
<a href="http://dannorth.net/introducing-bdd/" target="_blank">Introducing BDD by Dan North</a><br />
<a href="http://benalman.com/news/2010/11/immediately-invoked-function-expression/">Immediately-Invoked Function Expression (IIFE) by Ben Alman</a><br />
<a href="http://requirejs.org/" target="_blank">RequireJS</a><br />
<a href="https://github.com/amdjs/amdjs-api/wiki/AMD" target="_blank">AMD</a><br />
<a href="http://pivotal.github.com/jasmine/" target="_blank">Jasmine</a><br />
<a href="http://sinonjs.org/" target="_blank">Sinon</a><br />
<a href="https://github.com/derickbailey/jasmine.async" target="_blank">Jasmine.Async</a></p>
<h2>Post Series</h2>
<p><a href="https://github.com/bustardcelly/grocery-ls">grocery-ls github repo</a><br />
<a href="http://custardbelly.com/blog/2012/11/26/the-making-of-a-test-driven-grocery-list-application-in-javascript-part-i" target="_blank">Part I &#8211; Introduction</a><br />
<a href="http://custardbelly.com/blog/2012/11/26/the-making-of-a-test-driven-grocery-list-application-in-js-part-ii">Part II &#8211; Feature: Add Item</a><br />
<a href="http://custardbelly.com/blog/2012/12/06/the-making-of-a-test-driven-grocery-list-application-in-js-part-iii">Part III &#8211; Feature: Mark-Off Item</a><br />
<a href="http://custardbelly.com/blog/2012/12/17/the-making-of-a-test-driven-grocery-list-application-in-js-part-iv">Part IV &#8211; Feature: List-Item-Controller</a><br />
<a href="http://custardbelly.com/blog/2012/12/31/the-making-of-a-test-driven-grocery-list-application-in-js-part-v/">Part V &#8211; Feature: List-Controller Refactoring</a><br />
<a href="http://custardbelly.com/blog/2013/01/08/the-making-of-a-test-driven-grocery-list-application-in-js-part-vi/" target="_blank">Part VI &#8211; Back to Passing</a><br />
<a href="http://custardbelly.com/blog/2013/01/17/the-making-of-a-test-driven-grocery-list-application-in-js-part-vii/">Part VII &#8211; Remove Item</a><br />
<a href="http://custardbelly.com/blog/2013/01/22/the-making-of-a-test-driven-grocery-list-application-part-viii/">Part VIII &#8211; Bug Fixing</a><br />
<a href="http://custardbelly.com/blog/2013/02/15/the-making-of-a-test-driven-grocery-list-application-in-js-part-ix/">Part IX &#8211; Persistence</a><br />
<a href="http://custardbelly.com/blog/2013/03/06/the-making-of-a-test-driven-grocery-list-application-in-js-part-x/">Part X &#8211; It Lives!</a></p>
]]></content:encoded>
			<wfw:commentRss>http://custardbelly.com/blog/2012/12/17/the-making-of-a-test-driven-grocery-list-application-in-js-part-iv/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Making of a Test-Driven Grocery List Application in JS: Part III</title>
		<link>http://custardbelly.com/blog/2012/12/06/the-making-of-a-test-driven-grocery-list-application-in-js-part-iii/</link>
		<comments>http://custardbelly.com/blog/2012/12/06/the-making-of-a-test-driven-grocery-list-application-in-js-part-iii/#comments</comments>
		<pubDate>Thu, 06 Dec 2012 18:19:19 +0000</pubDate>
		<dc:creator>todd anderson</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[RequireJS]]></category>
		<category><![CDATA[grocery-ls]]></category>
		<category><![CDATA[jasmine]]></category>
		<category><![CDATA[unit-testing]]></category>

		<guid isPermaLink="false">http://custardbelly.com/blog/?p=636</guid>
		<description><![CDATA[This is the third installment in a series of building a Test-Driven Grocery List application using Jasmine and RequireJS. To learn more about the intent and general concept of the series please visit The Making of a Test-Driven Grocery List Application in JavaScript: Part I
&#8212;
Introduction
In the previous article, I addressed adding the first feature to [...]]]></description>
			<content:encoded><![CDATA[<p><em>This is the third installment in a series of building a Test-Driven Grocery List application using <a href="http://pivotal.github.com/jasmine/" target="_blank">Jasmine</a> and <a href="http://requirejs.org" target="_blank">RequireJS</a>. To learn more about the intent and general concept of the series please visit <a href="http://custardbelly.com/blog/2012/11/26/the-making-of-a-test-driven-grocery-list-application-in-javascript-part-i/">The Making of a Test-Driven Grocery List Application in JavaScript: Part I</a></em><br />
&#8212;</p>
<h1>Introduction</h1>
<p>In the <a href="http://custardbelly.com/blog/2012/11/26/the-making-of-a-test-driven-grocery-list-application-in-js-part-ii/">previous article</a>, I addressed adding the first feature to the <strong>Grocery List</strong> application: <em>Add Item</em>. Trying my best to adhere to the TDD/BDD philosophy, a story and a couple scenarios were drummed up prior to implementation development using language similar to that described in <a href="http://dannorth.net/introducing-bdd/" target="_blank">Dan Worth’s Introducing BDD article</a>. Once passing, the code written within the test was moved to its own file(s) with dependencies updated in the specs and tests run again to confirm passing against the implementations.</p>
<p>I will take the same approach in adding a new feature in this article: <em>Mark-Off Item</em>. </p>
<p>I suspect, however, that I may actually end up creating stories for more of what can be considered <em>integration</em>. Since the last post, I stumbled upon a <a href="http://chrismdp.com" target="_blank">great blog from Chris Parsons</a> that covers BDD (with a bend toward Cucumber), and in particular the article <a href="http://chrismdp.com/2012/11/the-integration-testing-trap/" target="_blank">Cucumber: the integration test trap</a> provided some great insight into the difference between acceptance and integration testing. In the previous article, I suppose more of what was done could be considered acceptance testing. Some implementation details are testing against in the <em>Add-Item</em> feature (for instance, the item API on the list-controller), but I sort of threw in extra code and UX/UI implementation details at the end just so I could make sure the code was actually usable in a real-life scenario. At the time, I felt that writing specs for the integration of features &#8211; what i consider more fine-grained in testing that an element is added to the DOM upon an API call &#8211; would muddle down the intent of this series. I might take back that assumption. That may lead to longer posts&#8230; you have been forewarned <img src='http://darko.liquidweb.com/~custardb/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h1>Mark-Off Feature</h1>
<p>There are basically 3 states to an item in the grocery store: </p>
<ol>
<li>unpossessed</li>
<li>unpurchased</li>
<li>owned</li>
</ol>
<p>Once owned&#8230; well it either gets eaten or is freed into the wild &#8211; through those seemingly impenetrable automatic doors of unpurchased state, into the world of natural lighting. As well, prior to own-ed-ship, the item is in limbo as to whether or not it can reach that state &#8211; it might be placed back on the shelf to be forever unpossessed again. (You don&#8217;t want me to go over the possessed state.) Not unlike the life a a loaf of bread in a store, so too are the states of the grocery list items of the <strong>Grocery List</strong> application.</p>
<p>By adding an item &#8211; the feature completed in the <a href="http://custardbelly.com/blog/2012/11/26/the-making-of-a-test-driven-grocery-list-application-in-javascript-part-i/">previous article</a> &#8211; a User has essentially identified an item not in possession, with the end goal of being owned. As a User of the application, we want to be able to denote the item as being in possession, but not purchased. The unpurchased state will notify other Users of the list that it no longer needs to be obtained. However, it will still be allowed to be unmarked and back to unpossessed &#8211; say if someone got <strong>Miracle Whip</strong> mayo instead of <strong>Helmann&#8217;s</strong> (whole &#8216;nother argument).</p>
<p>So we have essentially defined the feature for this post in the series: being able to mark and unmark an item added to the grocery list.</p>
<p><em>// story</em><br />
&#8212;<br />
<strong>Story:</strong> Item is marked off on grocery list</p>
<p><strong>In order to</strong> remember what items have already made it to the cart<br />
<strong>As a</strong> grocery shopper<br />
<strong>I want to</strong> mark an item as being attained on the grocery list.<br />
&#8212;</p>
<p>Similarly, since the item will still be available from the <strong>Grocer List</strong> application and only considered marked off, we could write up another story of being able to unmark an item from the list. For brevity&#8217;s sake, I should probably do that and if we were actually incorporating DSLs and tools that would facilitate in BDD testing, I probably would. But for the sake of this article, we&#8217;ll leave that as an added scenario to this feature.</p>
<p><em>// spec</em><br />
&#8212;<br />
<strong>Scenario 1:</strong> Item is marked off on grocery list<br />
<strong>Given</strong> a user has saved an item to the list<br />
<strong>When</strong> she requests to mark off the item<br />
<strong>Then</strong> the item is presented differently to the user, denoting in possession<br />
<strong>And</strong> the item is not removed from the list<br />
&#8212;</p>
<p>Okay. I&#8217;ll admit. The desired outcome from that scenario is a little vague. But the scenarios I am writing &#8211; as discussed before, after having read <a href="http://chrismdp.com/2012/11/the-integration-testing-trap/" target="_blank">this article from Chris Parsons</a> &#8211; are more loosely acceptance criteria. As a developer, it makes me squirm a little because I know there is much more that can be described in this scenario, especially as it pertains to UI and UX. Aspects such as those can be considered more as integration points and I may circle back for more scenarios involving more of what we, as developers, are affirming in our tests (ie, design and functionality).</p>
<p>Anyway, undoing as well:</p>
<p><em>// spec</em><br />
&#8212;<br />
<strong>Scenario 2:</strong> Item is un-marked off on grocery list<br />
<strong>Given</strong> a user has saved an item to the list<br />
<strong>And</strong> she has marked off an item<br />
<strong>When</strong> she requests to un-mark off the item<br />
<strong>Then</strong> the item is presented to the user as not being in possession<br />
<strong>And</strong> the item is not removed from the list<br />
&#8212;</p>
<p>Basically, we are defining an item of the <strong>Grocery List</strong> application as a toggle control. Now, I can sum that up in a tiny single sentence and wave my hand, but I think we will find that there is a lot more to that statement as we start writing our tests and ultimately will change the design of the application &#8211; fo the better, I hope!</p>
<h2>Test</h2>
<p>To start, the story in question and described above adds to the API of the <em>list-controller</em> we defined and created in the <a href="http://custardbelly.com/blog/2012/11/26/the-making-of-a-test-driven-grocery-list-application-in-js-part-ii" target="_blank">previous article</a>. The <em>list-controller</em> will need to expose a way to mark off an item that is saved to the list, and a way to unmark an item that was previously marked. As I see it, that&#8217;s two new methods &#8211; let&#8217;s call them <em>markOffItem</em> and <em>unmarkOffItem</em>. Let&#8217;s flesh them out and their signatures in a new spec for this feature:</p>
<p><em>/test/jasmine/spec/markitem.spec.js</em></p>
<pre class="brush: jscript; first-line: 1; title: ;">
define(['script/controller/list-controller'], function(listController) {

  describe('User Requests to mark-off existing item', function() {

    var name = 'apples',
        savedItem,
        markOffSpy,
        unmarkOffSpy;

    beforeEach( function() {
      listController.createNewItem();
      listController.editFocusedItem(name);
      listController.saveFocusedItem();

      savedItem = listController.itemList[listController.itemList.length-1];

      markOffSpy = spyOn(listController, &quot;markOffItem&quot;).andCallThrough();
      unmarkOffSpy = spyOn(listController, &quot;unmarkOffItem&quot;).andCallThrough();
    });

    ...

    afterEach( function() {
      savedItem = undefined;
      markOffSpy.reset();
      unmarkOffSpy.reset();
      listController.itemList = [];
      listController.editableItem = undefined;
    });

  });

});
</pre>
<p>I wanted to start off this test example with just showing to setup and teardown for the feature as it introduces the concept of spies. The <em>beforeEach()</em> of the above specification suite starts off similarly to the other spec we created for the <em>Add Item</em> feature &#8211; create, edit and save an item on the <em>list-controller</em>. Following that, and specifically on line 17 and 18, we create spies for the API modifications we are making on the <em>list-controller</em> in order to add the <em>Mark Off Item</em> feature &#8211; <em>markOffItem()</em> and <em>unmarkOffItem()</em>. Spies, in as far as they are used in this instance, are essentially wrappers on a function that can record invocation calls and provide another API to facilitate in affirming expectations of how a method should be used. If you are unfamiliar with spies, both <a href="https://github.com/pivotal/jasmine/wiki/Spies" target="_blank">Jasmine</a> and <a href="http://sinonjs.org/docs/#spies" target="_blank">Sinon</a> have some great documentation.</p>
<p>The spies are defined to &#8220;call through&#8221; to the function implementation on the <em>list-controller</em>, as well. This will allow for the benefit of recording invocation and defining expectations of the actual implementation. Before we get into the real implementation, let&#8217;s take a look at the first spec for this test &#8211; marking off an item:</p>
<p><em>/test/jasmine/spec/markitem.spec.js</em></p>
<pre class="brush: jscript; first-line: 21; title: ;">
    it('should denote item as being in possession', function() {
      var previouslySavedItem = savedItem,
          savedItemID = savedItem.id,
          savedItemSpy = sinon.spy();

      savedItemSpy(previouslySavedItem);
      listController.markOffItem(savedItemID);

      // spy expectations.
      expect(markOffSpy).toHaveBeenCalled();
      expect(markOffSpy).toHaveBeenCalledWith(savedItemID);

      // model expectations.
      expect(previouslySavedItem.hasOwnProperty('marked')).toBe(true);
      expect(previouslySavedItem.marked).toBe(true);
      // OR &gt;
      sinon.assert.calledWith(savedItemSpy, sinon.match.hasOwn('marked', true));
    });
</pre>
<p>With this spec, we are affirming the signature of <em>markOffItem()</em> method on the <em>list-controller</em>, as well as revealing the need for modifications to the attributes on the model of a grocery list item. I wanted to highlight how the <em>markOffSpy()</em> is being used in expectations, and &#8211; though not technically needed &#8211; also maybe provide some intrigue (hopefully not confusion) in using spies from <a href="http://sinonjs.org" target="_blank">SinonJS</a> as well.</p>
<p>The following expectations, taken from the above spec, facilitate more in describing how <em>listController.markOffItem()</em> is to be used in the application, particularly that the method should be called with only one argument and that being an ID of an item from the list :</p>
<pre class="brush: jscript; first-line: 30; title: ;">
  expect(markOffSpy).toHaveBeenCalled();
  expect(markOffSpy).toHaveBeenCalledWith(savedItemID);
</pre>
<p>Some may say that such expectations are superfluous, and in some ways I do agree. Essentially, this line already defines its usage:</p>
<pre class="brush: jscript; first-line: 27; title: ;">
  listController.markOffItem(savedItemID);
</pre>
<p>If the test didn&#8217;t cough at that line, that we can relatively assume the expectations called into question. To each his own, however. In fact, part of me thinks I should go <em>even more</em> overboard &#8211; ensuring only one argument was called, that it was of the same type as the id attribute on the model, etc. Anyway, after the expectations on the spy, we verify an update to the model on an attribute we have yet to define as well. From this test, we have defined it as being a boolean value and accessible on the <em>marked</em> property. I included a spy created using <a href="http://sinonjs.org" target="_blank">SinonJS</a> as well, just to show off it&#8217;s capabilities and compare and contrast testing on the new attribute of the model:</p>
<pre class="brush: jscript; title: ;">
var previouslySavedItem = savedItem,
      savedItemSpy = sinon.spy();
savedItemSpy(previouslySavedItem);
...
sinon.assert.calledWith(savedItemSpy, sinon.match.hasOwn('marked', true));
</pre>
<p>A spy is created on the model object, and after marking it off through the <em>list-controller</em> API, it is verified as being of type boolean and value of true using a sinon assert. Neat stuff. In this case, I probably would have just stuck with the <strong>Jasmine</strong> expectations, but I wanted to show you the power of <strong>SinonJS</strong> as it can provide a more robust testing API.</p>
<p>Rambling on. There&#8217;s still two other specifications we need to cover in this suite:</p>
<p><em>/test/jasmine/spec/markitem.spec.js</em></p>
<pre class="brush: jscript; first-line: 40; title: ;">
    it('should retain the item in the grocery list', function() {
      listController.markOffItem(savedItem.id);

      expect(listController.itemList.length).toBe(1);
      expect(listController.itemList.indexOf(savedItem)).toBe(0);
    });

    it('should have marked-off item available to unmark-off', function() {
      var previouslySavedItem = savedItem,
          savedItemID = savedItem.id;

      listController.markOffItem(savedItem.id);
      listController.unmarkOffItem(savedItem.id);

      // stubbed expectations.
      expect(unmarkOffSpy).toHaveBeenCalled();
      // model expectations.
      expect(previouslySavedItem.marked).not.toBe(true);
    });
</pre>
<p>These specs define the expectations of the list remaining unmodified when marking off an item, and that the model is updated appropriately when unmarking off an item through the <em>list-controller</em> API, respectively. </p>
<p><small><br />
[note]<br />
<em>I am using Array.prototype.indexOf in the first spec from the previous example. That didn&#8217;t make <a href="https://developer.mozilla.org/en-US/docs/JavaScript/New_in_JavaScript/1.6" target="_blank">an appearance until JavaScript 1.6</a> and as such is not implemented in some older browsers (i have no &lt;3 for IE&lt;9). As I mentioned in the first article of this series, I am taking for granted that the application will be viewed on modern browsers, and in particular modern mobile browsers.</em><br />
</small></p>
<h3>Failing</h3>
<p>If you added this spec to the spec runner like so:</p>
<p><em>/test/jasmine/specrunner.html</em></p>
<pre class="brush: jscript; first-line: 34; highlight: [34]; title: ;">
require( ['spec/newitem.spec.js', 'spec/markitem.spec.js'], function() {
  var jasmineEnv = jasmine.getEnv(),
       ...
  jasmineEnv.execute();
});
</pre>
<p>&gt; it will fail. miserably. But that&#8217;s okay! That&#8217;s expected. Spies require an actual implementation on the object you are spying, and if you recall from the first spec described, we actually request a call through on the implementation in order to verify expected functionality. </p>
<p>Let&#8217;s get to the <em>list-controller</em> and <em>grocery-ls-item</em> model, as those are the two items addressed in the latest spec suite as needing modifications to pass.</p>
<h2>Implementation</h2>
<p>In our Mark Off Item spec suite, we identified two additions to the API of the list-controller. Those methods are:</p>
<ul>
<li>+ markOffItem( itemID )</li>
<li>+ unmarkOffItem( itemID )</li>
</ul>
<p>The first instinct is to just add these to the <em>list-controller</em> object and add an internal method that traverses the held <em>itemList</em> array to locate models that have the passed <em>itemID</em> value. Not a bad instinct, and something of the following would get the tests passing:</p>
<p><em>/script/controller/list-controller.js</em></p>
<pre class="brush: jscript; first-line: 64; title: ;">
markOffItem: function(itemID) {
  var item = findItemByID(itemID, this.itemList),
        renderer = findRendererByItem(item, $itemList.children());
  item.marked = true;
  $(renderer).css('text-decoration', 'line-through');
},
unmarkOffItem: function(itemID) {
  var item = findItemByID(itemID, this.itemList),
        renderer = findRendererByItem(item, $itemList.children());
  item.marked = false;
  $(renderer).css('text-decoration', 'none');
}
</pre>
<p><em>&gt; where findByItemID() locates the model associated with the itemID within the itemList array and findRendererByItem() locates the DOM element associated with the model.</em></p>
<p>If you were to run that, the tests would pass. Well, technically, if you left that bit in there where a <a href="http://sinonjs.org" target="_blank">SinonJS</a> spy was asserting on the model, it would not pass. But if you took that out, all green. Even without modifying the <em>grocery-ls-item</em> model&#8230; such is the dynamic nature of JavaScript. For brevities sake, let&#8217;s add the marked property to the Object.defineProperties object upon creation of a new model:</p>
<p><em>/script/model/grocery-ls-item.js</em></p>
<pre class="brush: jscript; first-line: 3; highlight: [15,16,17,18,19]; title: ;">
var properties = function(id) {
    return {
      &quot;id&quot;: {
        value: id,
        writable: false,
        enumerable: true
      },
      &quot;name&quot;: {
        value: '',
        writable: true,
        enumerable: true
      },
      &quot;marked&quot;: {
        value: false,
        writable: true,
        enumerable: true
      }
    };
  };
</pre>
<p><img src="http://custardbelly.com/blog/images/tdd_js/part_iii_1.png" alt="passing mark-off item spec" /><br />
<img src="http://custardbelly.com/blog/images/tdd_js/part_iii_app_1.png" alt="grocery list app with mark off" /></p>
<p><strong>Tagged</strong>: 0.1.3 <a href="https://github.com/bustardcelly/grocery-ls/tree/0.1.3" target="_blank">https://github.com/bustardcelly/grocery-ls/tree/0.1.3</a></p>
<h2>Before you leave!</h2>
<p>I am not satisfied with the current state of the <em>list-controller</em>; it has far too much responsibility in managing list item renderers and models and lacks the finer details to properly keep the 1:1 relationship that renderers have to their models. We could just throw more code in there, more tests and let it grow into this gross beast, but I really think it is up for a good refactor.</p>
<p>So, that is what I have planned for the next article. We&#8217;ll refactor the <em>list-controller</em> to have less responsibility in managing each <em>grocery-ls-item</em> model and pass that off to a new <em>list-item-controller</em>. In fact, I already have started upon such a refactor and had included most of it in this article, but I felt it was getting too long (as usual) and taking away from the <em>Mark Off Item</em> feature presented here.</p>
<p>Until then, you have passing tests and a functioning <strong>Grocery List</strong> application to play with if you <a href="https://github.com/bustardcelly/grocery-ls" target="_blank">check it out of the repo</a>.</p>
<p>&#8212;</p>
<h1>Link Dump</h1>
<h2>Post Series</h2>
<p><a href="https://github.com/bustardcelly/grocery-ls">grocery-ls github repo</a><br />
<a href="http://custardbelly.com/blog/2012/11/26/the-making-of-a-test-driven-grocery-list-application-in-javascript-part-i" target="_blank">Part I &#8211; Introduction</a><br />
<a href="http://custardbelly.com/blog/2012/11/26/the-making-of-a-test-driven-grocery-list-application-in-js-part-ii">Part II &#8211; Feature: Add Item</a><br />
<a href="http://custardbelly.com/blog/2012/12/06/the-making-of-a-test-driven-grocery-list-application-in-js-part-iii">Part III &#8211; Feature: Mark-Off Item</a><br />
<a href="http://custardbelly.com/blog/2012/12/17/the-making-of-a-test-driven-grocery-list-application-in-js-part-iv">Part IV &#8211; Feature: List-Item-Controller</a><br />
<a href="http://custardbelly.com/blog/2012/12/31/the-making-of-a-test-driven-grocery-list-application-in-js-part-v/">Part V &#8211; Feature: List-Controller Refactoring</a><br />
<a href="http://custardbelly.com/blog/2013/01/08/the-making-of-a-test-driven-grocery-list-application-in-js-part-vi/" target="_blank">Part VI &#8211; Back to Passing</a><br />
<a href="http://custardbelly.com/blog/2013/01/17/the-making-of-a-test-driven-grocery-list-application-in-js-part-vii/">Part VII &#8211; Remove Item</a><br />
<a href="http://custardbelly.com/blog/2013/01/22/the-making-of-a-test-driven-grocery-list-application-part-viii/">Part VIII &#8211; Bug Fixing</a><br />
<a href="http://custardbelly.com/blog/2013/02/15/the-making-of-a-test-driven-grocery-list-application-in-js-part-ix/">Part IX &#8211; Persistence</a><br />
<a href="http://custardbelly.com/blog/2013/03/06/the-making-of-a-test-driven-grocery-list-application-in-js-part-x/">Part X &#8211; It Lives!</a></p>
<h2>Reference</h2>
<p><a href="http://tddjs.com/" target="_blank">Test-Driven JavaScript Development by Christian Johansen</a><br />
<a href="http://dannorth.net/introducing-bdd/" target="_blank">Introducing BDD by Dan North</a><br />
<a href="http://chrismdp.com/2012/11/the-integration-testing-trap/" target="_blank">Cucumber: the integration test trap by Crhis Parsons</a><br />
Testing spies for <a href="https://github.com/pivotal/jasmine/wiki/Spies">Jasmine</a> and <a href="http://sinonjs.org/docs/#spies">Sinon</a><br />
<a href="http://requirejs.org/" target="_blank">RequireJS</a><br />
<a href="https://github.com/amdjs/amdjs-api/wiki/AMD" target="_blank">AMD</a><br />
<a href="http://pivotal.github.com/jasmine/" target="_blank">Jasmine</a><br />
<a href="http://sinonjs.org/" target="_blank">Sinon</a><br />
<a href="https://github.com/derickbailey/jasmine.async" target="_blank">Jasmine.Async</a><br />
the <a href="http://www.flickr.com/photos/unitzeroone/4721521533/">infamous</a> <a href="http://bit-101.com">eye-roller</a> </p>
]]></content:encoded>
			<wfw:commentRss>http://custardbelly.com/blog/2012/12/06/the-making-of-a-test-driven-grocery-list-application-in-js-part-iii/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Making of a Test-Driven Grocery List Application in JS: Part II</title>
		<link>http://custardbelly.com/blog/2012/11/26/the-making-of-a-test-driven-grocery-list-application-in-js-part-ii/</link>
		<comments>http://custardbelly.com/blog/2012/11/26/the-making-of-a-test-driven-grocery-list-application-in-js-part-ii/#comments</comments>
		<pubDate>Mon, 26 Nov 2012 11:01:23 +0000</pubDate>
		<dc:creator>todd anderson</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[grocery-ls]]></category>
		<category><![CDATA[jasmine]]></category>
		<category><![CDATA[unit-testing]]></category>

		<guid isPermaLink="false">http://custardbelly.com/blog/?p=601</guid>
		<description><![CDATA[This is the second installment in a series of building a Test-Driven Grocery List application using Jasmine and RequireJS. To learn more about the intent and general concept of the series please visit The Making of a Test-Driven Grocery List Application in JavaScript: Part I
&#8212;
Introduction
In the previous article, I covered the intent of developing a [...]]]></description>
			<content:encoded><![CDATA[<p><em>This is the second installment in a series of building a Test-Driven Grocery List application using <a href="http://pivotal.github.com/jasmine/" target="_blank">Jasmine</a> and <a href="http://requirejs.org" target="_blank">RequireJS</a>. To learn more about the intent and general concept of the series please visit <a href="http://custardbelly.com/blog/2012/11/26/the-making-of-a-test-driven-grocery-list-application-in-javascript-part-i/">The Making of a Test-Driven Grocery List Application in JavaScript: Part I</a></em><br />
&#8212;</p>
<h1>Introduction</h1>
<p>In the <a href="http://custardbelly.com/blog/2012/11/26/the-making-of-a-test-driven-grocery-list-application-in-javascript-part-i" target="_blank">previous article</a>, I covered the intent of developing a Test-Driven <strong>Grocery List</strong> application using <a href="http://pivotal.github.com/jasmine/" target="_blank">Jasmine</a>, the <a href="http://dannorth.net/introducing-bdd/" target="_blank">BDD</a> testing framework for JavaScript.</p>
<p>In this article, I want to address a single <a href="http://en.wikipedia.org/wiki/User_story" target="_blank">User Story</a> with a couple scenarios, using language similar to that describe in <a href="http://dannorth.net/introducing-bdd/">Dan Worth&#8217;s <em>Introducing BDD</em> article</a>, that will describe the specifications and expectations of one piece of the <strong>Grocery List</strong> application: adding an item.</p>
<h1>Requirements</h1>
<p>Instead of starting with code and project setup, let&#8217;s take a bite off the requirements of the <strong>Grocery List</strong> application and discuss a single usability point to start with.</p>
<p>The intended use of the <strong>Grocery List</strong> application is to be able to add, check-off and delete items from a list. We&#8217;ll address the difference of checking-off items vs. deleting items in later posts, so for now we&#8217;ll be concerned with only adding an item. Let&#8217;s start with a simple story:</p>
<p><em>// story</em><br />
&#8212;<br />
<strong>Story:</strong> Item is added to grocery list</p>
<p><strong>In order to</strong> remember what to pick up at the grocery store<br />
<strong>As a</strong> grocery shopper<br />
<strong>I want to</strong> add an item to a grocery list accessible when at the store.<br />
&#8212;</p>
<p>With this story, we can define some specification for the application as far as User Requirements. Now, this is where I often have a struggle with my inner &#8216;<em>lets-get-to-it!</em>&#8216; developer attitude and I have to keep concrete implementations in check for a bit.</p>
<p><em>// spec</em><br />
&#8212;<br />
<strong>Scenario 1:</strong> Item added to list<br />
<strong>Given</strong> a user requests to add an item to the list<br />
<strong>And</strong> has provided a name for the item<br />
<strong>When</strong> she requests to save the item<br />
<strong>Then</strong> the list has grown by one item<br />
<strong>And</strong> the list contains the item appended at the end<br />
&#8212;</p>
<p>A pretty basic scenario. It is hard for me to not go overboard here and cover every single aspect and moving piece at this stage &#8211; ie, how does this all happen? What is involved upon the first request? What UI has changed? How is a name provided? Shouldn&#8217;t all these be defined as well? All good questions. In my head, this scenario can be broken out into a handful of other scenarios. But I have to stand back and say that this is the scenario that I consider to be the business requirement at hand. This can be read and agreed upon by a third-party who is unfamiliar with the technology that will fulfill this requirement. If I can prove that this expectation is met successfully, the implementation is a by-product and can have additional test if seen fit. We can also add another scenario to this:</p>
<p><em>// spec</em><br />
&#8212;<br />
<strong>Scenario 2:</strong> Item not added to list<br />
<strong>Given</strong> the list has a single item<br />
<strong>And</strong> a user requests to add an item to the list<br />
<strong>And</strong> has not provided a name for the item<br />
<strong>When</strong> she requests to save the item<br />
<strong>Then</strong> the list has the same items as stored previously<br />
<strong>And</strong> the list does not add an empty-named item<br />
&#8212;</p>
<p>Now we are covering the requirements involved in adding an item to the <strong>Grocery List</strong>&#8230; and I always like to fill in a scenario of what it <em>doesn&#8217;t</em> do, because sometimes what it <em>doesn&#8217;t do</em> tells you more about what the system is supposed to do. Again, we can get exhaustive with UI and device event tests, but we don&#8217;t want to meddle down the specs at this point with concrete implementations.</p>
<p>What I do find interesting from just these basic scenarios is that it does reveal some aspects of the application that will need to be addressed while creating the tests &#8211; mainly, a starter on the grocery item model schema and the API in conversing with a view controller to add and edit an item. </p>
<h4>design note</h4>
<p>It should be noted that I do prefer the design concept of <a href="http://martinfowler.com/eaaDev/SupervisingPresenter.html" target="_blank">Supervising Presenter</a> and will employ it within the tests and application, so you are forewarned <img src='http://darko.liquidweb.com/~custardb/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  If you are unfamiliar, a <strong>Supervising Presenter</strong> is knowledgable of the view and model and provides an API that allows for an outside party to affect each, but mostly in affecting the attributes on the model that are observed by the view. Consequently, it will also allow us to not worry to much about the view implementation and User-based events when resolving logical requirements. I don&#8217;t plan to incorporate any application framework that provides such a pattern, so a basic view controller (supervising presenter) will essentially be in charge of modifying the view and model in the <strong>Grocery List</strong> application that will be built. </p>
<p>Architecture, design patterns and the pros and cons of frameworks are things I am more than willing to discuss over beers <img src='http://darko.liquidweb.com/~custardb/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  I just wanted to give you a heads up.</p>
<h2>Test</h2>
<p>I suppose we should address some set-up as this is the first post. <a href="http://pivotal.github.com/jasmine/" target="_blank">Jasmine</a> tests are described in a JavaScript file related to a (typically, single) specification of the application requirements, and those <strong>specs</strong> are run in what is considered a <strong>spec-runner</strong>. The browser-based <a href="http://pivotal.github.com/jasmine/" target="_blank">Jasmine</a> library comes with support for reporting in an HTML document.</p>
<p>Here is an example of the <strong>specrunner.html</strong> from <em>/test/jasmine</em> directory of the github repo for <a href="https://github.com/bustardcelly/grocery-ls">grocery-ls</a>:</p>
<pre class="brush: xml; first-line: 1; title: ;">
&lt;!DOCTYPE html&quot;&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;title&gt;grocery-ls Spec Runner&lt;/title&gt;
    &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;lib/jasmine-1.2.0/jasmine.css&quot;&gt;
    &lt;script src=&quot;../../lib/require-2.1.1.min.js&quot;&gt;&lt;/script&gt;
    &lt;script src=&quot;lib/jasmine-1.2.0/jasmine.js&quot;&gt;&lt;/script&gt;
    &lt;script src=&quot;lib/jasmine-1.2.0/jasmine-html.js&quot;&gt;&lt;/script&gt;
    &lt;script src=&quot;lib/jasmine.async.min.js&quot;&gt;&lt;/script&gt;
    &lt;script src=&quot;lib/sinon-1.5.0.js&quot;&gt;&lt;/script&gt;

    &lt;script&gt;
      (function( window, require ) {

        require.config({
          baseUrl: &quot;../..&quot;,
          paths: {
            &quot;spec&quot;: &quot;./test/jasmine/spec&quot;,
            &quot;script&quot;: &quot;./script&quot;,
            &quot;jquery&quot;: &quot;./lib/jquery-1.8.3.min.js&quot;
          }
        });

        require( ['spec/newitem.spec.js'], function() {

          var jasmineEnv = jasmine.getEnv(),
              htmlReporter = new jasmine.HtmlReporter();

          jasmineEnv.updateInterval = 1000;
          jasmineEnv.addReporter(htmlReporter);
          jasmineEnv.execute();

        });  

      }(window, requirejs));
    &lt;/script&gt;

&lt;/head&gt;
&lt;body&gt;&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>In the spec runner, we have included the library scripts described previously in the <a href="http://custardbelly.com/blog/2012/11/26/the-making-of-a-test-driven-grocery-list-application-in-javascript-part-i">previous post</a>. One thing to note, is the use of <a href="http://requirejs.org/" target="_blank">RequireJS</a>. In order to support <a href="https://github.com/amdjs/amdjs-api/wiki/AMD" target="_blank">AMD</a>, we instruct <strong>RequireJS</strong> to load the <strong>Jasmine</strong> specs defined in JavaScript files prior to setting the environment and executing the specs. Normally, when not incorporating <strong>RequireJS</strong>, you would just add the specs as script tags in the head. An important part of using <strong>RequireJS</strong> is setting the proper paths in the configuration. This allows <strong>RequireJS</strong> to find the proper dependencies not only in the spec itself, but in any concrete implementations separate from the specs. In this example we have set the <em>baseURL</em> to the root of the project directory and define the keyword &#8220;<em>spec</em>&#8221; as pointing to the <strong>Jasmine</strong> spec directory we have set up. If you checkout the <a href="https://github.com/bustardcelly/grocery-ls">project from the repo</a>, the directory structure and the <strong>RequireJS</strong> configuration paths hopefully will make things clearer.</p>
<p>That&#8217;s just a quick introduction to the spec runner. I may not discuss it further in later posts aside from appending specs to the <em>require()</em> invocation. Without additional headless tooling (which may be covered later), when I run the tests I will simply load the spec runner in a browser.</p>
<h2>New-Item Specifications</h2>
<p>Back to the task at hand&#8230; we have to verify the adding of an item to our <strong>Grocery List</strong>. The make up of a spec file should be addressed, especially when incorporating <a href="http://requirejs.org" target="_blank">RequireJS</a> in our application and tests. We need to start off with a <em>define()</em>, which is a <strong>RequireJS</strong> method to define an <strong>AMD</strong> module &#8211; what we are loading from the spec runner are <strong>Jasmine</strong> spec modules, essentially. Within the <strong>Jasmine</strong> spec file itself, we will be primarily concerned with 3 methods:</p>
<ul>
<li><strong>describe</strong> : encapsulates a suite of specifications</li>
<li><strong>it</strong> : defines a specification</li>
<li><strong>expect</strong> : executes a test against matchers that verify expectations</li>
</ul>
<p>That list is hierarchical &#8211; expectations are defined in a suite of specifications. I will start off using the basic matchers that come with <a href="http://pivotal.github.com/jasmine/" target="_blank">Jasmine</a>, but may cover creating custom ones if need be while I develop the <strong>Grocery List</strong> application. It is also important to note that suites can be nested and <strong>Jasmine</strong> is knowledgable enough to execute the tree of specifications appropriately.</p>
<p>Along with those methods that involve expectations of a suite of specifications, there are also two helper methods that I will employ often: <em>beforeEach()</em> and <em>afterEach()</em>. If you are already familiar with unit testing, these are the <strong>setup</strong> and <strong>teardown</strong> methods and will be executed before and after each specification, respectively. They aide in performing common tasks across a suite of specifications that basically setup and teardown dependencies for expectations.</p>
<p><em>Again all of this is a basic overview to actually get to the spec file itself. Definitely checkout the <a href="http://pivotal.github.com/jasmine/" target="_blank">Jasmine documentation</a> for finer detail.</em></p>
<h2>Failing</h2>
<p>With this knowledge, we can create a basic skeleton of the spec file to cover the scenarios described before:<br />
/test/jasmine/spec/newitem.spec.js</p>
<pre class="brush: jscript; first-line: 1; title: ;">
define( function() {

  describe('User requests to add new item', function() {

    it('should save new item when name supplied', function() {
        expect(false).toBe(true);
    });

    it('should not save new item when name not supplied', function() {
        expect(false).toBe(true);
    });

  });

});
</pre>
<p>This spec encompasses the story and specifications we defined previously in this post, and has two failing expectations &#8211; typically, when setting up a suite of specifications and just defining specifications that I will return to in order to complete, I throw in a failing expectation. We are describing our &#8216;add item to grocery list&#8217; story with the two specifications: <strong>1)</strong> allowing an item to be added that has a valid name and <strong>2)</strong> not allowing an item to be added without a valid name.</p>
<p>Now, just working through the employment of a view controller/presenter and the API to expose in order to properly define the requirement of adding an item to the list in the specification, we can come to a handful of requirements in order to successfully fulfill these specs:</p>
<ul>
<li>A grocery item model that exposes a &#8220;name&#8221; property</li>
<li>A list view controller/presenter that exposes an API to:</li>
</ul>
<ul>
<li>add/create a new item</li>
<li>modify a newly added/created item</li>
<li>save an item to the list</li>
</ul>
<p>Additionally, we will want to run the request to add at least one item to the list in order to meet expectations in each specification defined. As such, and without any concrete implementations or stubs, we can modify the spec to include the setup and teardown of the controller that will get us to the expectations of the spec:</p>
<p><em>/test/jasmine/spec/newitem.spec.js</em></p>
<pre class="brush: jscript; first-line: 3; title: ;">
describe('User requests to add new item', function() {

    var listController = {
              editableItem: undefined,
              itemList: []
          };

    beforeEach( function() {
      listController.createNewItem();
      listController.editFocusedItem('apples');
      listController.saveFocusedItem();
    });

    it('should save new item when name supplied', function() {
      expect(false).toBe(true);
    });

    it('should not save new item when name not supplied', function() {
      expect(false).toBe(true);
    });

    afterEach( function() {
      listController.itemList = [];
      listController.editableItem = undefined;
    });

  });
</pre>
<p>Before each spec is entered, the list controller is requested to create a new item, modify it and save it to the list. After each spec, reference to the newly created item is returned to an undefined value and the list is emptied. All this will fail if you run it &#8211; even before getting to the specifications; the <em>listController</em> variable only exposes the item and list properties and does not provide the API we have defined in the <em>beforeEach()</em> method. </p>
<p>Now we could go about stubbing the <em>listController</em> out with an API, like such:</p>
<pre class="brush: jscript; title: ;">
sinon.stub(listController, &quot;createNewItem&quot;, function() {
    listController.editableItem = {};
});
</pre>
<p>&#8230; but, in instances like such, I&#8217;d rather just modify the object directly and then move the implementation to its own <strong>AMD</strong> module. We will get into stubbing and mocking in later posts &#8211; as it is very useful &#8211; but for now, to keep things a little more simpler, I will define the makeup of the <em>listController</em> on itself directly:</p>
<p><em>/test/jasmine/spec/newitem.spec.js</em></p>
<pre class="brush: jscript; first-line: 3; highlight: [3,4,5,6,7,8,9,10,11,12,13,14,15,16,20,21,22,23,24,25,26,27,28,29,30,31,32]; title: ;">
var itemProperties = function(id) {
      return {
        &quot;id&quot;: {
          value: id,
          writable: false,
          enumerable: true
        },
        &quot;name&quot;: {
          value: '',
          writable: true,
          enumerable: true
        }
      };
    },
    listController = {
      itemList: [],
      editableItem: undefined,
      createNewItem: function() {
        this.editableItem = Object.create(Object.prototype, itemProperties(new Date().getTime()));
      },
      editFocusedItem: function(name) {
        this.editableItem.name = name;
      },
      saveFocusedItem: function() {
        if( this.editableItem.name.length !== 0 ) {
          this.itemList.push(this.editableItem);
        }
        this.editableItem = undefined;
      }
    };
</pre>
<p>The <em>listController</em> now exposes the methods for creation, edit and save of an item and internally updates the property values of <em>itemList</em> and <em>editableItem</em>. As well, you will notice how a new item is generated using the <em>Object.create()</em> method and supplying a <em>defineProperties</em> object with an immutable &#8220;<em>id</em>&#8221; property and a mutable &#8220;<em>name</em>&#8221; property. With the <em>listController</em> fleshed out a bit more, we can return to the specs and defined some expectations. Remembering that we instruct the <em>listController</em> to create, modify and save an item to the list in the <em>beforeEach()</em> method fo the spec suite, we can modify the first spec that pertains to the successful add of an item:</p>
<p><em>/test/jasmine/spec/newitem.spec.js</em></p>
<pre class="brush: jscript; first-line: 59; title: ;">
    it('should save new item when name supplied', function() {
      expect(listController.itemList.length).toBe(1);
      expect(listController.itemList[0]).not.toBe(undefined);
      expect(listController.itemList[0].hasOwnProperty('name')).toBe(true);
      expect(listController.itemList[0].name).toBe('apples');
    });
</pre>
<p>It can be debated about the number of expectations per spec and whether each expectation should be split into their respective spec. I see pros and cons with both styles, but I mainly strive to keep &#8220;noise&#8221; to a minimum in my tests &#8211; meaning i will sacrifice listing a handful of expectations around a single specification in order for the progression and specification suite to be more &#8220;readable&#8221;. In this case, I am just verifying that an item has been added and retained by the list exposed on <em>listController</em>, and that the item that resides in the list matches that which was added.</p>
<p>Likewise, to complete the other specification of not being able to add an item that does not have an name attributed to it:<br />
<em>/test/jasmine/spec/newitem.spec.js</em></p>
<pre class="brush: jscript; first-line: 0; title: ;">
    it('should not save new item when name not supplied', function() {
      listController.createNewItem();
      listController.saveFocusedItem();
      expect(listController.itemList.length).toBe(1);
      expect(listController.itemList[0].name).toBe('apples');
    });
</pre>
<p>In this specification, we are requesting to create and save a new item through the <em>listController</em> API. Remembering that an item has already been added from the <em>beforeEach()</em> method, after the <em>saveFocusedItem()</em> request, the list should only contain the item added previously.</p>
<h2>Passing</h2>
<p>If we ran the spec runner, we would see our specifications pass:<br />
<img src="http://custardbelly.com/blog/images/jasmine_1.png" alt="new item passing spec" /></p>
<p>Whoopee! The following is the whole spec file:</p>
<p><em>/test/jasmine/spec/newitem.spec.js</em></p>
<pre class="brush: jscript; first-line: 1; title: ;">
define( function() {

  var itemProperties = function(id) {
        return {
          &quot;id&quot;: {
            value: id,
            writable: false,
            enumerable: true
          },
          &quot;name&quot;: {
            value: '',
            writable: true,
            enumerable: true
          }
        };
      },
      listController = {
        itemList: [],
        editableItem: undefined,
        createNewItem: function() {
          this.editableItem = Object.create(Object.prototype, itemProperties(new Date().getTime()));
        },
        editFocusedItem: function(name) {
          this.editableItem.name = name;
        },
        saveFocusedItem: function() {
          if( this.editableItem.name.length !== 0 ) {
            this.itemList.push(this.editableItem);
          }
          this.editableItem = undefined;
        }
      },
      itemName = 'apples';

  describe('List Controller creates a new item', function() {

    beforeEach( function() {
      listController.createNewItem();
    });

    it('should expose the editableItem upon creation', function() {
      var createdItem = listController.editableItem;
      expect(createdItem).not.toBeUndefined();
      expect(typeof createdItem.name).toBe('string');
      expect(createdItem.name.length).toBe(0);
    });

    afterEach( function() {
      listController.editableItem = undefined;
    });

  });

  describe('User requests to add new item', function() {

    beforeEach( function() {
      listController.createNewItem();
      listController.editFocusedItem(itemName);
      listController.saveFocusedItem();
    });

    it('should save new item when name supplied', function() {
      expect(listController.itemList.length).toBe(1);
      expect(listController.itemList[0]).not.toBe(undefined);
      expect(listController.itemList[0].hasOwnProperty('name')).toBe(true);
      expect(listController.itemList[0].name).toBe(itemName);
    });

    it('should not save new item when name not supplied', function() {
      listController.createNewItem();
      listController.saveFocusedItem();
      expect(listController.itemList.length).toBe(1);
      expect(listController.itemList[0].name).toBe(itemName);
    });

    afterEach( function() {
      listController.itemList = [];
      listController.editableItem = undefined;
    });

  });

});
</pre>
<p>You may notice that I snuck in another little specification revolved around the creation and exposure of a new item through the <em>listController</em> &#8211; that is because I am anal and additionally wanted to ensure that the <em>listController</em> responded properly as I saw fit upon creation of a new item.</p>
<p>Of course, at this point the design of the controller can be debated &#8211; and it is a much welcome discussion. I setup <em>listController</em> as it is with the following requirements:</p>
<ul>
<li>View implementation is abstracted away. <em>In fact there is absolutely no communication with the DOM to make these specifications pass. It will be the controller&#8217;s responsibility on how the view is updated based on the exposed API.</em></li>
<li>Only one item will be editable at any given time within the application session. <em>This may be later determined as an oversight, but that is the requirement I have set at the moment&#8230; and if we need multiple editable items, we&#8217;ll modify our tests and refactor!</em></li>
<li>The list of items is accessible and mutable on the controller. <em>This is a requirement that will likely change as the addition and removal of items will have some impact on the supervised view, likely leading to the an API to modify the list replacing the direct access.</em></li>
</ul>
<p><strong>Tagged</strong> 0.1.0: <a href="https://github.com/bustardcelly/grocery-ls/tree/0.1.0" target="_blank">https://github.com/bustardcelly/grocery-ls/tree/0.1.0</a></p>
<h3>Implementation</h3>
<p>Typically, after having passed specifications, I like to move the work to actual implementations of the application. It is similar to the concept of <a href="http://cumulative-hypotheses.org/2011/08/30/tdd-as-if-you-meant-it/" target="_blank"><em>TDD like you mean it</em></a>, but I don&#8217;t think I strictly adhere to that principle. In any event, we can move the implementation of the <em>listController</em> from the <strong>newitem.spec</strong> to its own <strong>AMD</strong> module define that as a dependency for our spec.</p>
<p>Very simply, we could rip the object declarations from <strong>newitem.spec.js</strong> and drop them into a new <strong>AMD</strong> module and define the <em>listController</em> export for dependency reference in the spec:</p>
<p><em>/script/controller/list-controller.js</em></p>
<pre class="brush: jscript; first-line: 1; title: ;">
define(function() {
  var itemProperties = function(id) {
        return {
          &quot;id&quot;: {
            value: id,
            writable: false,
            enumerable: true
          },
          &quot;name&quot;: {
            value: '',
            writable: true,
            enumerable: true
          }
        };
      },
      listController = {
        itemList: [],
        editableItem: undefined,
        createNewItem: function() {
          this.editableItem = Object.create(Object.prototype, itemProperties(new Date().getTime()));
        },
        editFocusedItem: function(name) {
          this.editableItem.name = name;
        },
        saveFocusedItem: function() {
          if( this.editableItem.name.length !== 0 ) {
            this.itemList.push(this.editableItem);
          }
          this.editableItem = undefined;
        }
      };

  return listController;
});
</pre>
<p><em>/test/jasmine/spec/newitem.spec.js</em></p>
<pre class="brush: jscript; first-line: 1; title: ;">
define( ['script/controller/list-controller'], function(listController) {

  var itemName = 'apples';

  describe('List Controller creates a new item', function() {

    beforeEach( function() {
      listController.createNewItem();
    });

    it('should expose the editableItem upon creation', function() {
      expect(listController.editableItem).not.toBeUndefined();
    });

    afterEach( function() {
      listController.editableItem = undefined;
    });

  });

  describe('User requests to add new item', function() {

    beforeEach( function() {
      listController.createNewItem();
      listController.editFocusedItem(itemName);
      listController.saveFocusedItem();
    });

    it('should save new item when name supplied', function() {
      expect(listController.itemList.length).toBe(1);
      expect(listController.itemList[0]).not.toBe(undefined);
      expect(listController.itemList[0].hasOwnProperty('name')).toBe(true);
      expect(listController.itemList[0].name).toBe(itemName);
    });

    it('should not save new item when name not supplied', function() {
      listController.createNewItem();
      listController.saveFocusedItem();
      expect(listController.itemList.length).toBe(1);
      expect(listController.itemList[0].name).toBe(itemName);
    });

    afterEach( function() {
      listController.itemList = [];
      listController.editableItem = undefined;
    });

  });

});
</pre>
<p>In the modified <strong>newitem.spec.js</strong>, we have defined the dependency on the <em>list-controller</em> module which is then referenced using <em>listController</em>. Running that will result in the same successful expectations as before. You may notice that the dependency for the <em>listController</em> is defined as <em>&#8217;script/controller/list-controller&#8217;</em>. The <em>&#8217;script&#8217;</em> directory is defined in the <strong>RequireJS</strong> configuration in the spec runner file discussed previously in this post &#8211; it will know how to resolve its location and load the controller file.</p>
<p>Now is where, typically, as modifications to <em>list-controller</em> are made in response to new requirements and specifications, stubbing comes into play within my specs more. If an addition or change to the API of <em>list-controller</em> is required for a new story, then in the specification test I would implement that API using stubs, then move the implementation to the <em>list-controller</em> module once they pass.</p>
<p><strong>Tagged</strong>, 0.1.1: <a href="https://github.com/bustardcelly/grocery-ls/tree/0.1.1" target="_blank">https://github.com/bustardcelly/grocery-ls/tree/0.1.1</a></p>
<h3>Usability</h3>
<p>Because I can&#8217;t leave well-enough alone, I want to hook up this functionality to User response <img src='http://darko.liquidweb.com/~custardb/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Available in the repo at the current revision up to this point (tagged  <a href="https://github.com/bustardcelly/grocery-ls/tree/0.1.1" target="_blank">0.1.1</a>), there is a main index file that I have not addressed in this post:</p>
<p><em>/index.html</em></p>
<pre class="brush: xml; first-line: 1; title: ;">
&lt;!DOCTYPE html&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;title&gt;grocery-ls&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;header&gt;
      &lt;h1&gt;grocery-ls&lt;/h1&gt;
    &lt;/header&gt;
    &lt;section class=&quot;groceries&quot;&gt;
      &lt;ul class=&quot;grocery-list&quot;&gt;&lt;/ul&gt;
      &lt;button id=&quot;add-item-button&quot;&gt;add item&lt;/button&gt;
    &lt;/section&gt;
    &lt;script src=&quot;lib/require-2.1.1.min.js&quot;&gt;&lt;/script&gt;
    &lt;script src=&quot;script/grocery-ls.js&quot;&gt;&lt;/script&gt;
  &lt;/body&gt;
&lt;/html&gt;
</pre>
<p>The page just defines an unordered list to display grocery items (editable &#038; uneditable) and a button to add an item to the list. As well, we have included the <a href="http://requirejs.org/" target="_blank">RequireJS</a> library and a main JS file for the <strong>Grocery List</strong> application:</p>
<p><em>/script/grocery-ls.js</em></p>
<pre class="brush: jscript; first-line: 1; title: ;">
(function(window, require) {

  require.config({
    baseUrl: &quot;.&quot;,
    paths: {
      &quot;lib&quot;: &quot;./lib&quot;,
      &quot;script&quot;: &quot;./script&quot;,
      &quot;jquery&quot;: &quot;./lib/jquery-1.8.3.min&quot;
    }
  });

  require( ['jquery', 'script/controller/list-controller'], function($, listController) {
    listController.setView($('section.groceries'));
  });

}(window, requirejs));
</pre>
<p>The configuration paths, you are familiar with when we set up the specrunner for our <a href="http://pivotal.github.com/jasmine/" target="_blank">Jasmine</a> tests. Additionally, we are asking <strong>RequireJS</strong> to load the &#8216;<em>jquery</em>&#8216; and &#8216;<em>list-controller</em>&#8216; dependencies, after which, the <em>list-controller</em> is given a reference to the DOM element it will supervise: the <strong>section</strong> element with the <strong>class</strong> attribute value of &#8216;<em>groceries</em>&#8216;.</p>
<p>The <em>list-controller</em> will now have more responsibility in updating the view based on invocations of the API we have previously defined for our specifications:</p>
<p><em>/script/controller/list-controller.js</em></p>
<pre class="brush: jscript; first-line: 1; title: ;">
define(['jquery', 'script/model/grocery-ls-item'], function($, itemModel) {

  var $view,
      $item,
      $itemList,
      itemFragment              = '&lt;li class=&quot;grocery-item&quot; /&gt;',
      editableItemFragment  = '&lt;li class=&quot;editable-grocery-item&quot;&gt;' +
                                '&lt;input id=&quot;editableItem&quot; name=&quot;editableItem&quot; ' +
                                  'class=&quot;editable-item&quot; placeholder=&quot;Enter item name...&quot;&gt;' +
                                '&lt;/input&gt;' +
                              '&lt;/li&gt;',
      findItemList = function() {
        if( typeof $itemList === 'undefined' ) {
          $itemList = $('.grocery-list', $view);
        }
        return $itemList;
      },
      listController = {
        itemList: [],
        editableItem: undefined,
        setView: function(value) {
          var controller = this;
          $view = $(value);
          $('#add-item-button', this.$view).on( 'click', function(event) {
            controller.createNewItem();
          });
        },
        createNewItem: function() {
          var $list = findItemList(),
              $input,
              controller = this;

          this.editableItem = itemModel.create();
          $item = $(editableItemFragment);
          $input = $('input', $item);
          $input.first().bind( 'blur', function(event) {
            var $this = $(this);

            $this.unbind('blur');
            controller.editFocusedItem( $this.val() );
            controller.saveFocusedItem();
          });

          $item.data('gls-item', this.editableItem);
          $list.append($item);
          $input.first().focus();
        },
        editFocusedItem: function(name) {
          this.editableItem.name = name;
        },
        saveFocusedItem: function() {
          var $list = findItemList();
              $itemFragment = $(itemFragment);

          $item.remove();
          if( this.editableItem.name.length &gt; 0 ) {
            $itemFragment.append('p').text(this.editableItem.name);
            $itemFragment.data('gls-item', this.editableItem);
            $list.append($itemFragment);
            this.itemList.push(this.editableItem);
          }
          this.editableItem = undefined;
        }
      };

  return listController;

});
</pre>
<p><em>/script/model/grocery-ls-item.js</em></p>
<pre class="brush: jscript; first-line: 1; title: ;">
define(function() {

  var properties = function(id) {
    return {
      &quot;id&quot;: {
        value: id,
        writable: false,
        enumerable: true
      },
      &quot;name&quot;: {
        value: '',
        writable: true,
        enumerable: true
      }
    };
  };

  return {
    create: function() {
      return Object.create(Object.prototype, properties(new Date().getTime()));
    }
  };

});
</pre>
<p>The modifications to the <em>list-controller</em> from it&#8217;s previous implementation mainly involve access and modification of the DOM in response to requests on its API. If we ran the <a href="http://pivotal.github.com/jasmine/" target="_blank">Jasmine</a> spec we previously created &#8211; <strong>newitem.spec.js</strong> &#8211; it would still pass. If the main <strong>index.html</strong> file is loaded in a browser, you will be able to add an item by clicking the button and as long as you provide a name in the input field, it will be added to the list.</p>
<p><img src="http://custardbelly.com/blog/images/jasmine1_app.png" alt="grocery list app version 0.1.2" /></p>
<p>We could (and perhaps some readers would say that I <em>should</em> have) created more specs that defined the usability and expectations of DOM manipulation on response to API invocations on the <em>list-controller</em>. It is a valid point and I totally agree. At this point I don&#8217;t want to add noise with the user interface implementations in the specifications; the view implementation is subject to change and the API on the <em>list-controller</em> currently supports the modification of the grocery list. We can be assured at the current moment that the <em>list-controller</em> knows how to manage the list and we should not worry about what User impetus invokes the API.</p>
<p>Perhaps in later posts I will see the error of my ways in letting this go&#8230;</p>
<p><strong>Tagged</strong>, 0.1.2: <a href="https://github.com/bustardcelly/grocery-ls/tree/0.1.2" target="_blank">https://github.com/bustardcelly/grocery-ls/tree/0.1.2</a></p>
<h1>Conclusion</h1>
<p>We went through the first story, scenarios and specifications of the <strong>Grocery List</strong> application that will be built throughout this series. A tonne of information was covered and if you stayed with me, I appreciate it. In the end we have a passing spec suite for the creation and add of a grocery item through a list view controller. We moved the implementation of the controller and model from the spec to their respective <strong>AMD</strong> modules and allowed for user interaction with the application to perform the creation and add operations.</p>
<p>Thanks for sticking around. I hope this series proves to be helpful in some way.</p>
<p>&#8212;-</p>
<h1>Link Dump</h1>
<h2>Post Series</h2>
<p><a href="https://github.com/bustardcelly/grocery-ls">grocery-ls github repo</a><br />
<a href="http://custardbelly.com/blog/2012/11/26/the-making-of-a-test-driven-grocery-list-application-in-javascript-part-i" target="_blank">Part I &#8211; Introduction</a><br />
<a href="http://custardbelly.com/blog/2012/11/26/the-making-of-a-test-driven-grocery-list-application-in-js-part-ii">Part II &#8211; Feature: Add Item</a><br />
<a href="http://custardbelly.com/blog/2012/12/06/the-making-of-a-test-driven-grocery-list-application-in-js-part-iii">Part III &#8211; Feature: Mark-Off Item</a><br />
<a href="http://custardbelly.com/blog/2012/12/17/the-making-of-a-test-driven-grocery-list-application-in-js-part-iv">Part IV &#8211; Feature: List-Item-Controller</a><br />
<a href="http://custardbelly.com/blog/2012/12/31/the-making-of-a-test-driven-grocery-list-application-in-js-part-v/">Part V &#8211; Feature: List-Controller Refactoring</a><br />
<a href="http://custardbelly.com/blog/2013/01/08/the-making-of-a-test-driven-grocery-list-application-in-js-part-vi/" target="_blank">Part VI &#8211; Back to Passing</a><br />
<a href="http://custardbelly.com/blog/2013/01/17/the-making-of-a-test-driven-grocery-list-application-in-js-part-vii/">Part VII &#8211; Remove Item</a><br />
<a href="http://custardbelly.com/blog/2013/01/22/the-making-of-a-test-driven-grocery-list-application-part-viii/">Part VIII &#8211; Bug Fixing</a><br />
<a href="http://custardbelly.com/blog/2013/02/15/the-making-of-a-test-driven-grocery-list-application-in-js-part-ix/">Part IX &#8211; Persistence</a><br />
<a href="http://custardbelly.com/blog/2013/03/06/the-making-of-a-test-driven-grocery-list-application-in-js-part-x/">Part X &#8211; It Lives!</a></p>
<h2>Reference</h2>
<p><a href="http://tddjs.com/" target="_blank">Test-Driven JavaScript Development by Christian Johansen</a><br />
<a href="http://dannorth.net/introducing-bdd/" target="_blank">Introducing BDD by Dan North</a><br />
<a href="http://cumulative-hypotheses.org/2011/08/30/tdd-as-if-you-meant-it/">TDD as if you Meant it by Keith Braithwaite</a><br />
<a href="http://requirejs.org/" target="_blank">RequireJS</a><br />
<a href="https://github.com/amdjs/amdjs-api/wiki/AMD" target="_blank">AMD</a><br />
<a href="http://pivotal.github.com/jasmine/" target="_blank">Jasmine</a><br />
<a href="http://sinonjs.org/" target="_blank">Sinon</a><br />
<a href="https://github.com/derickbailey/jasmine.async" target="_blank">Jasmine.Async</a></p>
]]></content:encoded>
			<wfw:commentRss>http://custardbelly.com/blog/2012/11/26/the-making-of-a-test-driven-grocery-list-application-in-js-part-ii/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
