Matching partial request bodies with Nock

A recent update to Nock meant that partial matches of the request body would no longer match (one dev’s bug is another’s feature).

Their recommended solution is to supply a predicate, and do the check yourself. That’s simple when just checking one property, but I didn’t really want to re-invent the wheel.

Seeing as I’m already using sinon, that seemed like the obvious solution:

    var expected = {a: 1};

    nock("https://foo.com")
            .post("/bar", checkReqBody(expected))
            .reply(200, '{}');

        function checkReqBody(expected) {
            return reqBody => {
                expect(reqBody).to.equal(sinon.match(expected));
                return true;
            };
        }

This works fine in the success case; but if the match fails, throwing an error in that callback tears down the test runner process, rather than failing the test.

A bit of digging in the sinon (and sinon-chai) source revealed the right method to call:

    return reqBody => {
        return sinon.match(expected).test(reqBody);
    };

This is now equivalent to the previous behaviour, if the match fails you get the generic nock error. I wanted to make more use of the sinon output, when the match failed, but never really got anywhere with it.

Converting complex js objects to xml

The xml node package offers “fast and simple Javascript-based XML generation”.

I had hoped that it would be as simple as:

var xml = require('xml');

var result = xml({
    FOO: {
        BAR: "something"
    }
});

But that only included the top level element:

<FOO />

After some RTFM, and a few false starts, it became clear that you need to represent each child node as an array of key value pairs:

xml({
    FOO: [
        {_attrs: { abra: "cadabra" },
        { BAR: "something" },
        { BAZ: "else" }
    ]
});

Which should result in XML like this:

<FOO abra="cadabra">
    <BAR>something</BAR>
    <BAZ>else</BAZ>
</FOO>

Property changed decorator using ES7

Watching a model for changes is a pretty common requirement, and you often end up with code like this (in ES6):

export default class Foo extends EventEmitter {
    get bar() {
        return this._bar;
    }

    set bar(value) {
        if (value !== this._bar) {
            this._bar = value;
            this.emit("barChanged");
        }
    }
}

Boilerplate code is always an excuse for metaprogramming! And this seemed like an ideal use case for the proposed ES7 decorators.

We’re using babeljs via babelify, so needed to enable decorators in our gulpfile:

return browserify({
    ...
    transform: [babelify.configure({
        optional: ["es7.decorators"]
    })],
    ...
});

Once enabled, you can add the decorator:

export default class Foo extends EventEmitter {
    @propertyChanged
    get bar() {
        return this._bar;
    }

    set bar(value) {
        this._bar = value;
    }
}

function propertyChanged(target, name, descriptor) {
    let getter = descriptor.get, setter = descriptor.set;

    descriptor.set = function(value) {
        if (value !== getter.call(this)) {
            setter.call(this, value);
            this.emit(name + "Changed");
        }
    };

    return descriptor;
}

Mmm, curry

Currying and partial function application are two concepts from functional programming that sound far more complicated than they really are.

One of the times I find myself wishing it were more convenient to do in JavaScript is when trying to escape callback hell by extracting functions:

var shared = new Shared();
doSomething(shared).then(function(result) {
    somethingElse(shared, result);
});

It would be nice to be able to go straight to this:

var shared = new Shared();
doSomething(shared).then(somethingElse);

Of course this wouldn’t work, as the somethingElse function expects 2 parameters instead of just one.

If JavaScript supported partial application in the way that the ML family of languages do, then we could say:

doSomething(shared).then(somethingElse(shared));

But that means something entirely different in JavaScript: the result of the function being executed with one argument would be passed in.

It’s relatively straightforward to write a curry function and use that, but there is an alternative; returning an appropriate function from the called method:

var shared = new Shared();
doSomething(shared).then(somethingElse(shared));

function somethingElse(shared, result) {
    return function(result) {
        // do something with shared & result
    };
}