My JavaScript book is out! Don't miss the opportunity to upgrade your beginner or average dev skills.

Saturday, February 18, 2012

JavaScript Test Framewors: more than 30 + 1

After @szafranek hint and suggestion, wru landed almost at the end of this Wikipedia List of unit testing frameworks page.

If you use this tweet size hand made imperfect script in the wikipedia page console:

a=q="querySelectorAll",[].map.call(document[q](".mw-headline,.wikitable"),function(v,i){i%2?a=v.textContent:o[a]=v[q]("tr").length},o={}),o

You gonna see that JavaScript is third when it comes to number of test frameworks ... and not sure that's good, anyway, here a quick description of mine.

About wru

You can find most info in github page itself but essentially wru is a generic purpose, environment agnostic, JavaScript tests framework compatible with both client and server, where client means every bloody browser, and server means Rhino, node.js, and recently phantom.js too.
To be really fair, wru is not exactly a unit test framework since it does not provide by default anything related to mocks or stubs.
However, wru is so tiny and unobtrusive that any 3rd parts library could be integrated without effort in whatever test you want + need.

wru In A Nutshell

Well, the first thing to do with wru is to write code such:

wru.test([
{
name: "the test name, for feedback purpose",
setup: function (obj) {
// the OPTIONAL setup property performed before the test
// obj will be a freshly new created object
// with a single test lifecycle ... reusable within the test
},
test: function (obj) {
// obj comes from setup, if any
wru.assert(true); // a generic truish condition
setTimeout(wru.async(function () {
// a generic asynchronous condition
// where you will inevitably assert something
wru.assert("this is also true", true);
}), 1000);

// the handy possibility to reuse assert itself
if (wru.assert("this is a truish value", obj)) {
// do stuff with obj
// or simply log the object
wru.log(obj);
}
},
teardown: function (obj) {
// the OPTIONAL teardown property performed after the test
// obj comes from the test function, is the same
// passed through setup, if present, and test
}
}
]);

After this you are basically ready to go.
Both assert() and async() accept one up to two arguments: the optional description of the test, recommended if you want at least understand what's going on and where if something failed, and the second parameter which is returned in both cases.
Via assert() the condition/expression is evaluated as it is, truish or falsy, and returned if addressed.
Via async() the callback is wrapped in an unobtrusive way and this is simply to let wru know that something is going to happen, hopefully in a reasonable timeout of 10 seconds.

How To See Results

Once you have your test in place, you can re-use the same code all over supported environments.
The cool part about wru is that templates for all scenarios are automagically created at build time.
You don't even need to npm install wru to use the test, or include it in a page via script tag, you can simply grab a template and copy and paste or replace, during a build process, the test. This will make your life easier than any setup oriented test framework, isn't it?

Write Once, Run Everywhere

Isn't this the dream we all have about JavaScript in both browsers and server side environments? As far as I know wru is the only one that supports all these environments with a unified, cross platform, and easy to remember API. (until I have discovered JS Class via @jcoglan)
Main principles behind wru? KISS and YAGNI, so that everyone can start, at least, writing tests for what's needed, without any ulterior waste of time about environment, library dependency, or programming language setup.
And what if you want to test platform specific gotchas ? Oh well, you can still recycle the whole test and check the number of positive results, as expected, at the end ... well, not all the code we are writing should work cross platform, but even in this case, wru gonna make you familiar with tests and tests logic so it's a win win in any case.

Pluggable UT Libraries

You must admit the name of this framework is absolutely crap. I didn't even know how to call it in a manner that no other frameworks would have been affected, so I sticked with my blog initials, WebReflection, and the one out of Unit in it, until I introduced this tiny library in one of those amazing BerlinJS events where someone suggested Where Are You acronym, and I simply loved it ... uh wait, let's go back in the topic ...
Any external library able to mock or stub your code should be easy to integrate in a wru test without problems.
In this case you may need to include this library upfront via script tag, in the Web html template, or inside any server side related template through require() or some other mechanism.
For browsers, you may consider JSMock, as example, but others which aim is to provide mocks or stubs functionality should be all supported without problems.

About Asynchronous Logic

