Wednesday, September 21, 2011

.Net and WinRT

Well, I have to say, Microsoft is making a bold move with .Net and Windows 8. It seems like they're betting that what people use computers for has essentially been established, and it isn't what we're used to.  Basically, they're betting the company that people don't want computers they sit in front of and type on all day.  Instead, they want something smaller, something that has a tactile interface, that allows them to read email, watch movies, check bank accounts, maybe create an occasional document, and so on.  What they don't really want is what they have - workstations, notebooks, things that require a keyboard, a mouse, and an investment of time to use.

I think they're probably right in broad strokes, but the devil will be in the details.  Microsoft still makes the lion's share of their revenue from operating system and office licenses, last I checked.  It's about 60% of their revenue, in fact.  I think this is the first time they've really done something this radical in those segments.  I mean, what could compare to changing the entire way people interact with their computers? to relegating the workstation role to a small segment of their installed base? Windows 95? not even close if you ask me.

So the Windows 8 development stack is all on top of the Windows Runtime (WinRT), so apps will be developed in a typical web stack (CSS/JS/HTML) and/or in C++.  I'm personally interested in how you effectively merge the two - heavy lifting in C++ via WinRT, and integration and UI with web tech.

So what happens to .Net? Well, you'd better get familiar with Azure.  I think the writing's on the wall at this point, .Net is going to transition to being a cloud development framework, and move away from the client.  No more WPF, WinForms, or anything like that.  I suppose they'll continue to support it in desktop mode, but how many people are really going to use that?  Folks like us (developer-types) will, sure, but let's face it, there's not many of us out there.  I'll be interested to see how long desktop mode sticks around now that's it's essentially yesterday's news.

I've just downloaded the developer preview released from the Build conference. Hopefully, it'll be stable enough to work with a bit.

Monday, September 12, 2011

Behavior Driven Development Presentation

I've been working this week on a guest lecture at the local University on Behavior Driven Development (BDD).  I only have a single class to really go over it, and the audience is somewhat diverse with respect to technical expertise.  The presentation's hosted on my github account, you're welcome to take a look at it, and feel free to comment if you have any thoughts.

Monday, September 5, 2011

Jenkins and Node.js

So I've spent some time with Jenkins lately, and have good news and bad news.  The good news is, yes, you can integrate Node.js projects, tested through jasmine-node, with Jenkins.  Jasmine-node returns appropriate values when executed; 0 on a successful test run and 1 on a test failure.  Furthermore, it does seem you can use git with Hudson/Jenkins.   Integrating a builder that runs jasmine-node tests is possible too, perhaps following the lead of other plugins that have integrated node.js with Jenkins.

The bad news is that the integration is still rough and kinda kludgey, and needs some work from both the Jenkins and the jasmine-node ends to make things work smoothly.  Jenkins needs to support Node.js and Jasmine-node via custom builder plugins.  Furthermore, jasmine-node will likely need to generate test output that Jenkins can use to generate reports, and Jenkins will likely need a custom reporter and publisher of some kind.  This is important work that somebody needs to tackle to make Node.js attractive to professional development teams.  Node.js has some real advantages for developing RPC over HTTP infrastructures without unneeded web server cruft, something really important in next generation systems where web clients use HTML5 technologies like web workers to retrieve and process information, and act more like fully-fledged clients than simple pages as a result.

I'm going to begin to look at these issues, starting with jasmine-node integration and then reporting, in future posts.  I'm also going to start the development of a simple grocery list system using Node.js, HTML5, and likely the Android SDK.

Sunday, August 28, 2011

BDD Testing Example with Node.js and Jasmine

In Node.js at least, using jasmine is pretty straightforward.  We can use standard Node.js require(.) semantics to include the modules we're testing.  In the prior examples, we defined a couple of modules, one that defines a random number generator and another that returns the current date.  Here, we're going to write some simple specifications we can use to test the services.

First, in the project, create a spec directory.  I created it right next to the lib directory, which holds my source files.  Once that's in place, you can create your specifications. The first specification, the date specification, tests the date service.  You can include the date service source files with using require(.):

var date = require('../lib/date').date;


describe('date specification', function(){


  it('should return a valid value', function(){
    var generator = new date.Generator();
var value = generator.generate();
expect(value).not.toBeNull();
  });


it('should return the current date', function() {
var generator = new date.Generator();
expect(generator.generate().toString()).toEqual(new Date().toString());
});


});


This, we can run this with jasmine-node by executing the command line 'jasmine-node spec' in the directory containing the spec subdirectory.  We can then create an additional suite of tests for the random service:


var random = require('../lib/random').random;


