I created an ASCII cheat sheet from the table that I used in my blog post about my favorite regular expression. I know there are a billion ASCII cheat sheets out there but I wanted my own. This cheat sheet includes dec, hex, oct and bin values for ASCII characters.


download ascii cheat sheet

Also see my other cheat sheets.

Six Years of BloggingHey everyone! Another year has passed and it's been 6 years since I've been blogging here on catonmat! In this post I wish to summarize this year's statistics.

See the one year of blogging, two years of blogging, three years of blogging, four years of blogging, and five years of blogging for the previous year statistics.

Let's start this year's stats with traffic:



Traffic statistics from Google Analytics for Jul 1, 2012 - Jun 30, 2013.

This year: 903,468 uniques. 1,191,596 visits. 1,695,544 page views.
Last year: 988,295 uniques. 1,374,228 visits. 1,940,530 page views.
Delta: -84,827 unqiues. -182,632 visits. -244,986 page views.

I haven't been blogging as much as in the previous year and that explains the negative delta.

Feedburner stats: At 16,343 rss subscribers this year. Last year 14,362. Delta +1,981. subscribe.
Github stats: At 1400 followers this year. Last year 1070. Delta +330. follow me.
Twitter stats: At 3774 followers this year. Last year 3093. Delta +681. follow me.

Subscriptions and followers grow over time, which explains the positive delta.

Total articles written: 25. Top 10 articles:

My top 5 favorite articles:

During this year I made 4 announcements:

That's all folks! Now let's have some 6 year birthday cake,

And let's meet for the cake next year again! See you!

This guide covers the ins-and-outs of tape, a simple TAP-producing test library for node and browsers. The tape API is a small superset of the node core assert module.

This guide was written for Testling. Testling lets you write continuous integration cross-browser tests that run on every git push! Once the tests run you get a badge you can put in your readme with the current browser test status. Here's how it looks:


Click the badge to learn how to write Testling tests!

For an exaustive list of all the methods that tape supports, consult the tape readme.

Simple equality with a plan

Most of the time, you'll just need to plan out a few simple asserts with t.equal(), which uses === internally:

var test = require('tape');

test('basic arithmetic', function (t) {
    t.plan(2);

    t.equal(2 + 3, 5);
    t.equal(7 * 8 + 9, 65);
});

If you want you can leave off the test name and just do:

var test = require('tape');

test(function (t) {
    t.plan(2);

    t.equal(2 + 3, 5);
    t.equal(7 * 8 + 9, 65);
});

Simple equality with an end

If you have an indefinite number of assertions, sometimes it's easier to call t.end() instead:

var test = require('tape');

test('basic arithmetic', function (t) {
    t.equal(2 + 3, 5);
    t.equal(7 * 8 + 9, 65);

    t.end();
});

Deep equality

To compare array and object references deeply, you can use t.deepEqual():

var test = require('tape');

test('deep equality', function (t) {
    t.plan(2);

    t.deepEqual([ 3, 4, 5 ], [ 3, 4, 2+3 ]);
    t.deepEqual(
        { a: 7, b: [ 8, 9 ] },
        { a : 3+4, b: [ 4*2 ].concat(3*3) }
    );
});

Comparing booleans

Just use .ok() to assert truthiness:

var test = require('tape');

test('comparing booleans', function (t) {
    t.plan(1);

    t.ok(3 > 4 || 5 > 2);
});

Negations

For each kind of assertion, prepend (and camel-case) a "not" to turn it into a negative assertion:

var test = require('tape');

test('negatives', function (t) {
    t.plan(3);
    t.notEqual(1+2, 5);
    t.notDeepEqual([1,2], [12]);
    t.notOk(false);
});

Pass/fail

If you need a test to just fail, you can call t.fail():

var test = require('tape');

test('empty map', function (t) {
    [].map(function (x) {
        t.fail('this callback should never fire');
    });

    t.end();
});

Conversely, there is a t.pass() which always succeeds:

var test = require('tape');

test('map with elements', function (t) {
    t.plan(2);

    [2,3].map(function (x) {
        t.pass();
    });
});

More info

You can always add an assertion description as the last argument:

var test = require('tape');

test('more info', function (t) {
    t.plan(2);

    t.equal(1+2, 3, 'basic arithmetic still works');
    t.ok(3+4>5, 'inequalities are as we might expect');
});

Asynchronous

Since we either plan out the number of assertions explicitly with t.plan(n) or end the test explicitly with t.end(), we don't need to do anything differently when our tests make asynchronous calls:

