Wednesday, November 21, 2012

CSS3 animations made easy with SASS

With CSS3 a lot of goodies have been made available out of the box with HTML. One of these goodies is the ability to use animations.  The problem is, that different browser vendors have created different CSS properties to support these functionalities.  This requires you to copy those vendor tags over and over again.  This make your CSS bigger then it needs to be, and hurts to the readability of the styles.

One way to deal with this is by using SASS, which is a meta language written on top of CSS allowing you to write "CSS" in a structured way while also supporting mixins and other goodies.

SASS can be easily installed as a Ruby gem, and you can make it watch a "scss" file and automatically generate your CSS files.

As an example, let say we have a webpage with a "<div class='box'/>".  We want that box to have a certain size, on hovering we would like to make that size grow.  In CSS you could do something like this : 
.box {
  -webkit-transition: height 1s;
  -moz-transition: height 1s;
  -o-transition: height 1s;
  -ms-transition: height 1s;
  transition: height 1s;
  width: 100px;
  height: 20px;
  background: #00F; 
}
.box:hover {
    height: 100px;
    -webkit-transition: height 1s;
    -moz-transition: height 1s;
    -o-transition: height 1s;
    -ms-transition: height 1s;
    transition: height 1s; 
}
While this works, it has quite a lot of repetition, and that kind of hides the more important properties.  In this case: the height that changes from 20 to 100 pixels.
Using SASS you can make this a lot more concise, improving readability. We can get rid of those vendor properties, resulting in a much shorter CSS that clearly describes what we want.
.box{
    @include animate(height);
    width: 100px;
    background: #00F;
    height:20px;
   &:hover{ height:100px; @include animate(height); } }
Notice we are using indentation for the hover selector, and it is contained within the parent CSS closure. This clearly expresses the inheritance of those properties.
We are however cheating a little. As you may have noticed I am including an "animate" mixin. The animate method doesn't come out of the box, you have to write it.
This is trivial however, you can pass in the desired property and apply it to all vendor properties.

We can also use variables within SCSS, this makes sure you never have to copy the same color code over and over again. Or for our example, we can make all animations take the same amount of time (1s).  
$animationTime : 1s;

@mixin animate($property){
    -webkit-transition: $property $animationTime;
       -moz-transition: $property $animationTime;
         -o-transition: $property $animationTime;
        -ms-transition: $property $animationTime;
            transition: $property $animationTime;
}

Saturday, November 3, 2012

Writing Javascript tests for Mocha in CoffeeScript

These days I am working a lot with JavaScript, for testing, we chose to write readable tests in CoffeeScript, and executing these in Mocha.

Testing your code in JavaScript, to me, is even more important then in a compiled language (for example: C#), because you miss the convenience of a compiler that will already check your syntax. 

Using CoffeeScript in combination with Mocha-Cakes, I find, makes your tests very readable.
Mocha Cakes provides the Given/When/Then syntax, allowing you to clearly explain the behavior.

Lets say we want to test the following piece of code, written in JavaScript : 
var Foo = function(config){
    this.config = config;
}

Foo.prototype = {
    getAnswer: function(){
        return this.config ? "Bar" : "Bazz";
    }
}
module.exports = Foo;

We might want to write a test, to test the behavior based on the configuration that is given to Foo.  That test might look something like this, written in CoffeeScript.
Foo = require "../js/foo"

Feature "Foo, In order to get an answer as a user I want to get a result", ->;
    Scenario "With a configuration", ->;
        Given "Foo is created with a configuration", ->;
            @foo = new Foo("showBar")

        When "An answer is requested", ->;
            @response = @foo.getAnswer()
 
        Then "Answer given is 'Bar'", ->;
            @response.should.equal("Bar")

    Scenario "Without a configuration", ->;
        Given "Foo is created without a configuration", ->;
            @foo = new Foo();

        When "An answer is requested", ->;
            @response = @foo.getAnswer()

        Then "Answer given is 'Bazz'", ->;
            @response.should.equal("Bazz")
This syntax is very readable and allows you to quickly understand what is going on, and what behavior is expected.

To get mocha to run your CoffeeScript tests, you will need a "mocha.opts" file, containing the options that mocha will use.

--require should
--require mocha-cakes
--reporter spec
--compilers coffee:coffee-script
--recursive

When everything is up and running, when starting mocha in the command line, your test result should look something like this: