Showing posts for tag: javascript

Namespacing in JavaScript

May 30th 2012

JavaScript’s global variables are evil, and namespacing is a good thing. However, as I regularly move from project to project, I find myself rewriting the code to help manage namespaces again and again. Every time I search for something reusable, I find conventions that require unpleasant boilerplate.

I started a little personal project, and ended up writing this. Hopefully somebody might find it useful.

Grab the source here.

Include it in your document like so:

<script src="/path/to/n.js" type="text/javascript"></script>

Register objects and classes like so:

n('foo.bar.baz', function(s) {
  s.Person = function () {
    this.greet = function () {
      alert('hello');
    };
  };
});

Reference registered objects and classes like so:

var myPerson = new foo.bar.baz.Person();
myPerson.greet();

That’s all there is to it!

UPDATE: A minified version can now be found here. Thanks Scott Hamper!

Updated jasmine-underscore

March 14th 2012

Last year jasmine-underscore was released. Since then, some issues have been fixed, and two new matchers have also been included:

allToSatisfy
expect([2, 4, 6]).allToSatisfy(function (val) { return val%2 == 0; });
expect([1, 4, 6]).not.allToSatisfy(function (val) { return val%2 == 0; });
anyToSatisfy
expect([2, 3, 5]).anyToSatisfy(function (val) { return val%2 == 0; });
expect([1, 3, 5]).not.anyToSatisfy(function (val) { return val%2 == 0; });

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

Get version 1.1 here. Enjoy!

jasmine-underscore

June 19th 2011

I love Jasmine. It’s a fantastic testing framework with a good set of extensions (e.g. jasmine-jquery).

I also love Underscore. It has a number of utility functions that help improve the readability of my code and dramatically reduces the code duplication associated with managing collections in JavaScript.

Recently I’ve been using Jasmine and Underscore together in tests. Underscore provides a number of functions to interrogate the state of an object, and I find I often use these in my Jasmine specs:

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

This is a useful test, however it doesn’t read quite as nicely as it could. There is a lot of noise, and the failure reporting won’t be particularly informative. With that in mind I created jasmine-underscore. This extension creates matchers for Jasmine based on the Underscore’s object functions. Any function that Underscore provides that has the ‘is’ prefix can be used as a matcher. For example, the test above becomes:

it('should return today as a date', function () {
  var cal = new AwesomeCalendar();
  expect(cal.today()).toBeDate();
});

This is not only more readable, it also produces better failure messages. The first spec’s error message would be Expected false to be truthy. Now the failure will read Expected null to be date if today unexpectedly returns null.

using

Another situation I found myself using Underscore with Jasmine a great deal is the generation of examples for specs:

_([
    [1, 2, 3], 
    [2, 3, 5]
  ]).each(function (vals) {

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

  it('should sum ' + first + ' and ' + second, function () {
      expect(sum(first, second)).toEqual(total);
  });
});

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

using([1, 2, 3], [2, 3, 5], function (first, second, total) {
  it('should sum ' + first + ' and ' + second, function () {
      expect(sum(first, second)).toEqual(total);
  });
});