lördag 14 mars 2015

ES6 & TDD: Can I test it?

(Yes you can!)

I like the style of Test Driven Development (TDD), dead or not. I have been using TDD mainly for server side code with C# and NUnit. I think the benefits of writing unit tests for client side code is obvious. Now, with ECMAScript 6 (ES6), we have cool stuff like modules, promises, iterators ... is ES6 testable?

Interested in test driven JavaScript in general? Check out From the Streets of Test Driven Development: JavaScript.


Write, transpile, test?
To use all those cool new JavaScript features today, the source code need to be transpiled to a version that browsers support. What about the unit tests (that is also written in JavaScript)?


The unit tests can (of course) be written in old school JavaScript (ES5). But I think the context switch between the two (ES5/ES6) probably would break the flow. I would like to write both the unit test and the code in ES6. How about using Babel to transpile them both?

Check out my earlier post about some tools I use (like Babel): Sublime ES6 coding - the tools and the flow

QUnit and ES6 arrow functions
I like the simplicity and the basic TDD style of QUnit. I like the words test and assert. Jasmine and Mocha are cool to, using the behavior driven style of writing, but I prefer the classic TDD approach. Maybe it's a mindset thing? 


QUnit uses a test runner, that is where the unit tests are started. The test runner is an html file and lives in a browser (or in PhantomJS). That's the old school world. Transpiled versions of unit tests and transpiled production code will run there. There are some things to think about. QUnit doesn't identify itself as a loadable module (yet). Instead, a variable is added to the global object. By default, QUnit will run when the DOM is loaded. When used with AMD, QUnit have to be paused until the unit test modules are loaded. In this example, I have transpiled ES6 code to AMD modules (RequireJS) using Babel. The test runner is loading a single file that will import all my unit tests.

You will find unit tests, code, settings, project structure and setup on GitHub: 

ES6 and TDD

Example - the script section of the test runner html file, written in old school JavaScript:

(function () {
  'use strict';

  QUnit.config.autostart = false;
 
  require(['script/transpiled/start.js'], function () {
    QUnit.load();
    QUnit.start();

  });
}());



The contents of start.js, importing all unit test modules, written in ES6:

import {} from './modules/exampletest.js';


The unit test, written in ES6:

import foo from 'modules/foo';

QUnit.module('my example tests');

QUnit.test('will this work?', assert => {
     const expected = 'hello foo';

     assert.equal(foo.message, expected);
});


The code under test, written in ES6:

let foo = {
     message: 'hello foo'
};

export default foo;
 


The require and imports of the test runner and start.js uses relative urls. That is because I use the same base url as the production code. This enables the simple kind of imports done in the unit test. The code there is written in the same way it would in the production code.

Run with Gulp 

I use Gulp to automate a lot of things: transpiling with Babel, checking for syntax errors with JSHint and running QUnit tests with PhantomJS (i.e. no browser required). All of these will execute as soon as any ES6 file is changed in my project. By doing that, I will get instant feedback without having to interupt the flow.

Give the code a try and let me know what you think about it. What aspects am I missing? What can be improved, changed, refactored?

You will find unit tests, code, settings, project structure and setup on GitHub: 
ES6 and TDD

torsdag 12 mars 2015

Sublime ES6 coding - the tools and the flow

Sublime Text 3 and JavaScript - a nice combination
A while ago, I decided to give Sublime Text a try when learning ECMAScript 6. I mostly use Visual Studio, and with Sublime It feels like I'm on a diet! As a side effect I am also learning a little bit of Node, because many packages are based on tools installed with the Node package manager (npm). 


ECMAScript 6 (ES6)
In order to get full ES6 syntax, I have installed the babel-sublime package. Enable the package by open or create a file with a .js extension, select View -> Syntax -> Open all with current extension as ... -> Babel -> JavaScript (Babel).





JSHint
I think JSHint does the job well also with checking for errors in ES6 code. I have only found one issue - grouping exports in a module - but I can live with writing separate multiple exports until it is fixed. I think ESLint also looks very promising, but for now I will keep using JSHint.

SublimeLinter-jshint


Linting ES6?
Selecting Babel as the default syntax for .js files will actually disable the JavaScript linting. The SublimeLinter settings file need syntax mappings for Babel (the selected row in the image below). Add the row and the linting will be enabled again.  




Share the Rules
Instead of adding comments to every single .js file (like the esnext option), I use settings files (named .jshintrc). Are you on a Windows machine and can't create file names starting with a dot? Save the file with the name jshintrc, and rename it from the command prompt using the "ren" command:  