Let's face reality, asynchronous tests are created exclusively to test the condition after the asynchronous callback has been executed, and this is exactly the wru expectation, you call for async? you wait for async.
If you get how async work you'll realize that you don't have to expect() anything, simply do what your test should do and trigger the done() at the end.
This comes from one of the most appreciated asynchronous pattern out there, Promises, where you simply wait for a done() to be called.
wru does the same, except the equivalent of done() is assert() which is the trigger.
If you have truly complex asynchronous logic, here a common pattern you might find useful with wru.

wru.test([{
name: "async",
test: function () {
var expectation = wru.async(function (arg) {
wru.assert("everything went better than expected", arg === "OK");
});
// your whatever async logic you need
var xhr = new XMLHttpRequest;
xhr.onreadystatechange = function () {
// called multiple times during xhr lifecycle
if (xhr.readyState === 4) {
// async, inside async
doSomeStuffOutThere(xhr.responseText, function (e) {
expectation(e.result); // hopefully the string "OK"
});
}
};
}
}]);

in few words, you don't need to expect a thing since once you define a single asynchronous callback in your test logic, you can trigger it once everything has been tested and, if that will never happen, the timeout will automatically flag the test as failed.

wru Output

Things are kept simple in this case as well, with the happy exception for the cursor.
I mean, you don't really need to stare at it, but the cursor is a visual indication that everything is not just stuck, but it's simply waiting for things to happen, if ever.
A classic infinite loop or endless generator is able to freeze the lifecycle of our app, and only a visual feedback will be able to tell you the truth since any other method, specially in browsers where tests are showed only once executed, won't be able to give you a thing ... except a crash in the best case scenario.
The cursor may interfere with the normal output but, at least when it comes to server side tests, whatever external tool will be able to remove cursor noise in the log and analyze anything that happened during test execution, from green to red or black, providing you an instant feedback if something went wrong.

Improve As You Go

wru is not a universal answer to JS tests but hopefully a good start point or most likely everything you need if the project, and your tests, are not that complex.
Being that simple, the best thing about this library is that we could reproduce its API everywhere else in few lines of code, transforming, as example, your tests into another UT framework without much effort.
The fragmentation of JS tests out there is massive, so I don't really want to go deeper into this, just think that this library made asynchronous tests that easy, as well as normal synchronous one and without interferences, thanks to the chosen namespace, out there.
What else about wru ... well, give i a try :)

Friday, February 17, 2012

If You Don't Get It, Go And Get It!

Oh well, a rant against another one ... how lovely is this? Just trying to make your week end, right?
I am talking about this misleading post with indeed 29530+ views and just 1 Favorited entry (right now) that must be the post author itself since I can't even check and click that red link ... anyway ...

At the very beginning I thought that was a sarcastic post .. like, the opposite of reality, then I have realized it wasn't ... or was it?

V8 is not server-class ?

Define "server class programming language" first ... 'cause I have tried to search it in Google (with quotes) and result was like a single entry that indeed pointed to some Java stuff ...
This argument is kinda boring in 2012, specially against a general purpose programming language as JS is, you don't say?

I mean, doooooode, should I remind you the Java Applet joke early in the Web era? So it was fine for a server-class programming language to do client side stuff? Or it's just a matter of core functionalities, where a project that never even landed in its 1.0 status keeps growing like hell and already showed its high performances muscles against all other modern scripting oriented languages such PHP (without HipHop), Ruby or Python, and others?

Maybe I should simply mention that via C++ you can write your own modules ... just in case ...

Callback spaghetti is bad ?

Let me guess your thoughts, wizard of multiple threads developer ... how you handle asynchronous stuff and how many headaches this caused? I bet you are big fun of races and non-trustable lines of code, isn't it?
Well, with node you'll never have this problem within the language itself, but of course you can write your own module able to use all possible cores and cause yourself headaches about emitting events with consistent and ordered, if necessary, results. You know strongly typed languages so deal with them if you want to improve modules performances.

its nigh-on-impossible to follow the code 6 months later

Oh ... really? There you are server framework pattern developer, you don't understand your own code if the language is JavaScript ... let's blame the chosen technology that caused your frustration: achievement unlocked!

Non-blocking != fast != scalable

As well as
blocking != fast != scalable
but I see you have valid points here, such
  • scalability has very little to do with raw speed, of course it has nothing to do with raw speed if architecture is over-bloated
  • Just because you're fast does not mean you're scalable ... thanks captain obvious, so how come you underline scala performances later on?
  • Node.js isn't even that fast. You can do much better with Scala and its a much nicer language, to boot ... my brain simply tried to divide by zero here ... your argument is that node is not that fast 'cause scala is faster but node performances should not matter?


