it('should write a map encoded as a series of blocks, each block consists of a long count, followed by that many key/value pairs, a block count of 0 indicates the end of the map', function(){ var schema = Avro.Schema({ "name": "headers", "type": { "type": "map", "values": "string" } }); var data = { "user-agent": "firefox", "remote-ip": "10.0.0.0", "content-type": "applicaiton/json" } var block = DataFile.Block(); var writer = IO.DatumWriter(schema); var encoder = IO.BinaryEncoder(block); writer.writeMap(schema, data, encoder); var i = 0; block.toBuffer()[i++].should.equal(_.size(data) * 2); // zig-zag encoding _.each(data, function(value, key) { block.toBuffer()[i++].should.equal(key.length * 2); // zig-zag encoding block.toBuffer().slice(i,i + key.length).toString().should.equal(key); i += key.length; block.toBuffer()[i++].should.equal(value.length * 2); // zig-zag encoding block.toBuffer().slice(i,i + value.length).toString().should.equal(value); i += value.length; }) });
it('should encode a record by encoding the values of its fields in the order that they are declared', function(){ var schema = Avro.Schema({ "name": "user", "type": "record", "fields": [ {"name":"firstName","type": "string"}, {"name":"lastName","type": "string"}, {"name":"age","type": "int"} ] }); var data = { "firstName": "bob", "lastName": "the_builder", "age": 40 } var block = DataFile.Block(); var writer = IO.DatumWriter(schema); var encoder = IO.BinaryEncoder(block); writer.writeRecord(schema, data, encoder); block.toBuffer()[0].should.equal(data.firstName.length * 2); // zig-zag encoding block.toBuffer().slice(1,4).toString().should.equal(data.firstName); block.toBuffer()[4].should.equal(data.lastName.length * 2); // zig-zag encoding block.toBuffer().slice(5,16).toString().should.equal(data.lastName); block.toBuffer()[16].should.equal(data.age * 2); })
it('should encode a string as a long of its length, followed by the utf8 encoded string', function(){ var schema = Avro.Schema({ "type": "string" }); var block = DataFile.Block(); var writer = IO.DatumWriter(schema); var encoder = IO.BinaryEncoder(block); writer.write("testing", encoder); block.toBuffer().toString().should.equal("\u000etesting"); });
it('should encode an int/long with zig-zag encoding', function() { var schema = Avro.Schema({ "type": "int" }); var block = DataFile.Block(); var writer = IO.DatumWriter(schema); var encoder = IO.BinaryEncoder(block); writer.write(-64, encoder); block.toBuffer()[0].should.equal(127); });
it('should encode an array as a series of blocks, each block consists of a long count value, followed by that many array items, a block with count zero indicates the end of the array', function(){ var schema = Avro.Schema({ "type": "array", "items": "long", }); var block = DataFile.Block(); var writer = IO.DatumWriter(schema); var encoder = IO.BinaryEncoder(block); var testArray = [10, 20, 30, 40, 50]; writer.writeArray(schema, testArray, encoder); block.toBuffer().equals(new Buffer([testArray.length * 2, 20, 40, 60, 80, 100, 0])).should.be.true; })
it('should write an eneration encoded by its index', function(){ var schema = Avro.Schema({ "type": "enum", "name": "phonetics", "symbols": [ "Alpha", "Bravo", "Charlie", "Delta"] }); var block = DataFile.Block(); var writer = IO.DatumWriter(schema); var encoder = IO.BinaryEncoder(block); writer.writeEnum(schema, "Charlie", encoder); writer.writeEnum(schema, "Delta", encoder); block.toBuffer()[0].should.equal(4); block.toBuffer()[1].should.equal(6); });
it('should add a series of bytes specified by the schema', function(){ var schema = Avro.Schema({ "type": "fixed", "name": "telephone", "size": 10 }); var block = DataFile.Block(); var writer = IO.DatumWriter(schema); var encoder = IO.BinaryEncoder(block); var testString = "1234567890"; writer.writeFixed(schema, testString, encoder); block.toBuffer().toString().should.equal(testString); block.toBuffer().length.should.equal(testString.length); })
it('should encode a union as a long of the zero-based schema position, followed by the value according to the schema at that position', function(){ var schema = Avro.Schema([ "int", "string", "null" ]); var block = DataFile.Block(); var writer = IO.DatumWriter(schema); var encoder = IO.BinaryEncoder(block); var record = "test"; writer.write(record, encoder); block.toBuffer().toString().should.equal("\u0002\u0008test"); block.flush(); var record = null; writer.write(record, encoder); block.toBuffer()[0].should.equal(4); });
it('should encode a record as the values of its fields in the order of declaration', function(){ var schema = Avro.Schema({ "type" : "record", "name" : "IntStringRecord", "fields" : [ { "name" : "intField", "type" : "int" }, { "name" : "stringField", "type" : "string" }] }); var block = DataFile.Block(); var writer = IO.DatumWriter(schema); var encoder = IO.BinaryEncoder(block); var record = { intField: 1, stringField: "abc" }; writer.write(record, encoder); block.toBuffer().toString().should.equal("\u0002\u0006abc"); });
it('should encode a union by first writing a long value indicating the zero-based position within the union of the schema of its value, followed by the encoded value according to that schema', function(){ var schema = Avro.Schema([ "string", "int" ]); var data = "testing a union"; var block = DataFile.Block(); var writer = IO.DatumWriter(schema); var encoder = IO.BinaryEncoder(block); writer.writeUnion(schema, data, encoder); block.toBuffer().length.should.equal(data.length + 2); block.toBuffer()[0].should.equal(0); block.toBuffer()[1].should.equal(data.length * 2); block.toBuffer().slice(2).toString().should.equal(data); block.flush(); writer.writeUnion(schema, 44, encoder); block.toBuffer().length.should.equal(2); block.toBuffer()[0].should.equal(2); block.toBuffer()[1].should.equal(44 * 2); });
it('should encode a nested schema', function() { var schema = Avro.Schema({ "fields": [ { "name": "host", "type": "string" }, { "name": "time", "type": "string" }, { "name": "elapsedTime", "type": "long" }, { "name": "request", "type": { "name": "Request", "type": "record", "fields": [ { "name": "headers", "type": { "type": "map", "values": "string" } }, { "name": "method", "type": "string" }, { "name": "path", "type": "string" }, { "name": "queryString", "type": [ "string", "null" ] }, { "name": "body", "type": { "type": "map", "values": "string" } } ] } }, { "name": "exception", "type": [ { "fields": [ { "name": "class", "type": "string" }, { "name": "message", "type": "string" }, { "name": "stackTrace", "type": [ "null", "string" ] } ], "name": "AppException", "type": "record" }, "null" ] } ], "name": "LogEvent", "namespace": "e.d.c.b.a", "type": "record" }); var block = DataFile.Block(); var writer = IO.DatumWriter(schema); var encoder = IO.BinaryEncoder(block); var log = { host: "testhostA", time: "1970-01-01T00:00Z", elapsedTime: 123456789, request: { headers: { "user-agent": "firefox", "remote-ip": "0.0.0.0" }, method: "GET", path: "/basepath/object", queryString: "param1=test1¶m2=test2", body: {} }, exception: { "AppException": { "class": "org.apache.avro", message: "An error occurred", stackTrace: "failed at line 1" } } } writer.write(log, encoder); block.toBuffer().equals(new Buffer([0x12, 0x74, 0x65, 0x73, 0x74, 0x68, 0x6f, 0x73, 0x74, 0x41, 0x22, 0x31, 0x39, 0x37, 0x30, 0x2d, 0x30, 0x31, 0x2d, 0x30, 0x31, 0x54, 0x30, 0x30, 0x3a, 0x30, 0x30, 0x5a, 0xaa, 0xb4, 0xde, 0x75, 0x04, 0x14, 0x75, 0x73, 0x65, 0x72, 0x2d, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x0e, 0x66, 0x69, 0x72, 0x65, 0x66, 0x6f, 0x78, 0x12, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2d, 0x69, 0x70, 0x0e, 0x30, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x30, 0x00, 0x06, 0x47, 0x45, 0x54, 0x20, 0x2f, 0x62, 0x61, 0x73, 0x65, 0x70, 0x61, 0x74, 0x68, 0x2f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x00, 0x32, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x31, 0x3d, 0x74, 0x65, 0x73, 0x74, 0x31, 0x26, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x32, 0x3d, 0x74, 0x65, 0x73, 0x74, 0x32, 0x00, 0x00, 0x1e, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x61, 0x76, 0x72, 0x6f, 0x22, 0x41, 0x6e, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x6f, 0x63, 0x63, 0x75, 0x72, 0x72, 0x65, 0x64, 0x02, 0x20, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x20, 0x61, 0x74, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x31])).should.be.true; })
(function() { var dummyBlock = { write: 0 }; var invalidEncoder = IO.BinaryEncoder(dummyBlock); }).should.throwError();
(function() { var invalidEncoder = IO.BinaryEncoder(); }).should.throwError();
beforeEach(function(){ block = DataFile.Block(); encoder = IO.BinaryEncoder(block); })