var test = require('tape');

test('asynchronous results', function (t) {
    t.plan(2);

    t.equal(2+3, 5);

    setTimeout(function () {
        t.equal(5+5, 10);
    }, 500);
});

Multiple serial tests

var test = require('tape');

test('first', function (t) {
    t.plan(1);
    setTimeout(function () { t.ok(true) }, 200);
});

test('second', function (t) {
    t.plan(1);
    setTimeout(function () { t.ok(true) }, 100);
});

The 'first' test will run, then the 'second'.

Nesting tests

You probably shouldn't do this very often, but you can have nested tests too:

var test = require('tape');

test('nested', function (t) {
    t.test(function (st) {
        st.plan(1);
        st.equal(1+2, 3);
    });

    t.test(function (st) {
        st.plan(1);
        setTimeout(function () {
            st.pass();
        }, 100);
    });
});

Running a tape test in node

Just run your test file directly with node:

$ node test/def.js 
TAP version 13
# defined-or
ok 1 empty arguments
ok 2 1 undefined
ok 3 2 undefined
ok 4 4 undefineds
ok 5 false[0]
ok 6 false[1]
ok 7 zero[0]
ok 8 zero[1]
ok 9 first arg
ok 10 second arg
ok 11 third arg

1..11
# tests 11
# pass  11

# ok

Running a directory full of tape tests in node

If you npm install -g tape, you get a test runner for running directories full of tests all at once:

$ tape test/*.js
TAP version 13
# defined-or
ok 1 empty arguments
ok 2 1 undefined
ok 3 2 undefined
ok 4 4 undefineds
ok 5 false[0]
ok 6 false[1]
ok 7 zero[0]
ok 8 zero[1]
ok 9 first arg
ok 10 second arg
ok 11 third arg
# (anonymous)
ok 12 should be equal

1..12
# tests 12
# pass  12

# ok

You could also use the test runner from the tap module for more terse output. First npm install -g tap, then do:

$ tap test/*.js
ok test/def.js ........................................ 12/12
ok test/falsy.js ........................................ 2/2
total ................................................. 14/14

ok

In the test runner scripts for both tap and tape you will get lots of output including line numbers when an assertion fails.

Running a tape test in a browser

First npm install -g browserify, then you can do:

$ browserify test.js > bundle.js
$ echo '<script src="bundle.js"></script>' > test.html

Then open test.html in a browser and look at the test output in the debugger. tape writes all its output to console.log() by default.

If you want to run your tests in a real headless browser locally, npm install -g testling then do:

$ browserify test.js | testling
TAP version 13
# defined-or
ok 1 empty arguments
ok 2 1 undefined
ok 3 2 undefined
ok 4 4 undefineds
ok 5 false[0]
ok 6 false[1]
ok 7 zero[0]
ok 8 zero[1]
ok 9 first arg
ok 10 second arg
ok 11 third arg

1..11
# tests 11
# pass  11

# ok

and your test will run in chrome or firefox headlessly, depending which you have installed on your system. The console.log() output is proxied from the browser to your stdout and the testling command generates an exit code by parsing the TAP output.

Running a directory full of tape tests in a browser

To run multiple tests, just use a file glob:

$ browserify test/*.js | testling
TAP version 13
# defined-or
ok 1 empty arguments
ok 2 1 undefined
ok 3 2 undefined
ok 4 4 undefineds
ok 5 false[0]
ok 6 false[1]
ok 7 zero[0]
ok 8 zero[1]
ok 9 first arg
ok 10 second arg
ok 11 third arg
# (anonymous)
ok 12 should be equal

1..12
# tests 12
# pass  12

# ok

Running tape tests on Testling

To get your tape tests running on testling simply add the "testling" field to package.json

"testling" : {
    "files" : "test/*.js",
    "browsers" : {
        "ie" : [ 6, 7, 8, 9, 10 ],
        "ff" : [ 3.5, 10, 15.0, 16.0, 17.0 ],
        "chrome" : [ 10, 20, 21, 22, 23 ],
        "safari" : [ 5.1 ],
        "opera" : [ 10, 11, 12 ]
    }
}

and setup a github hook to point to git.testling.com. Now every time you push to github the tape tests will run in all the specified browsers.

To learn more about how to write testling tests, see this article.

Conclusion

If you need more complicated abstractions in your tests, just npm install them and require() them in your tests. Just be careful that the libraries you're importing also work in browsers.

Tape shows that you don't actually need very much API to test your libraries in a powerful and flexible way that works in node and in browsers.

Last time I stopped at showing how to override functions in shared libraries by compiling your own shared library and preloading it via the LD_PRELOAD environment variable. Today I'll show you how to call the original function from the overridden function.

First let's review the code example that we used in the previous article. We had a program called prog.c that simply used fopen:

#include <stdio.h>

int main(void) {
    printf("Calling the fopen() function...\n");

    FILE *fd = fopen("test.txt", "r");
    if (!fd) {
        printf("fopen() returned NULL\n");
        return 1;
    }

    printf("fopen() succeeded\n");

    return 0;
}

Today let's write a shared library called myfopen.c that overrides fopen in prog.c and calls the original fopen from the c standard library:

#define _GNU_SOURCE

#include <stdio.h>
#include <dlfcn.h>

FILE *fopen(const char *path, const char *mode) {
    printf("In our own fopen, opening %s\n", path);

    FILE *(*original_fopen)(const char*, const char*);
    original_fopen = dlsym(RTLD_NEXT, "fopen");
    return (*original_fopen)(path, mode);
}

This shared library exports the fopen function that prints the path and then uses dlsym with the RTLD_NEXT pseudohandle to find the original fopen function. We must define the _GNU_SOURCE feature test macro in order to get the RTLD_NEXT definition from <dlfcn.h>. RTLD_NEXT finds the next occurrence of a function in the search order after the current library.

We can compile this shared library this way:

gcc -Wall -fPIC -shared -o myfopen.so myfopen.c -ldl

Now when we preload it and run prog we get the following output that shows that test.txt was successfully opened:

$ LD_PRELOAD=./myfopen.so ./prog
Calling the fopen() function...
In our own fopen, opening test.txt
fopen() succeeded

This is really useful if you need to change how a part of a program works or do some advanced debugging. Next time we'll look at how LD_PRELOAD is implemented.

Remember my previous two blog posts about publishing 30 and 20 of my projects to github? Here are another 10 projects in no particular order that I've written since then.

I really love writing open source projects. Everyone should publish all their projects to github. Good or bad. Like my friend just said: "Publish more open source, not less. "Too much noise" is a terrible excuse. Publish wisdom so we may use. Publish mistakes so we may learn."

If you find my projects interesting, consider following me on github! Thank you!

Shorten urls with bitly without api

This is a Perl module that shortens urls via bitly without using their API. I once had to shorten more than a few hundred urls quickly so I wrote this.

Here's an example of how to use it:

use bitly;

my $bitly = bitly->new('username', 'password');
my $url = bitly->shorten('http://www.url.com');

unless ($url) {
    say $bitly->{error};
}
else {
    say $url;
}

Speak text files to wav via Microsoft Speech API

I once had this idea of converting my blog posts to mp3. So I wrote a C++ program that uses the Microsoft's speech api. It takes a txt file as input and produces a wav file output.

Usage:

speak.exe <voice name> <text file> <wav file>
-or-
speak.exe --list-voices

Compile this project with Microsoft Visual Studio 2008 or later.

Bonus: At first I tried using Loquendo SDK and created a TextToWav project but their speech engine wasn't too great so I created speak-text-files-to-wav.

Load status server for Windows

This simple C++ program creates a single threaded TCP server that replies with information in JSON format about Window's CPU, Disk, and Memory usage. I created this because I had to monitor Windows servers at Browserling.

Here's an example:

C:\bin\> load-status-server.exe
Started server on port 7000

Now if you connect to server.com:7000, it will send you JSON with the current server load info:

$ nc server.com 7000
{
    "memory": {
        "usage": 71,
        "total_physical": 1068388352,
        "free_physical": 302112768,
        "total_paging_file": 3096842240,
        "free_paging_file": 2155446272,
        "total_virtual": 2147352576,
        "free_virtual": 2130919424,
        "free_extended_virtual": 0
    },
    "cpu": {
        "load": 5
    },
    "disk": {
        "free_user": 22858027008,
        "free_total": 22858027008,
        "total": 42947571712
    }
}

Compile this project with Visual Studio or mingw. It uses just Win32 calls.

HWND finder

We started working on a new product at Browserling that takes screenshots so I wrote a bunch of code that finds browser window HWNDs. Then I decided to open source some parts of it and created HWND finder. The idea is to have something like jQuery's syntax for finding HWNDs. We delayed launching this screenshot product so I haven't made any updates.

Here's an example:

#include "hwnd-finder.h"

HwndFinder hf;
HWND rendererHwnd = hf.find("Chrome_WidgetWin_1 > Chrome_WidgetWin_0 > Chrome_RenderWidgetHostHWND");

This finds Chrome renderer's window handle. Here Chrome_RenderWidgetHostHWND is a child of Chrome_WidgetWin_0 is a child of Chrome_WidgetWin_1 which is the top window.

node-number-range

This is a node.js module that streams number ranges. Here are all the ranges it supports:

var range = require('number-range');

* range(10) - range from 0 to 9
* range(-10, 10) - range from -10 to 9 (-10, -9, ... 0, 1, ... 9)
* range(-10, 10, 2) - range from -10 to 8, skipping every 2nd element (-10, -8, ... 0, 2, 4, 6, 8)
* range(10, 0, 2) - reverse range from 10 to 1, skipping every 2nd element (10, 8, 6, 4, 2)
* range(10, 0) - reverse range from 10 to 1
* range('5..50') - range from 5 to 49
* range('50..44') - range from 50 to 45
* range('1,1.1..4') - range from 1 to 4 with increment of 0.1 (1, 1.1, 1.2, ... 3.9)
* range('4,3.9..1') - reverse range from 4 to 1 with decerement of 0.1
* range('[1..10]') - range from 1 to 10 (all inclusive)
* range('[10..1]') - range from 10 to 1 (all inclusive)
* range('[1..10)') - range grom 1 to 9
* range('[10..1)') - range from 10 to 2
* range('(1..10]') - range from 2 to 10
* range('(10..1]') - range from 9 to 1
* range('(1..10)') - range from 2 to 9
* range('[5,10..50]') - range from 5 to 50 with a step of 5 (all inclusive)
* range('10..') - infinite range starting from 10
* range('(10..') - infinite range starting from 11

Very cool stuff. Especially the infinite ranges, which use the process.nextTick trick.

HTTP::Async::Retry

It's almost HTTP::Async::Retry. It's actually just a async_retry.pm file that you can drop into your project to do a quick hack. With a bit of effort it could be HTTP::Async::Retry.

I once had to scrape a lot of information so I used my favorite language Perl and used the HTTP::Async module. A lot of URLs would time out as I was creating thousands of connections per second. At first I simply copied the retry code from hack to hack but then at one moment I had enough so I simply wrote async_retry.pm that abstracts away the retries.

Here's an example:

use warnings;
use strict;

use HTTP::Request;
use async_retry qw/async_retry/;

my @urls = (
    'http://www.google.com/1';,
    'http://www.google.com/2';,
    'http://www.google.com/3';,
    'http://www.google.com/';,
    'http://www.google.com/5';,
);

async_retry(
    {
        retries => 5
    },
    [
        map { HTTP::Request->new(GET => $_) } @urls
    ],
    sub {
        my ($req, $res) = @_;
        print $res->base, "\n";
    }
);

This code tries to get all those Google urls and retries to get them 5 times. If a url succeeds or fails after retries, it calls the callback with HTTP::Request and HTTP::Response objects.

HTML Keyboard Widget

This is just an on-screen keyboard widget for Browserling. I wrote it because people with weird keyboard layouts couldn't input various English characters in Browserling. We'll add it to Browserling soon (it's a planned feature.)

Here's how it looks like:

You can try a live demo here.

Cached browser badges

This project just creates cached browser badges for Testling, so that we don't have to generate them again as it's costly.

~/.ssh/authorized_keys ssh key manager

This project manages public ssh keys in ~/.ssh/authorized_keys file. We'll use this at Browserling to manage the ssh keys for tunnels so that you can add, remove and list the keys. (It's a planned feature.)

Here's an example:

var sshManager = require('ssh-key-manager');
sshManager.addKey('pkrumins', 'ssh-rsa AAAAB3NzaC1y...', function (err) {
    if (err) {
        console.log(err);
        return;
    }
});

node-tree-kill

This is a node.js module that kills all processes in the process tree, including the given root process.

Here's an example:

var kill = require('tree-kill');
kill(301, 'SIGKILL');

In this example we kill all the children processes of the process with pid 301, including the process with pid 301 itself.

This module currently works on Linux only as it uses ps -o pid --no-headers --ppid PID to find the parent pids of PID.

GitHub is awesome!

Push all your projects to github all the time! Don't let your project rot on your hard drive! Publish it to github! Publish wisdom so we may use. Publish mistakes so we may learn.

And just another reminder, I'd love if you followed me on github and twitter! :)