ren jshintrc .jshintrc

Transpile to old school JavaScript with Babel
Using Babel from the command line is really simple and it runs fast.
This command will create JavaScript RequireJS style modules (AMD):
babel my/es6/path --modules amd --out-dir destination/path

But running a command after each code change is an interruption, a manual step that should be automated. I use Gulp to run Babel commands and watcher to track changes in files.

Keep the flow with Gulp
With Gulp running in the background, each file change will trigger lint rules validation, ES6-to-ES5 transpilation and unit tests. An example:


var gulp = require('gulp');
var newer = require('gulp-newer');
var babel = require('gulp-babel');
var qunit = require('node-qunit-phantomjs');
var jshint = require('gulp-jshint');
 

gulp.task('lint', function () {
    return gulp.src(source)
        .pipe(jshint())
        .pipe(jshint.reporter('default')) // linting passed
        .pipe(jshint.reporter('fail')); // linting failed
});


gulp.task('transpile', function () {
    return gulp.src(source)
        .pipe(newer(destination)) // is the file changed?
        .pipe(babel({modules: 'amd'})) // run babel and pass options
        .pipe(gulp.dest(destination));
});


gulp.task('qunit', function () {
    qunit('path/to/qunit/testrunner.html', { 'verbose': false });
});


Test Driven ES6 Development with QUnit
This is a separate blog post. Stay tuned!  

Update: Here it is the post: ES6 & TDD - can I test it?

torsdag 5 mars 2015

What? Wait. Really? Oh no! (a post about ES6 classes and privacy)

ECMAScript 6 is here with lots of new features, one of them is the class keyword. Yes, we can now write classes in JavaScript. You knew that already, right? Happy, pappy? 

I guess that about half of the World population currently is doing an imaginary High Five, the other half is probably planning a revolution (or will they just write a function?). Class is a controversial thing in society.

I am not that thrilled about it, but classes are here and will be used. Heavily. JavaScript classes are however a bit different from the ones written in C# or Java. How do I write a property? Are the properties I add private or public? Most of the examples I've seen in blog posts and presentations look something like this:

class myClass {
     constructor(firstName) {
          this.firstName = firstName;
     }
}


Is "firstName" a private property? Nope. It is publicly accessible - everyone can read and change it. If you have ever used function constructors, the behavior will be familiar. Everything added to an object using the this. syntax will be public.


Is it obvious that classes will work the same way? I don't think it is. I think the word class itself implies that certain functionality should be present. Especially for programmers coming from C#, Java or any other object oriented language. In JavaScript, classes also can only contain methods. Private variables cannot be added in the class body in the same way we are used to in C#. This code will throw an error:

// will this work? (No.)
class myClass {
     let _firstName = ''; // illegal syntax
}

Almost private?

To make a property almost private, you could use the new Symbol data type to generate a property name and store it in a Module together with the class. A symbol is a unique value (like a GUID) and will (most likely) prevent properties from being overwritten by code that consumes it.

An example:

// myModule.js
let first_Name = Symbol();

// How about this, will it be private? (No.)
class myClass {
     constructor(firstName) {
          this[first_Name] = firstName;
     }

     get name() {
          return this[first_Name];
     }
}

export default myClass;


This won't make the property private, because all keys of an object (including symbols) can be accessed using the Reflect object or the getOwnPropertySymbols method of the current object.


Really private?

