Alexander Beletsky's development blog

My profession is engineering

Kiev ALT.NET Re-launch with Jimmy Bogard

Good news, Kiev ALT.NET community! One of the best know ALT.NET developers Jimmy Bogard is visiting us on December 11. It’s been awhile since the last meetup we had, so it’s just great time to gather again and listen to the presentation Jimmy prepared for us.

There will be a talk with intriguing name “Real World Polyglot Persistence”. Here is the short description of it.

It always sounds easy - “use the best tool for the job”. With very isolated systems, it’s easy to decide RDBMS for one application, Redis for another and Cassandra for somethings else. When it comes time to building systems with multiple persistent stores, we’re met with challenges in integration, existing applications, and push back from IT administrators. In this session, we’ll look at the multitude of challenges of achieving polyglot persistence nirvana, and strategies for addressing associated risks.

I don’t know about you, but for me it sound extremely interesting.

Meetup will take place in Ciklum, the most spectacular place in Kiev - Sky Point at 19-00. As always, Ciklum happily agreed host us.

Participation is completely free, but you have to register before. Registration is available here.

The information support by our good friend at wp7rocks.com.


Pair Programming Takes Double Effort

Pair programming is very known as efficient technique of writing code. Originally appeared as one of key XP practices, it got a lot of traction. You can find many publication about Pair Programming and seems everybody clearly understands it’s value. Being a XP trainer and visiting conferences related to engineering practices I usually see such situation: the question goes to the crowd “How many of you do practice Pair Programming?” and I can give a bet, only few hands will appear.. very few people are actually practicing Pair Programming. Why?

Because Pair Programming is damn hard!

There could be 2 situations with PP: first one, then both guys are completely different levels of skills - it turns to be that one (more experienced) is writing and thinking all the time, another one is almost watcher helping to find a grammar errors in code comments. At the end of the day you got 2 mans powers producing 1 mans power work. Easy journey.

Second one is different, is then 2 guys are same or equally same level. Working in such pair could be compared to wresting. You literally have to fight to move on. All the time you under pressure of another man’s opinion, usually strong one. You struggle much to get consensus on different topics. You are talking all the time and arguing all the time. Sure, you got shinny-working-super-cool results much more faster by working such pair.

But there is a problem - after 3-4 hours of working that way you will be completely exhausted. Believe me, you are absolutely useless after 4 hours session of true Pair Programming. Thinking, focusing, arguing, writing, testing, debugging over and over again. It takes a lot of energy. Working a 40 hours week in strong pair will let you feel like 80 hours week. There is also psychological side as well: 2 persons could not match each over, so working in pair would be like hell.

Pair programming takes double effort. You should not plan PP session for a whole day, half day as maximum. In my opinion it’s not valuable to do every task in pair, simply it’s not productive. Pick up most difficult ones, ones that requires cross-functional expertise or most risky ones. As problem well kick-started, rest of things might go in parallel.

I really like Pair Programming, but I would not use it as day-to-day practice as XP suggests. Most of the time, it’s more efficient to work alone.

Baby steps to Backbone.js: Unit testing of models

Unit testing is important part of development process. If you care about the application state and code quality, sooner or later you start to automate the tests. My experience shows, sooner is better option. There are several approaches to unit testing, `test-first` and `test-after`. There are many holy wars appears on that topic. I would say, both options works - but `test-first` or test driven development, works better for me.

By the end of the day, it’s only important that tests exists and helping to catch regression bugs. Still, developing by `test-first` helps to see the problem before ahead and in general provides better code quality (that would conclude the holy war).

Today we going to write some tests, that would cover our existing model class Feedback.js. Since the code is already written, we will go `test-after` approach. Fortunately, the code is quite simple, so it would not make a problem to unit test that. But before, let’s setup our testing infrastructure.

Folders and files

We’ll have a new folder called `spec`. Inside the spec folder, I’ll have `models` and `views` folders that would contain tests for models and views.




Tests runner