Performances

The only reliable tests I know about different programing languages is The Computer Language Benchmarks Game.
Now, the only test that makes a concrete difference there, able to screw up final score in a meaningful way, is pidigits, a test that penalizes JavaScript with the inclusion of /home/dunham/shootout/bench/Include/javascript/biginteger.js that gosh knows how badly big integers could perform once simulated in JavaScript.
What you should care about the whole test page, is that not a single test has more code than scala equivalent, preserving in any case performances with basically irrelevant performances gap in real world scenarios.
This is the beauty of V8, the first engine that pushed JS so freaking far away known performances and before it was cool!
I would rather respect it, rather than blame it ... but that just me I guess ...

JavaScript doesn't even have namespaces ?

After you talk about modularity? Do you know that in node.js everything is basicallyy a module? Do you know that any namespace starts from a root, which is called global object in Javascript world, where the community nowadays is freaking aware of namespaces conflicts?
Do you know that every time you define your own object in Javascript you basically create a namespace so that JS had namespace since the very beginning of his concrete history?
it's clear to me you don't ... so please, stop talking about stuff you don't know!
JavaScript namespaces have been there since ever and the best part is that JavaScript supports multiple inheritance through prototypal nature where you don't even need to write kilometrics namespaces to obtain a single bloody "class" out of it.
it's true that in 2000 JavaScript was abused, it's absolutely a lie that nowadays any sort of well known library isn't aware of namespace possibility.
I would add modularity that resolves namespaces automatically, and in an ordered way as Java guys like in folders structure, through any sort of loader that has been developed from a developer as skilled as you are.

people who are really crazy about Node.js are people who only knew JavaScript to begin with

for a project entirely based on C++? Sure, node.js guys are all freaking idiots developers that do not deserve anything in the server side ... isn't it?
I am Zend Certified Engineer and an AS2 (ECMAScript 4th + C#) Certified Developer with some C, C++, Python, and Java background experience that sticked with JavaScript the day ActionScript 3 became a Java like programming language ... and guess what? I am happily writing JavaScript on daily basis and I am sick, programming since year 2000, to hear developers from one language complaining about other programming languages blaming developers that are using them as if they don't know what are doing.

Respect JavaScript

... and stop thinking as if it's a toy language you, in first place, is not able to get. I have no hacking idea about scala and I am blogging since ever without complaining a single time about Scala developers.
You think Scala is what you need? You think scala is what you know? Go Scala, for gosh sake, but don't ever even try to blame another community if you didn't spend at least 2 years behind that programming language, and with a decent programming background, specially if you can't even get your own code after 6 months.
Let's stop this, cause programming today is way too far from perfect, and rather than picking best things out of every language, we keep blaming others and acting like 5 years old kids.
Enough!

Excellent About node.js

Performances are good enough, and code and skills reusability, something anyone with an IT related BSC learned, is absolutely awesome, fresh, new, and productive, without even considering potentials for companies budget.
It's true in JS community itself that the fragmentation of engines never made things easy, the reason a cross platform JS developer should be valued as much or more than a JVM one rather than usually less, due background knowledge per each environment, imo, but it's true as well that node.js makes things eventually easy for new comers in client/server programming world too.
As a Zend engineer, I have complained many times about PHP as programming language due intrinsic non-sense all over, and as JavaScript developer I keep complaining about lack of proper knowledge of the language, still rarely studied properly in Universities, basically the most important language ever in the Web, client and server, field.
Being easy to learn, same success PHP had years ago, many developers from any sort of language are first of all welcome, secondly have an easy way to do things via patterns that, once learned, may not look so smart from other languages point of view, but take care already of many common bottlenecks or problems the web has seen so far.
As summary, Node.js is a great technology that eventually made it where Rhino, Cocoon, and other JS server side related projects, failed. Node.js is easy, fast enough, natural, and junior to senior prone when it comes to server side development.
Scalablity, once again, is not a programming language feature, is a developer mind-set plus skills related matter so think about it any time you decide to blame a technology you don't really understand.

Thursday, February 16, 2012

Berlin JS - RegExp Slides

Here they are!
(published live)

If you want to test examples remember to replace weird keynote double-quotes with normal one :)

Enjoy JavaScript Regular Expressions

Tuesday, February 14, 2012

