You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
294 lines
8.5 KiB
294 lines
8.5 KiB
var assert = require('assert'); |
|
var BufferBuilder = require('../buffer-builder'); |
|
|
|
/* Build 1 2 3 3 4 5 4 5 6 7 ... and make sure it comes out right */ |
|
(function() { |
|
var builder = new BufferBuilder(7); |
|
var top = 100; |
|
for (var base = 1; base < top; base++) { |
|
var xs = []; |
|
for (var offset = 0; offset < base; offset++) { |
|
xs.push(base + offset); |
|
} |
|
builder.appendBuffer(new Buffer(xs)); |
|
} |
|
|
|
var result = builder.get(); |
|
var idx = 0; |
|
for (var base = 1; base < top; base++) { |
|
for (var offset = 0; offset < base; offset++) { |
|
assert.equal(result[idx++], base+offset); |
|
} |
|
} |
|
})(); |
|
|
|
/* Build 1 2 2 3 3 3 4 4 4 4 5 5 5 5 5 ... and make sure it comes out right. */ |
|
(function() { |
|
var builder = new BufferBuilder(3); |
|
var top = 20; |
|
for (var i = 1; i < top; i++) { |
|
builder.appendFill(i, i); |
|
} |
|
|
|
var result = builder.get(); |
|
var idx = 0; |
|
for (var i = 1; i < top; i++) { |
|
for (var j = 0; j < i; j++) { |
|
assert.equal(result[idx], i); |
|
idx++; |
|
} |
|
} |
|
})(); |
|
|
|
/* Numeric types come out like they went in */ |
|
(function() { |
|
var builder = new BufferBuilder(); |
|
var n = 500; |
|
|
|
var buildFns = BufferBuilder.prototype; |
|
var readFns = Buffer.prototype; |
|
var entries = []; |
|
|
|
function Entry(buildFn, readFn, length, value) { |
|
this.buildFn = buildFn; |
|
this.readFn = readFn; |
|
this.length = length; |
|
this.value = value; |
|
} |
|
|
|
for (var i = -n; i <= n; i++) { |
|
entries.push(new Entry(buildFns.appendInt32LE, readFns.readInt32LE, 4, i)); |
|
entries.push(new Entry(buildFns.appendInt32BE, readFns.readInt32BE, 4, i)); |
|
entries.push(new Entry(buildFns.appendUInt32LE, readFns.readUInt32LE, 4, Math.abs(i))); |
|
entries.push(new Entry(buildFns.appendUInt32BE, readFns.readUInt32BE, 4, Math.abs(i))); |
|
entries.push(new Entry(buildFns.appendInt16LE, readFns.readInt16LE, 2, i)); |
|
entries.push(new Entry(buildFns.appendInt16BE, readFns.readInt16BE, 2, i)); |
|
entries.push(new Entry(buildFns.appendUInt16LE, readFns.readUInt16LE, 2, Math.abs(i))); |
|
entries.push(new Entry(buildFns.appendUInt16BE, readFns.readUInt16BE, 2, Math.abs(i))); |
|
entries.push(new Entry(buildFns.appendInt8, readFns.readInt8, 1, Math.round(i/50))); |
|
entries.push(new Entry(buildFns.appendUInt8, readFns.readUInt8, 1, Math.abs(Math.round(i/50)))); |
|
entries.push(new Entry(buildFns.appendFloatLE, readFns.readFloatLE, 4, i)); |
|
entries.push(new Entry(buildFns.appendFloatBE, readFns.readFloatBE, 4, i)); |
|
entries.push(new Entry(buildFns.appendDoubleLE, readFns.readDoubleLE, 8, i)); |
|
entries.push(new Entry(buildFns.appendDoubleBE, readFns.readDoubleBE, 8, i)); |
|
} |
|
|
|
for (var i = 0; i < entries.length; i++) { |
|
var entry = entries[i]; |
|
entry.buildFn.call(builder, entry.value); |
|
} |
|
|
|
var result = builder.get(); |
|
var idx = 0; |
|
for (var i = 0; i < entries.length; i++) { |
|
var entry = entries[i]; |
|
var read = entry.readFn.call(result, idx); |
|
assert.equal(read, entry.value); |
|
idx += entry.length; |
|
} |
|
})(); |
|
|
|
/* Newly-created buffer should be empty */ |
|
(function() { |
|
assert.equal(new BufferBuilder().get().length, 0) |
|
})(); |
|
|
|
/* It should concatenating strings. */ |
|
(function() { |
|
var words = ['This', 'is', 'a', 'test']; |
|
var builder = new BufferBuilder(); |
|
for (var i = 0; i < words.length; i++) { |
|
builder.appendString(words[i]); |
|
} |
|
|
|
assert.equal(builder.get().toString(), words.join('')); |
|
})(); |
|
|
|
/* Test appendStringZero */ |
|
(function() { |
|
var words = ['alpha', 'bravo', 'charlie', 'delta']; |
|
var builder = new BufferBuilder(); |
|
for (var i = 0; i < words.length; i++) { |
|
builder.appendStringZero(words[i]); |
|
} |
|
|
|
function appendZero(str) { return str + '\0'; } |
|
assert.equal(builder.get().toString() , words.map(appendZero).join('')); |
|
})(); |
|
|
|
/* copy() sanity checks */ |
|
(function() { |
|
var check = function(low, high, targetStart, sourceStart, sourceEnd) { |
|
var source = new BufferBuilder(); |
|
source.appendFill(1, 10); |
|
var dest = new Buffer(20); |
|
dest.fill(0); |
|
|
|
|
|
source.copy(dest, targetStart, sourceStart, sourceEnd); |
|
for (var i = 0; i < 20; i++) { |
|
assert.equal(dest[i], low<=i && i<high ? 1 : 0); |
|
} |
|
}; |
|
|
|
check(0, 10); |
|
check(3, 13, 3); |
|
check(3, 10, 3, 3); |
|
check(10, 14, 10, 0, 4); |
|
})(); |
|
|
|
/* copy() applied over ranges */ |
|
(function() { |
|
var source = new BufferBuilder(3); |
|
for (var i = 1; i < 100; i++) { |
|
source.appendUInt8(i); |
|
} |
|
|
|
for (var i = 0; i < 20; i++) { |
|
var sourceStart = i*3; |
|
var sourceEnd = source.length - i*5; |
|
var targetStart = i*20; |
|
|
|
var target = new Buffer(1000); |
|
target.fill(0); |
|
source.copy(target, targetStart, sourceStart, sourceEnd); |
|
|
|
for (var i = 0; i < target.length; i++) { |
|
var expected; |
|
if (i >= targetStart && i < targetStart + sourceEnd - sourceStart) { |
|
expected = i - targetStart + sourceStart + 1; |
|
} else { |
|
expected = 0; |
|
} |
|
assert.equal(expected, target[i]); |
|
} |
|
} |
|
})(); |
|
|
|
/* Overlap small chunks over one large copy, making sure that does not change anything. */ |
|
(function() { |
|
var n = 1000; |
|
var builder = new BufferBuilder(10); |
|
var x = .4; |
|
for (var i = 0; i < n; i++) { |
|
builder.appendDoubleLE(x); |
|
x = x * (1-x) * 4; |
|
} |
|
|
|
var buffersMatchOneOff = function(b1, b2) { |
|
// Why one off? Because then sourceStart != targetStart, so I can't have mixed those up in copy(). |
|
assert.equal(b1.length+1, b2.length); |
|
for (var i = 0; i < b1.length; i++) { |
|
assert.equal(b1[i], b2[i+1], 'byte ' + i + ' mismatch'); |
|
} |
|
} |
|
|
|
var original = builder.get(); |
|
var copyTarget = new Buffer(original.length+1); |
|
original.copy(copyTarget, 1); |
|
|
|
buffersMatchOneOff(original, copyTarget); |
|
var copyLength = 105; |
|
var copyStart = 4; |
|
var copyOffset = 143; |
|
for (var i = copyStart; i+copyLength < builder.length; i += copyOffset) { |
|
builder.copy(copyTarget, i+1, i, i + copyLength); |
|
//console.log(copyTarget); |
|
buffersMatchOneOff(original, copyTarget); |
|
} |
|
|
|
})(); |
|
|
|
|
|
/* Try a copy that starts right on a buffer boundary */ |
|
(function() { |
|
var builder = new BufferBuilder(3); |
|
for (var i = 0; i < 10; i++) { |
|
builder.appendUInt8(i); |
|
} |
|
|
|
var dest = new Buffer(7); |
|
builder.copy(dest, 0, 3); |
|
for (var i = 0; i < 7; i++) { |
|
assert.equal(dest[i], i+3); |
|
} |
|
})(); |
|
|
|
/* BufferBuilder.copy() should behave just like Buffer.copy(), including the exceptions thrown */ |
|
(function() { |
|
var builder = new BufferBuilder(5); |
|
for (var i = 0; i < 100; i++) { |
|
builder.appendUInt8(i); |
|
} |
|
var buffer = builder.get(); |
|
|
|
var dest = new Buffer(50); |
|
|
|
var behavesSame = function(f) { |
|
var bufferException, bufferResult, builderException, builderResult; |
|
try { |
|
bufferResult = f(buffer); |
|
} catch (e) { |
|
bufferException = e; |
|
} |
|
try { |
|
builderResult = f(buffer); |
|
} catch (e) { |
|
builderException = e; |
|
} |
|
|
|
assert.equal(bufferResult, builderResult); |
|
assert.equal(''+bufferException, ''+builderException); |
|
}; |
|
|
|
// copies that get cut off because target is small |
|
behavesSame(function(b) { return b.copy(new Buffer(50), 20) }); |
|
behavesSame(function(b) { return b.copy(new Buffer(50)) }); |
|
behavesSame(function(b) { return b.copy(new Buffer(50)) }); |
|
|
|
// targetStart too low |
|
behavesSame(function(b) { return b.copy(new Buffer(50, -1)) }); |
|
// targetStart too high |
|
behavesSame(function(b) { return b.copy(new Buffer(50, 50)) }); |
|
behavesSame(function(b) { return b.copy(new Buffer(50, 51)) }); |
|
|
|
// sourceStart too low |
|
behavesSame(function(b) { return b.copy(new Buffer(50, 0, -4)) }); |
|
// sourceStart too high |
|
behavesSame(function(b) { return b.copy(new Buffer(50, 0, 130)) }); |
|
|
|
// copy cut off by end of source |
|
behavesSame(function(b) { return b.copy(new Buffer(50, 0, 99)) }); |
|
|
|
// degenerate copy |
|
behavesSame(function(b) { return b.copy(new Buffer(50, 0, 99, 99)) }); |
|
|
|
// sourceEnd after sourceStart |
|
behavesSame(function(b) { return b.copy(new Buffer(50, 0, 99, 90)) }); |
|
|
|
// sourceEnd too high |
|
behavesSame(function(b) { return b.copy(new Buffer(50, 0, 99, 150)) }); |
|
|
|
// sourceStart and sourceEnd too high |
|
behavesSame(function(b) { return b.copy(new Buffer(50, 0, 120, 150)) }); |
|
|
|
})(); |
|
|
|
/* Make sure functions are chainable */ |
|
(function() { |
|
var x = new BufferBuilder(); |
|
assert.equal(x, x.appendString('hello')); |
|
assert.equal(x, x.appendUInt16LE(0x7720)); |
|
assert.equal(x, x.appendBuffer(new Buffer([111, 114, 108, 100]))); |
|
assert.equal(x, x.appendFill(33, 3)); |
|
})(); |
|
|
|
/* Test the degenerate copy */ |
|
(function() { |
|
var x = new BufferBuilder(); |
|
x.appendBuffer(new Buffer([2,4,6,8])); |
|
var b = new Buffer(7); |
|
b.fill(0); |
|
x.copy(b, 0,0,0); |
|
assert.equal(b[0], 0); |
|
})();
|
|
|