I’ll be using Jasmine test framework. It’s very easy to setup it, what we need is jasmine.js and jasmine.css to be placed on proper folders and setup a test page. Test page is a simple html file, which will be entry point for our testing. If you download jasmine standalone bundle you will see SpecRunner.html inside. It could be easily tailored for custom needs.

In the head part of tests.html we need to reference all required .css and .js files.

<title>Feedback form specs</title>

<link rel="stylesheet" type="text/css" href="content/jasmine.css">

<script type="text/javascript" src="/scripts/libs/jquery-1.7.2.js"></script>
<script type="text/javascript" src="/scripts/libs/underscore.js"></script>
<script type="text/javascript" src="/scripts/libs/backbone.js"></script>
<script type="text/javascript" src="/scripts/libs/jasmine.js"></script>
<script type="text/javascript" src="/scripts/libs/jasmine-html.js"></script>
<script type="text/javascript" src="/scripts/libs/mock-ajax.js"></script>

<!-- Sources -->
<script type="text/javascript" src="/scripts/src/models/Feedback.js"></script>

<!-- Specs -->
<script type="text/javascript" src="/scripts/spec/models/Feedback.spec.js"></script>
    

Jasmine tests in essence

Testing with Jasmine is fun and easy. Jasmine is BDD-style framework, so if you practiced TDD with another frameworks, the style might confuse initially. Let’s review the Jasmine test skeleton.

describe('Jasmine spec', function () {
    var value;

    beforeEach(function () {
        value = 1;
    });

    it ('should fail', function () {
        expect(value).toBe(0);
    });

    describe('when value is changed', function () {
        beforeEach(function () {
            value = 0;
        });

        it ('should pass', function () {
            expect(value).toBe(0);
        })
    });
});

In this example, value is our SUT (System under test). beforeEach() function is `context-establish` function, where SUT is initialized (in TDD it’s both arrange/act). it function is assert part. Here, we set our expectations about which state should SUT be in to. Notice, that beforeEach are nested into describe, so you tweek SUT depending on case.

Writing some tests

The only one functionality that Feedback.js model contains currently is validation. Let’s test that.

describe('Feedback.js spec', function () {
    var model;

    beforeEach(function () {
        model = new Feedback();
    });

    describe('when model is validating', function () {
        var errors;
    });
});

This is something to start with. It does not do any asserts, so now we’ll add some real cases. First case, is than both `email` and `feedback` attributes are absent.

describe('when email and feedback fields are absent', function () {
    beforeEach(function () {
        errors = model.validate({});
    });

    it ('should have 2 errors', function () {
        expect(errors.length).toBe(2);
    });

    it ('should have email fields as invalid', function () {
        expect(errors[0].name).toBe('email');
    });

    it ('should have feedback field as invalid', function () {
        expect(errors[1].name).toBe('feedback');
    });
});

It’s is possible that user put email, but forgot about feedback.

describe('when email is set, but feedback is absent', function () {
    beforeEach(function () {
        errors = model.validate({ email: 'a@a.com'});
    });

    it ('should have 1 error', function () {
        expect(errors.length).toBe(1);
    });

    it ('should have feedback field as invalid', function () {
        expect(errors[0].name).toBe('feedback');
    });

    it ('should have error message', function () {
        expect(errors[0].message).toBeDefined();
    });
});

Moving on, user might put feedback but forgot about email.

describe('when feedback is set, but email is absent', function () {
    beforeEach(function () {
        errors = model.validate({ feedback: 'TDD is awesome'});
    });

    it ('should have 1 error', function () {
        expect(errors.length).toBe(1);
    });

    it ('should have email field as invalid', function () {
        expect(errors[0].name).toBe('email');
    });

    it ('should have error message', function () {
        expect(errors[0].message).toBeDefined();
    });
});

Tests report

If you now try to run test.html in browser, you will something like that.




Conclusions

Testing of Backbone.Model’s is pretty simple thing. It’s nothing more than testing some business logic, that might reside inside. Testing of views is a bit trickier thing, but we will see how to do that next time.

JavaScript Object Creation by New Operator

There are different approaches of how to create object in JavaScript. C# and Java programmers are commonly starting with creation by new operator, since it very close to same practice they got used to.

function Person (name) {
    this.name = name;
}

var person = new Person('John Smith');
console.log(person.name);
    

If you try to run this code, you will see ‘John Smith’ in console. Now, try to delete new operator.

Instead of ‘John Smith’ you will see undefined. Why?

The difference is that without new operator it is just function call. During the call `this` points global namespace. If you running the code in browser, global namespace is bind to `window`.

It’s important to understand how new operator works. Internally, operator new is converted to NEW(Person, ‘John Smith’);. It does several things.

  1. Creates new native object and initializes the __proto__ of object by function.prototype.
  2. Calls function, applying newly created object as value for this.
  3. Returns newly created object.

It can be expressed in this kind of pseudo-code:

function NEW(f) {
    var obj = { '__proto__': f.prototype };
    f.apply(obj, arguments.slice(1));
    return obj;
}

(It’s a bit more complex actually, for details check this great answer on SO).

It means that during function call with `new operator()`, this always points to a new object, created based on function prototype. You can initialize the properties of new object inside the function. It’s no longer a simple function, but it is constructing function, or more simply - constructor.

To distinguish between constructors (that are always supposed to be called with `new`) and simple function, there is a convention to name a constructors with capital first letter (not person(), but Person()), just to give you some tips while you writing the code.

Knowing NEW() details of work and following simple conventions for constructors will help you to understand language better and prevent many stupid errors.

ELMAH.MVC 2.0.2 is out

ELMAH MVC 2.0.2 has been just pushed recently. This is a contribution by James Crowley which adds a special configuration key that prevents ELMAH.MVC to setup a global `HandleErrorAttribute()`. It’s in particular useful, than you already setup some configuration inside the app, so you don’t want default behavior.

Inside the web.config file you will find a configuration setting for that.

<appSettings>
 <add key="elmah.mvc.disableHandler" value="false" />
 <add key="elmah.mvc.disableHandleErrorFilter" value="false" />
 <add key="elmah.mvc.requiresAuthentication" value="false" />
 <add key="elmah.mvc.allowedRoles" value="*" />
 <add key="elmah.mvc.route" value="elmah" />
</appSettings>
    

It is elmah.mvc.disableHandleErrorFilter. By default it’s `false`, meaning `HandleErrorAttribute()` from ELMAH.MVC is used. To disable it, just set true to this setting.

And btw, it’s already 30.000 downloads of NuGet package! Huge number, thanks a lot for all users and contributors.

Baby steps to Backbone.js: Model Validation

Let’s go back for a moment for previous post where we started to bootstrap some basic Backbone.js application. It’s very simple now, just gathering all data and posting those data to server.

Any reliable system is almost impossible without validation. If some field is required or must conform to some particular rule, it should be validated as soon as possible and validation information should be displayed to user. User then applies corrections and re-submit data.

In case of `Feedback` model, we are interested that user always input her email and feedback message. Backbone.js provides very straight forward for models validation. If model requires validation, it should implement validate method.

So, let’s extend our model with validate method.

var Feedback = Backbone.Model.extend({
    url: '/feedback',

    defaults: {
        'email': '',
        'website': '',
        'feedback': ''
    },

    validate: function (attrs) {
        if (!attrs.email) {
            return 'Please fill email field.';
        }
        if (!attrs.feedback) {
            return 'Please fill feedback field.';
        }
    }
});
    

As you can see, in case of email or feedback is missing, we just simply return string with error message.

To better understand what’s going on, let’s look on some piece of the code from Backbone.js framework. Namely, to `_validate` method of `Backbone.Model`, which is actually responsible for validation.

_validate: function(attrs, options) {
    if (options.silent || !this.validate) return true;
    attrs = _.extend({}, this.attributes, attrs);
    var error = this.validate(attrs, options);
    if (!error) return true;
    if (options && options.error) {
       options.error(this, error, options);
    } else {
        this.trigger('error', this, error, options);
    }
    return false;
}