var SEED = 10;
var LOW_SEED = 2;
var MED_SEED = 50;
var HIGH_SEED = 1000;


var evaluator = function(seed) {
var generator = new random.Generator(seed);
var value = generator.generate();
expect(value).not.toBeNull();
expect(value).toBeGreaterThan(-0.001);
expect(value).toBeLessThan(seed);
};


describe('random specification', function() {

it('should return a value between 0 and the seed', function() {
evaluator(SEED);
});

it('should work with a variety of seed values', function() {
evaluator(LOW_SEED);
evaluator(MED_SEED);
evaluator(HIGH_SEED);
});

});

Now, when we execute jasmine-node, we see this (note, I'm using verbose mode here):

prompt> jasmine-node --verbose spec
Started
....


Spec date specification
Spec random specification
Finished in 0.004 seconds
2 tests, 14 assertions, 0 failures

Now we've successfully integrated our jasmine-node tests into our repository, and we can execute them from the command line.  The next step is to integrate them with a continuous integration system like Jenkins.

Saturday, August 27, 2011

Testing JavaScript with Jasmine and Node.js

To extend our previous example, there's a couple of tools you can use to test your code in a Node.js environment.  One of the most stable, and the one I'm planning to use, is jasmine-node, installable via npm or downloadable from git.

First, to install using npm, you'll need to use the following command-line (after, of course, you've installed npm itself):

prompt > sudo npm -g install jasmine-node

You'll get output like this:


/usr/local/bin/jasmine-node -> /usr/local/lib/node_modules/jasmine-node/bin/jasmine-node
jasmine-node@1.0.6 /usr/local/lib/node_modules/jasmine-node 
└── coffee-script@1.1.2

Sweet! You are now able to do behavioral-based testing of your Node.js code!  Here, on m mac, the -g  option was required.  Anyway, if you look at the output, you'll notice that you now have a command jasmine-node that's installed in /usr/local/bin (which is why you needed to run this via sudo).  Assuming that's in your path, you can test your installation:

prompt> jasmine-node

Which should give you the output:

USAGE: jasmine-node [--color|--noColor] [--verbose] [--coffee] directory

Options:
  --color      - use color coding for output
  --noColor    - do not use color coding for output
  --verbose    - print extra information per each test run
  --coffee     - load coffee-script which allows execution .coffee files

So if you see this, you know you've got it installed.  So let's do a bit more testing to ensure everything's looking good.

If you go to the git site where jasmine-node is hosted, you'll see a reference in the readme to a javascript test file.  You'll need to drop that into a directory named spec, and then we should be ready to test.  I'm using both a JavaScript and a CoffeeScript file, provided by Miško Hevery, jasmine-node's creator.

Once you've copied both of those files into a spec directory, cd to the directory directly above the directory you just created, and you can execute the tests like this:

prompt > jasmine-node spec

This will give you the following output:

Started
..

Finished in 0.011 seconds
1 test, 3 assertions, 0 failures

But wait, where's the CoffeeScript test? It's there, but you need to use the --coffee flag to get it to execute:

prompt > jasmine-node --coffee spec

Then you'll get what you expect:

Started
...

Finished in 0.013 seconds
2 tests, 4 assertions, 0 failures

That's it! You've now installed jasmine-node and you're ready to start testing your work.  In the next post, I'll go over how to import and test code from the random date server example.  Further upcoming posts will include using Node.js and HTML5 to implement an RPC infrastructure over HTTP with rich internet clients.  Prior to that, I'll explore how you can structure these kinds of projects in Git, hopefully including integration with Jenkins.

Wednesday, August 17, 2011

Design Primitives in Javascript: Pulling it Together

Now to pull together the components into a functional random number and date server!  I'm certain to get loads of venture funding for this highly in demand service, something to look forward to.

Anyway, at this level, I maintain two modules.  The first, the Node.js entry point, starts the server with callbacks defined in the main module.  To be precise, the first file is not actually a module as we've defined modules so far.  Rather, it's a simple script calling the appropriate bootstrapping methods:

(server.js)

var net = require('net');
var main = require('./main').main;


net.createServer(main.connection_listener)
  .listen(1337, "127.0.0.1", main.event_listener);

That's it! Pretty cool.  This just spawns a server on port 1337 using listeners defined in main, where the bulk of the communication implementation resides:

(main.js)

var version = require('./version').version;
var date = require('./date').date;
var random = require('./random').random;


exports.main = function() {



  // This is a private class object used to build 
  // the response generator needed based on the 
  // type of request. The dispatch(.) method takes 
  // a string and then calls the corresponding 
  // factory method based on the predefined module 
  // interfaces (see the previous two posts for 
  // more information on  those interface 
  // definitions).  If someone  requests an 
  // operation we don't recognize, we create an
  // anonymous class object implementing 
  // the generator interface.
  var _processor = function() {

    var SCALE = 10;
    var DATE = 1;
    var RANDOM = 2;
    var UNKNOWN = 3;

    var parser = function(cmd) {
      if (cmd.match(/date/ig)) return DATE;
      if (cmd.match(/random/ig)) return RANDOM;
      return UNKNOWN;
    }


    this.dispatch = function(cmd) {
      var generator;
      switch(parser(cmd.toString())) {
        case DATE:
          generator = new date.Generator();
          break;
        case RANDOM:
          generator = new random.Generator(SCALE);
          break;
        default:
          generator = new function() {
            this.generate = function() { 
              return 'undefined token submitted.';
            }
          }
      }
      return generator.generate();  
    }

  }



  // This is a private function building a version 
  // string using information defined in the version
  // module.
  var _build_version_string = function() {
    return version_string = version.major + '.' 
      + version.minor + '.' 
      + version.patch + ' - '
      + version.status;
  }



  // The server entry point.  We write output to the 
  // requestor socket as well as debug information 
  // to the console, first. We then define a handler
  // for submitted data using our private processor
  // class.  The handler processes the request
  // and emits a bit more status information to the
  // console.  Finally, we drop binding status to the
  // console and return.
  var _entry_pt = function(socket) {

    socket.write('date & random server: ' 
      + _build_version_string()
      + '; enter command\r\n', 
      'ascii', 
      function() { 
        console.log('...welcome sent to ' 
        + socket.remotePort 
        + '@' 
        + socket.remoteAddress); 
      });

    var processor = new _processor();


    socket.on('data', function(data) {
      console.log('data received: "' + data + '"');
      var retval = processor.dispatch(data);
      console.log('response: ' + retval);
      socket.write(retval + '\r\n');
    });


  }


  var _event_listener = function() {
    console.log('...server has been bound.'); 
  }


  // The module signature implementation.
  return {
    connection_listener: _entry_pt,
    event_listener: _event_listener
  }
}();


Note the comments above describing what's what in the implementation module.


Now, to run this on the command line type:


$ node lib/server.js


This'll bootstrap the server and kick it off, sending confirmation messages to the console.  To connect, use telnet:


$ telnet localhost 1337


And you'll be greeted by the smarmy welcome screen:


Connected to localhost.
Escape character is '^]'.
date & random server: 1.0.0 - gold; enter command

From here, you can type random or date.  The response will be either a randomly generated number or the current date.  That's it!  Now, I would generally not do something even this trivial without some kind of unit test support.  Next, I'm going to delve into how you can integrate Jasmine with Node.js to do test driven development.

Thursday, August 4, 2011

Design Primitives in Javascript: Example Modules, Classes, Functions

Okay, so we defined the modules I'm using in the last post; here, I'll show you the code associated with the version, date, and random modules, and explain what it's doing.

We'll start with the version module as it's the simplest:

(version.js)

exports.version = {
major: 1,
minor: 0,
patch: 0,
status: 'gold'
}

That's it.  Notice, this is an implementation of the versioning interface we defined previously.  We're exporting the version information in an object literal, in the version property, so you reference it from including files using require like this (this assumes side-by-side installation of library files with the server script):

var version = require('./version').version;

The date generator is a little more complex, but not very:

(date.js)

exports.date = function() {


  var _date_generator = function() {
    this.generate = function() {
      return new Date().toString();
    }
  }

  return {
    Generator: _date_generator
  }
}();

Note I've used the module pattern here.  That allows me to define the Generator class based on the private implementation class named _date_generator.  I include and use this class this way:

var date = require('./date').date;
...
var generator = new date.Generator();
var date = generator.generate();

Finally, the random number generating class, using a nifty private variable:

(random.js)

exports.random = function() {

  var _random_generator = function(scale) {

    var _scale = scale;

    this.generate = function() {
      return Math.floor(
        Math.random() 
        * _scale)
      .toString();
    }
  }

  return {
    Generator: _random_generator
  }
}();

Again I use the module pattern, and this time as an added bonus, I use a private variable (i.e. _scale, in the _random_generator class).  Include and use like this:

var random = require('./random').random;
var SEED = 10;
...
var generator = new random.Generator(SEED);
var randomNumber = generator.generate();

And finally, notice that both generator classes adhere to the Generator interface defined in the previous post!  Anyway, that's it for the modules that do the domain work of the service.  Next I'll go into how to get this to work with the network communication plumbing in Node.js.