var assert = require("assert"),
    spawn = require('child_process').spawn,
    hiredis = require("../src/build/default/hiredis");

exports.testCreateReader = function() {
    var reader = new hiredis.Reader();
    assert.isNotNull(reader);
}

exports.testStatusReply = function() {
    var reader = new hiredis.Reader();
    reader.feed("+OK\r\n");
    assert.equal("OK", reader.get());
}

exports.testIntegerReply = function() {
    var reader = new hiredis.Reader();
    reader.feed(":1\r\n");
    assert.equal(1, reader.get());
}

exports.testErrorReply = function() {
    var reader = new hiredis.Reader();
    reader.feed("-ERR foo\r\n");
    assert.equal("ERR foo", reader.get());
}

exports.testNullBulkReply = function() {
    var reader = new hiredis.Reader();
    reader.feed("$-1\r\n");
    assert.equal(null, reader.get());
}

exports.testEmptyBulkReply = function() {
    var reader = new hiredis.Reader();
    reader.feed("$0\r\n\r\n");
    assert.equal("", reader.get());
}

exports.testBulkReply = function() {
    var reader = new hiredis.Reader();
    reader.feed("$3\r\nfoo\r\n");
    assert.equal("foo", reader.get());
}

exports.testNullMultiBulkReply = function() {
    var reader = new hiredis.Reader();
    reader.feed("*-1\r\n");
    assert.equal(null, reader.get());
}

exports.testEmptyMultiBulkReply = function() {
    var reader = new hiredis.Reader();
    reader.feed("*0\r\n");
    assert.eql([], reader.get());
}

exports.testMultiBulkReply = function() {
    var reader = new hiredis.Reader();
    reader.feed("*2\r\n$3\r\nfoo\r\n$3\r\nbar\r\n");
    assert.eql(["foo", "bar"], reader.get());
}

exports.testNestedMultiBulkReply = function() {
    var reader = new hiredis.Reader();
    reader.feed("*2\r\n*2\r\n$3\r\nfoo\r\n$3\r\nbar\r\n$3\r\nqux\r\n");
    assert.eql([["foo", "bar"], "qux"], reader.get());
}

exports.testMultiBulkReplyWithNonStringValues = function() {
    var reader = new hiredis.Reader();
    reader.feed("*3\r\n:1\r\n+OK\r\n$-1\r\n");
    assert.eql([1, "OK", null], reader.get());
}

exports.testFeedWithBuffer = function() {
    var reader = new hiredis.Reader();
    reader.feed(new Buffer("$3\r\nfoo\r\n"));
    assert.eql("foo", reader.get());
}

exports.testUndefinedReplyOnIncompleteFeed = function() {
    var reader = new hiredis.Reader();
    reader.feed("$3\r\nfoo");
    assert.eql(undefined, reader.get());
    reader.feed("\r\n");
    assert.eql("foo", reader.get());
}

exports.testLeaks = function(beforeExit) {
    /* The "leaks" utility is only available on OSX. */
    if (process.platform != "darwin") return;

    var done = 0;
    var leaks = spawn("leaks", [process.pid]);
    leaks.stdout.on("data", function(data) {
        var str = data.toString();
        var notice = "Node 0.2.5 always leaks 16 bytes (this is " + process.versions.node + ")";
        var matches;
        if ((matches = /(\d+) leaks?/i.exec(str)) != null) {
            if (parseInt(matches[1]) > 0) {
                console.log(str);
                console.log('\x1B[31mNotice: ' + notice + '\x1B[0m');
            }
        }
        done = 1;
    });

    beforeExit(function() {
        setTimeout(function() {
            assert.ok(done, "Leaks test should have completed");
        }, 100);
    });
}


@@ -1128,32 +1128,221 @@
 ader.get());%0A%7D%0A%0A
+exports.testBulkReplyWithEncoding = function() %7B%0A    var reader = new hiredis.Reader();%0A    reader.feed(%22$%22 + Buffer.byteLength(%22%E2%98%83%22) + %22%5Cr%5Cn%E2%98%83%5Cr%5Cn%22);%0A    assert.equal(%22%E2%98%83%22, reader.get());%0A%7D%0A%0A
 exports.testNull

Test encoding in bulk reply