You can see, if `validate` returns either undefined or null or false, `_validate` just returns true - meaning the model is valid. Otherwise, it would check if `options.error` function initialized and call it, if not model event `error` is triggered.

During the model saving, we typically provide both success and error callbacks. It means, that error callback will be called, if model does not pass validation requirements. Inside the callback, we might decided what to do with errors. Right now, let’s just do alert.

var options = {
    success: function () {
        alert('Thanks for the feedback!');
    },
    error: function (model, error) {
        alert(error);
    }
};

var feedback = {
    email: this.$('#email').val(),
    website:  this.$('#website').val(),
    feedback: this.$('#feedback').val()
};

this.model.save(feedback, options);
    

Notice that `error` callback receiving model itself as first argument and error object (one returned from `validate` method) as second argument. Let’s try this code: leave email and feedback fields empty and press submit button.




There are several drawback of such implementation, though. First of all, `alert` windows are awful, second if user corrects email, next time she presses the submit button next alert with another message appears. This is terrible UX, so let’s fix it.

So, we should basically do 2 things: aggregate all errors during validation and apply some nice styles to errors.

Instead of returning simple strings, we’ll return an array of objects, containing name of failed and field and message.

validate: function (attrs) {
    var errors = [];

    if (!attrs.email) {
        errors.push({name: 'email', message: 'Please fill email field.'});
    }
    if (!attrs.feedback) {
        errors.push({name: 'feedback', message: 'Please fill feedback field.'});
    }

    return errors.length > 0 ? errors : false;
}

Change the `save` method options, to show errors if any error appeared and hide errors if save was successful.

var me = this;
var options = {
    success: function () {
        me.hideErrors();
    },
    error: function (model, errors) {
        me.showErrors(errors);
    }
};

And implement 2 simple methods:

showErrors: function(errors) {
    _.each(errors, function (error) {
        var controlGroup = this.$('.' + error.name);
        controlGroup.addClass('error');
        controlGroup.find('.help-inline').text(error.message);
    }, this);
},

hideErrors: function () {
    this.$('.control-group').removeClass('error');
    this.$('.help-inline').text('');
}

Let’s test the code. As all fields are left empty, it will look like,




As fields are filled and form submitted, all errors are cleared from form.

Conclusions

That was very simple “baby-step” style of approaching model validation. I would could it, validation “from the box”. Even if it’s very useful there are a lot of different approaches of making even things better. The source code is availble on github.

Stay tuned for next Backbone.js baby steps soon.

How to run multiple AJAX requests

Suppose you have a list of resources that you would like to retrieve by means of AJAX. `$.ajax()` (or it’s short variants like `$.get()` or `$.post`) is usual way of making AJAX calls, it works great than you need to fetch one.

var url = '/api/resource/1';
$.get(url, function (r) {
    // use response
});
    

Even in case of several it might be still usable,

var url1 = '/api/resource/1';
var url2 = '/api/resource/2'
$.get(url1, function (r) {
    // use response from url1

    $.get(url1, function (r) {
        // use response from url2
    });
});
    

You can easily see, if you have more than 3 you are trapping into “callback hell”. Furthermore, if you have a list of url’s to fetch and the size of that list is dynamic, it’s not even possible to build structure like that.

Not long time a ago, I’ve been exactly into this situation. So, I have a list of resources to fetch, I need to issue them one-by-one and I want to have only one callback, that would pass all fetched resources in one object. Initially I thought it’s not even possible, at least with-out creation of some ugly code. But with great help of my colleagues the problem been solved.

jQuery Deferred Object is something I’ve head about, but never got a change to play with. It turn’s out to be very nice and simple idea. Deferred allows you to build chainable constructions. Actually, `$.ajax()` always returns deferred object, so you can apply `.done()`, `.fail()` functions on it.

Here is the code, that you could be re-usable in the same situation;

var pipedAjaxRequests = function (urls, callback) {
 var responses = {};

 var promise = $.Deferred().resolve();
 _.each(urls, function (url) {
  promise = promise.pipe(function () {
   return $.get(url);
  }).done(function (response) {
   responses[url] = response;
  });
 });

 promise.done(function () {
  callback(responses);
 }).fail(function (err) {
  callback(responses, err);
 });
};