I have searched for and found the following solution to be good enough for creating private properties in JavaScript classes: using WeakMaps (also new in ES6). This data structure will keep track of your property names and keep them private (as long as you don't export them, of course). The data in a WeakMap is linked to the source object and will also be garbage collected when the source object is removed.

// myModule.js
const first_name = new WeakMap();

class myClass {
     constructor (firstName) {
          first_name.set(this, firstName);
     }

     get name() {
          return first_name.get(this);
     }
}

export default myClass;


By adding the current instance of the class and the actual property value to a WeakMap, we have the behavior of private variables. If this class is extended (inherited), the properties cannot be accessed directly, since the WeakMap only exists in the module. You can't have it all, I guess.

Is it worth it?

I don't know. Time will tell. Personally, I think I mostly will use simple Modules and export object literals. Or why not use a plain old Immediately Invoked Function Expression (including private variables and methods) instead of complicating things with classes?


Update:
@stevenlangbroek has shared a nice alternative solution. I think looks like a hybrid between a class and an Immediately Invoked Function Expression. Check it out! Private variables in ES6 classes

måndag 23 februari 2015

Yeah, we got classes now (ES6). You happy, pappy?

Since the beginning of time, JavaScript has been the class less society. Everyone had a function there. With ECMAScript 6, classes have now been added. Ah, man.

Wait, wait, wait! I actually like it. I believe the class keyword is good thing to JavaScript, mmkay?

There is quite a few frameworks out there that already have introduced classes (or class like solutions) to the language: Dojo, Prototype, CoffeScript, TypeScript ... They all have their own way of doing it. ECMAScript introduces a common way of how to write a class, and that itself is great. How can classes be useful in JavaScript?

I think it can simplify the structure of code, we can write functionality that is only accessible within a class. But then again, we have modules now. A module can export an object and keep code private. Why use classes?

Well, I think the benefit of writing a JavaScript class is inheritance (using the extends keyword). Inheritance can of course also be accomplished by creating literal objects extending other objects, simply by adding properties and methods to it. But the functional inheritance style looks kind of awkward sometimes. Writing a class that extends another class will probably make more sense. Especially for programmers used to write code in c#, java, Ruby or any other object oriented language.

However, I don't think consuming a class the traditional way is a good idea in JavaScript. I think it is an anti-pattern. Creating instances of classes using the new keyword spread out all over the code base? Don't do it! 


In sucks in c#, it sucks doing it in JavaScript too. Dependency Injection and IoC containers solve the "newing up classes problem" in c#. How about JavaScript?

Here's a suggestion.

Create your classes in ES6 modules. Export an already created instance (if you want a singleton like functionality), or export a "make" method that returns a new instance of the class.

By doing that, the consumer doesn't have to worry about if the code within the module is a class or an object literal.

An example:

// the foo module, exported as a singleton
class foo {
     constructor() {
          // constructor code here
     }

     myMethod () {
          // method body code here
     }
}

export default new foo();


// the foo module, exporting a "make instance" method
class foo {
     constructor() {
          // constructor code here
     }

     myMethod () {
          // method body code here
     }
}

let makeFoo = () => new foo();

export default makeFoo;



Using the first example, the consumer will get a baked and ready instance of the foo class. The second example will give the consumer the ability to get different instances, by calling the make function. The actual structure (currently a class) of the module is hidden, and not a part of the API.

What do you think about this? Let me know!






" - Happy, Pappy?"





söndag 22 februari 2015

Is the ES6 import feature an anti-pattern?

The new version of JavaScript is currently occupying my mind. I really like the ECMAScript 6 features, and the fact that we can write code using new stuff like arrow functions, scoped variables and native modules today (by using transpilers) is quite awesome.

There is especially one of the ES6 features that I've been thinking about: importing of modules. Modules will change the way we think about JavaScript for the web. Importing a module is so easy with ES6 and the syntax is very nice, readable and clean. How do I unit test such a module?

The import statement uses a relative url to perform the module lookup. So, can I somehow configure a "base test suite url" to load fake modules that my module under test is dependent of? Would that require me to write a lot of stubs (files)? Is it even possible, without writing a custom module loader? That's the things I have had on my mind, for a couple of days now.


See, these days I mostly think about code and don't actually write code that much. How come? I am currently enjoying life as a swedish dad on paternity leave. The days with the one year old are great. We read books, build with blocks and laugh a lot. I love it.

When he is sleeping, I catch up on coding by reading blogs (mostly one of the great posts on ES6 by Dr. Axel Rauschmayer) or watching a video tutorial (I recommend the ES6 course on Pluralsight, by Scott Allen and Joe Eames). I am learning new things, slowly, but scheduled and at a steady pace.

Tonight, just when I had finished reading a Pippi Longstocking bedtime story to our four year old son (the big brother), the background process of the brain suddenly sent me a message: keep it simple. Use dependency injection. Dave, you know this already. I think the new syntax and the new ways of writing has blinded me, made me forget about concepts I normally use when writing c# or old school JavaScript (pre ES6).

How about writing modules with dependencies injected, by exposing something like an "init" function, instead of directly importing them? That would make them testable. Something like this:


// foo.js
let message = 'My name is foo';

var foo = {
    getFoo() {
        return message;
    }
};

export default foo;


// bar.js - dependent on foo.js 
let message = '';

var bar = {
    init(obj) {
        let foo = obj.getFoo();
        message = `${foo}bar, and I am foonky`;
    },
    getBar() {
        return message;
    }
};

export default bar;


//app.js
import foo from 'modules/foo';
import bar from 'modules/bar';

// inject dependencies
bar.init(foo);

console.log(bar.getBar());


 

Please let me know what you think about it!