JSON.stringify Recursion + Max Execution Stack Exceeded

I believe this is a common problem, and we had a similar one today while debugging.
JSON methods do not support recursion ... which is the only thing I am really missing back to PHP serialize days.

Recursion Is Bad

Well, I would say cyclic references are never that good but sometimes these may happen and, specially while testing and debugging, it's more than useful to understand what happened there.
If you have cyclic/cross references in your code I suggest you to use approaches which aim is to avoid these kind of direct links.
Harmony Collections, specially Map and WeakMap, are indeed good helpers to reference indirectly objects without creating, hopefully, first level links and/or recursions.

How To Serialize Anyway

JSON.stringify() accepts a second argument called replacer.
I won't explain more than MDN about its potentials, but it can be really handy to avoid recursions.
A simple way to do it is indeed to store in a stack already parsed objects, included the object itself.
Some other extra operation may be handy too so the debug will be as complete as possible.

var replacer = function (stack, undefined, r, i) {
// a WebReflection hint to avoid recursion
return function replacer(key, value) {
// this happens only first iteration
// key is empty, and value is the object
if (key === "") {
// put the value in the stack
stack = [value];
// and reset the r
r = 0;
return value;
}
switch(typeof value) {
case "function":
// not allowed in JSON protocol
// let's return some info in any case
return "".concat(
"function ",
value.name || "anonymous",
"(",
Array(value.length + 1).join(",arg").slice(1),
"){}"
);
// is this a primitive value ?
case "boolean":
case "number":
case "string":
// primitives cannot have properties
// so these are safe to parse
return value;
default:
// only null does not need to be stored
// for all objects check recursion first
// hopefully 255 calls are enough ...
if (!value || !replacer.filter(value) || 255 < ++r) return undefined;
i = stack.indexOf(value);
// all objects not already parsed
if (i < 0) return stack.push(value) && value;
// all others are duplicated or cyclic
// mark them with index
return "*R" + i;
}
};
}();

// reusable to filter some undesired object
// as example HTML node
replacer.filter = function (value) {
// i.e. return !(value instanceof Node)
// to ignore nodes
return value;
};

A simple example about above function could be this one:

// how to test it
var o = {a:[], b:123, c:{}, e:function test(a,b){}};
o.d = o;
o.a.push(o);
o.c.o = o;
o.c.a = o.a;
o.c.c = o.c;
o.a.push(o.c);
alert(JSON.stringify(o, replacer));

Above alert will produce this kind of output:
{"a":["*R0",{"o":"*R0","a":"*R1","c":"*R2"}],"b":123,"c":"*R2","e":"function test(arg,arg){}","d":"*R0"}
which is surely not as bad as an exception, isn't it?

The Max Execution Stack Problem

Even using a stack variable, in order to avoid duplicated entries, the reason 255 < ++r is necessary is that the generic object may reference in one or more properties a DOM node.
Specially in big applications, the number of nodes, all unique, could be able to reach the function limit.
A tricky way to know this limit, which is browser and engine dependent, could be this one:

(function (Function, MAX_EXECUTION_STACK) {
if (MAX_EXECUTION_STACK in Function) return;
Function[MAX_EXECUTION_STACK] = function (i) {
try {
(function max(){
++i && max();
}());
} catch(o_O) {
return i;
}
}(0);
}(Function, "MAX_EXECUTION_STACK"));

// browser dependent
alert(Function.MAX_EXECUTION_STACK);

Unfortunately in the replacer we cannot use this number in any case because we don't know how many other times the function itself will be called but a good compromise, able to generate objects almost impossible to debug, would be Function.MAX_EXECUTION_STACK / 100 so the limit will scale accordingly.
In all other situations where we still have recursion and max execution stack problems but we are those calling our own function, this limit could be more than handy, i.e.

var
i = 0,
fn = function (obj) {
for (var key in obj) {
if (++i < Function.MAX_EXECUTION_STACK) {
parse(obj[key]);
fn(obj[key]);
}
}
}
;

... so now you know ...

Monday, February 13, 2012

Web Workers - Current Status

A quick one about workers after few tests.

Mobile

Workers are apparently nowhere in Android devices stock browsers. The only one able to bring workers seems to be Chrome in ICS.
As alternative, both Opera Mobile and Firefox Beta work without many problems.
About iOS, version 4 does not support workers while version 5 does and quite well.

Desktop and Data URI

Workers are almost fine everywhere except IE9 ( surpriiiiiiiiiise ) but there is one thing not a single browser does except again Firefox and Opera, accepting "data:application/javascript;" with or without base64 encoded code.
On mobile side this is supported again by Opera Mobile and Firefox Beta without problems but on desktop, and not only ...
  1. Safari works only with external files while inline data uri are supported only via file protocol
  2. WebKit nightly does not support inline data uri even through File protocol
  3. Chrome does not support inline data uri neither via file protocol nor online
  4. Safari Mobile does not support inline data uri, at least online
  5. Chrome Mobile does not support them at all


Why Bother With Data URI

Quite simple, Workers are a mechanism to detach some logic from the main thread and execute it in the background. The possibility to create inline Workers means we could create a sort of Threads manager, delegating runtime ad-hoc functions to perform certain tasks handling all requests from and to the main page.

Workers Until Now Are Not Good

Not only the serialization and deserialization problem does not scale with large amount of data, probably the only reason you would think to use a worker for some job, but the DOM security exception thrown with data URI and for no reason on earth is yet another limit for this technique.
Current status, except for data URI, is that you may need webkitPostMessage rather than simply postMessage in order to at least optimize data transfer between global objects, but on the other hand, the dream we all have about "HTML5" keeps fading out every time I understand I need to prefix something, either if I use CSS3 or JavaScript (i.e. requestAnimationFrame).

Disappointed, nothing else to add.

Sunday, February 05, 2012

JS1K - Markdown

Well, it does not look that good in the js1k page, so here the link to the official demo hosted by my site.
Check the source code there, the page is entirely written in Markdown :)



I submitted this demo because Markdown is widely used, and I believed loved too, by many developers and specially in github, but I may consider to create the whole thing in less than 1kb using gzip compression if people will like the idea.

Friday, February 03, 2012

Love ALL The Web

update no selection problems anymore ... eat the cake now

Maybe 'cause San Valentine is coming, maybe 'cause Chris Williams started it, promoting an end to negativity, or maybe 'cause the web has been recently under attack ... no matter why, the topic of this js1k contest is Love so here I am introducing my proposal, the very first demo submitted this year.
Click the link once to see it in action through following iframe:



What Is It

A simple script able to bring random harts behind the mouse or the finger in any page you want, even Facebook :)
In order to do this, you can bookmark the link dragging into your bookmark bar, change the name (i.e. LOVE), and start surfing surrounded by little harts any new page you visit by simply clicking it. I know it's a silly demo, but it was a quick and interesting experiment I could recycle with any sort of different shape since the graphic is directly drawn on every little canvas.

Technical Details

  • compatible with all modern mobile and desktop browsers, included IE9
  • unobtrusive, it should not affect much the normal behavior of the generic page
  • based on requestAnimationFrame where supported
  • lazy pointer evaluation, no matter if your tablet is attached to a deck with a mousepad, touch screens and other pointers are all supported at runtime
  • it fits in 1020 1023 bytes after Closure Compiler Advanced minification plus extra clean up performed by YUI Compressor (plus few manual tweaks for numbers) ... once gzipped, it fits in about 0.5Kb
  • 1 hour of work, included mobile and cross browsers tests ( plus 20 minutes to think about a solution and fix the text selection problem )
  • easy to recycle, a single change in the draw function and anything you want could be displayed, even smoke effect or rainbows


Discoveries During Creation

  • performances boost with requestAnimationFrame is unbelievable, if you compare current Opera browser VS Chrome, Safari, Webkit, or Firefox, you'll see the difference against setTimeout
  • IE9 and IE10 awesome canvas performances become crap once more than a canvas is created at runtime. If you see how slow this thing could be in my Netbook in IE compared to others, you'll rethink about how fast canvases are in MS browser: it is that fast, but only if there is one of them
  • Opera still doesn't support requestAnimationFrame even if prefixed with the little o
  • the canvas arc() method is completely freak, only few browsers give what you expect. Compare the bigger hart on click in Chrome and Firefox, as example, Chrome gonna show Mickey Mouse like hart
  • YUI Compressor after Google Closure Compiler Advanced is able to produce a slightly smaller output preserving functionality
  • Chrome DOM inspector is really smart. While Safari and Webkit becomes much slower during inspection, Chrome seems to use a "requestDOMInspection" like mechanism to do not slow down the page during DOM changes


Have fun with JS1K