It does create the pipe of `$.get()` calls and place the responses in one response object. At the time then all resources are fetched, the callback is called. In case of errors, second parameter of callback will have error info.

Thanks a lot to @antsamar and @alex_gonchar for helping me out.

Baby Steps to Backbone.js: Starting up

Many times then I speak to people regarding usage of any kind of MV* frameworks on front-end I hear common objection: “but we already have a lot of code written on jQuery/Dojo/Whatever, I think usage of additional framework would be impossible”. This is not actually true. Backbone is very lightweight and could fit into any existing application.

Baby steps strategy is the most efficient way of trying the things. You start with something really small, enhance it over the time and expand for other application areas. Now, let’s imagine you got an existing application, you wish to start using Backbone.js to improve that. I would like to show you, that it’s absolutely possible.

Suppose, you want to add a feedback form for your app. Let’s implement that with Backbone.js.

Applications, Models, Views

There are no such thing as `Controller` in Backbone.js. But you have to have some kind of entry point, some place with `main()` function inside. I got used to call this place - Application. Basically, the application is a module, which is responsible for initialization of model, instantiation of view, rendering the view.

The `Model` is object that holds the data. It could be fetched and persisted back to server.

And finally view is object that produces markup, hooking up events and updates View from data in Model and otherwise.

We are going to create all three things. It makes a lot of sense to breakdown the folder structure of to reflect logical meaning of each entity of Backbone application. So, we’ll create 3 folders for apps, models and views.




Setup Backbone.js

On a target html page we should place 2 additional script tags.

<script src="/scripts/libs/underscore.js"></script>
<script src="/scripts/libs/backbone.js"></script>
    

Besides of that, let’s add one more div. The one that application will be using for rendering views.

<div id="app" class="container"></div>
    

Application entry point

Let’s create a new file in `apps` folder and call it `FeedbackFormApp.js`. It would be very simple.

$(function () {
    var model = new Feedback();
    var view = new FeedbackFormView ({model: model});
    
    $('#app').html(view.render().el);
});
    

Then DOM is ready, we instantiate new model object and view and render the form into DOM element with id - app.

Feedback model

Now, let’s define a model. Create a new file in models folder and call it `Feedback.js`.

The model refects the data we are collecting/displaying to user and it’s typically stored on server (sometimes on localstorage). Feedback model will include 3 attributes: email of user, his web site and the feedback text. In terms of Backbone.js that would mean.

var Feedback = Backbone.Model.extend({

    url: '/feedback',

    defaults: {
        'email': '',
        'website': '',
        'feedback': ''
    }

});
    

The url property of model object is used by Backbone for persisting object to server. The default are defaults values for model attributes.

Rendering the view

The most interesting things in Backbone.js app is happening in Views. Add new file to `views` folder - FeedbackView.js.

The skeleton of view would look like this:

var FeedbackFormView = Backbone.View.extend({
   className: 'row',

    render: function () {
        return this;
    }
});
    

This view, does do nothing. So, let make it render the template. The template would be very simple form.

There are different approaches, there to actually place the markup. It’s possible to place it in the same .html file where view starts and extract it by jQuery, it’s possible to place to separate file and load it asynchronously by $.get(). But, according to baby steps scenario - we’ll place it directly to .js file. So, inside the view we’ll add property called template.

template: '\
 <form>\
  <legend>Share the feedback</legend>\
  <div class="control-group">\
   <label>Email</label>\
   <input type="text" id="email" placeholder="Your email address...">\
  </div>\
  <div class="control-group">\
   <label>Web site</label>\
   <input type="text" id="website" placeholder="Your website...">\
  </div>\
  <div class="control-group">\
  <label>Feedback</label>\
  <textarea id="feedback" class="input-xxlarge" placeholder="Feedback text..." rows="6"></textarea>\
  </div>\
  <button type="submit" id="submit" class="btn">Submit</button>\
 </form>\
',
    

And render method, would be:

render: function () {
    this.$el.html(this.template);

    return this;
}
    

First test

Basically, we are ready to see some results. Modify the target view by adding references to model and view.

<script src="/scripts/src/models/Feedback.js"></script>
<script src="/scripts/src/views/FeedbackFormView.js"></script>
<script src="/scripts/src/apps/FeedbackFormApp.js"></script>
    

Fire up the application and go to target page. You should be able to see something like this (for styles I use Twitter Bootstrap here).




If you see the form on screen, it means application started properly.

Submitting the form

We enter the data into input fields and as soon as data is in-place we are ready to submit. It means we have to catch an event of `Submit` button click and store the model to server.

To explain to Backbone.js that you interested in particular DOM event, you need to add another property to view. It is called events.

events: {
    'click #submit': 'submitClicked'
},
    

You can read it as - if click happed to element with id `submit`, call function submitClicked.

submitClicked: function (e) {
    e.preventDefault();

    var options = {
        success: function () {
            alert('Thanks for the feedback!');
        },
        error: function () {
            alert('Opps, your feedback has not been submitted, please try again.');
        }
    };

    var feedback = {
        email: this.$('#email').val(),
        website:  this.$('#website').val(),
        feedback: this.$('#feedback').val()
    };

    this.model.save(feedback, options);
}

What it does, is first of all prevent the default behavior of event. So, the form would not be actually posted to server. Second, it prepares the options object’s with success and error handlers. After we initialize all attributes with actual values from corresponding inputs/textbox. And finally we call model.save().

Second test

Fire up application again. Now, if have properly set-up server side to receive the HTTP post call to `/feedback` you actually post first feedback.




From my server trace, I can see that new object is received.




Now, it’s the server job to put to storage, allocate the id etc.

Conclusions

In this first baby step, I just showed how it’s possible to adopt Backbone.js for existing apps. It does not make a lot of sense to re-write your existing code with Backbone.js, but new widgets/elements/applications could be created with Backbone, having a benefit of it’s structural approach.

I’ll go on with baby steps, showing other features of Backbone.js.

Looking at TypeScript

Four days ago my twitter has been nuked. The bomb has exploded after TypeScript site link has reach to top of Hacker News and people watched the video of Anders Hejlsberg who generally described the language features and showed some example. Everybody were talking about TypeScript.

For ones who missed the video (I can’t believe you did) I shortly describe - TypeScript in new open source project, by Microsoft. It’s leader Anders Hejlsberg is very famous developer (my bad, I always forget his name), creator of C# and one of the persons who most influenced .NET platform. TypeScript compiled down to JavaScript, but it introduce the types checking during compilation, so it could be called ‘static typed language’.

First of all, TypeScript is definitely not the first language, that complies to JavaScript. It’s not the first one that augments JavaScript with new statements like class, interface or module. So, what’s so interesting on it?

I’ve been using static type languages for about 10 years. I’ve very much got used to compiler error messages and truly believed that it helps to build applications. Meaning, the complier is first guard towards the ‘good’ code. To the code that could be called reliable, error free.

But situation much changed after I start programming JavaScript.

I feel myself quite productive with using of using JavaScript. Of cause, there are some best practice & patters are collected nowadays, we have better tools, faster engines and JavaScript has been so much adopted by community. But JavaScript is indeed, so powerful language. I really like the dynamic typing, that bit more forces to unit testing, making code changes more easy in the same time creating some very beautiful code structures.

I know that some people are saying, “we don’t need any static typing for JavaScript; please don’t change the language”. Such developers could be called “purists”. And they are absolutely right - if you feel confidence in something you do, you should not change the way you do it.

In another hand, I came to conclusion that it’s not dynamic types that makes me productive with JavaScript, but rather the experience I gathered with programming lately. It’s always only experience, that allows you to work faster, better quality and had fun of your job.

And it’s absolutely not about Static vs. Dynamic languages.

Static types are not useless, though. I think, in average it reduces the chances of bug introduction into the code. That’s at least what I’ve seen so far. And that’s why “purists” are running JSLint. Basically, Static Types should provide better application quality. This is of cause not completely true, since we know great software written in Python and poor systems written in C++.

It’ about the engineers who build that software.

In my opinion the TypeScript will grow. It would have it’s own army of fans, like CoffeeScript have or Ruby have. The code that TypeScript outputs is nice and clean, that make easy of debugging it. TypeScript is designed to be closer to ECMAScript6 (Harmony), so in near future the pure JavaScript would start to look like TypeScript.

TypeScript is interesting project and open minded guys will like one.

The Game of Life

Last weekend the good friends of mine were organizing great event, CodeRetreat in Odessa. I supposed to be there, but due to bad luck I missed that. Nevertheless, I was very interested in CodeRetreat idea, so I followed up the materials and learned a bit about it.

CodeRetreat is about the software craftsmanship. You focus on 4 principles of Simple Design, work in pairs through the series of time boxed sessions, each time starting from scratch (yes, all code produced on previous sessions is destroyed with no mercy). All of that aim one simple goal, became a better developer. For the implementation they selected famous Game of Life. The cellular automata, with simple rules but given very interesting results and foundation for numerous researches.

To do not stay with my misery of missing event, I decided to “play” game of life at home. Trying to follow the rules of sessions, I started to write some JavaScript code. It’s even hard to tell, how much fun I had during this implementation.

Tests, code, tests

TDD is very recommended way of development in CodeRetreats. I love TDD and fortunately the game of life is very TDD friendly. It’s all about the logic. Logic seems to be very simple and easy describe with tests. For my JavaScript testing I used to use Jasmine testing framework. Jasmine is BDD tests style, which was a little difficult to me at very beginning, but not I tend to write all my tests with BDD style.

I’ve spent first two sessions for idea elaboration. At the end third session, I got something working. As I said, the process of writing that code was so fun to me, that I even decided to gist the code I created so far.




My big disappointment after was that code is actually not working.

Understanding the problem

Even if I had good tests suite, that showed my code works as expected the game was broken. And the issue is that I didn’t understand the domain good enough. It took me 4 sessions (about 4 hours) to finally understand the game.

I proved it once again for myself, there are no perfect code; the code you created at first time is probably broken (unless you understand the domain perfectly, but it’s rarely happen in reality). It’s OK to completely remove the code you created before and start from the beginning. And with each iteration you moving faster and faster.




Knowing the requirements I was able to create good test suite.

Algorithms and data structures

During the implementation, you have to recall some basics algorithms and data structures. My initial implementation was based on usage of 2-dimensional arrays. It seems to be very natural fit, since the game is happening on orthogonal grid of square cells. But during the implementation of cell replication logic I suffered that design.

Index arithmetic is very tricky and error-prone stuff. So, after several tries I switched from array into the list of cells, each cell holds it’s state and position. The tick method of became very elegant, containing 2-pass procedure - one to calculate next state of each state, second is to switch to new state.




Again, I was so happy with code. It looked very readable as for me, without nested cycles and if-else statements.

Visualisation

You can really understand if something works or not, only if you see it in action. I had to have some UI to see, how game is actually working.

I’ve created very simple HTML based UI. The number of div’s which change it’s state, depending on cell state (alive or dead).




The visualization of results is very important part. It’s only then I tried to run the game on 64x64 square, I realized that performance of my implementation is so terribly poor. It runs very slowly on Chrome, it makes IE10 die.

It means that, all beautiful code, tests, specs and so on - is almost useless, than it comes to performance. My 2-pass algorithm, with a simple implementation is not “production” ready, if we talk about some real software. Unit tests are usually done on smaller sets of data. Visualisation and trying the things on larger set of data opens up the reality.

Conclusions

As I already said, it’s so much fun. It makes you feel like “back to roots”, forget about your enterprise stuff and do some real work. Besides it’s great TDD exercise. It’s probably to big to be called code kata, but it is still great for sharping an axe. Focusing on simple design is important. But making things “visible” and running them in real mode is vital.

The most important conclusion for me is: I’m still newbie developer, with so many areas to improve.