blob: 31258553cd13dc3481577ee432af55a473e17bcb [file] [log] [blame]
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#!/usr/bin/env perl
use strict;
use warnings;
use Avro::Schema;
use Config;
use Test::More;
use Test::Exception;
use Math::BigInt;
use_ok 'Avro::BinaryEncoder';
sub primitive_ok {
my ($primitive_type, $primitive_val, $expected_enc) = @_;
my $data;
my $meth = "encode_$primitive_type";
Avro::BinaryEncoder->$meth(
undef, $primitive_val, sub { $data = ${$_[0]} }
);
is $data, $expected_enc, "primitive $primitive_type encoded correctly";
return $data;
}
## some primitive testing
{
primitive_ok null => undef, '';
primitive_ok null => 'whatev', '';
primitive_ok boolean => 0, "\x0";
primitive_ok boolean => 1, "\x1";
## - high-bit of each byte should be set except for last one
## - rest of bits are:
## - little endian
## - zigzag coded
primitive_ok long => 0, pack("C*", 0);
primitive_ok long => 1, pack("C*", 0x2);
primitive_ok long => -1, pack("C*", 0x1);
primitive_ok int => -1, pack("C*", 0x1);
primitive_ok int => -20, pack("C*", 0b0010_0111);
primitive_ok int => 20, pack("C*", 0b0010_1000);
primitive_ok int => 63, pack("C*", 0b0111_1110);
primitive_ok int => 64, pack("C*", 0b1000_0000, 0b0000_0001);
my $p =
primitive_ok int => -65, pack("C*", 0b1000_0001, 0b0000_0001);
primitive_ok int => 65, pack("C*", 0b1000_0010, 0b0000_0001);
primitive_ok int => 99, "\xc6\x01";
## BigInt values still work
primitive_ok int => Math::BigInt->new(-65), $p;
throws_ok {
my $toobig;
if ($Config{use64bitint}) {
$toobig = 1<<32;
}
else {
require Math::BigInt;
$toobig = Math::BigInt->new(1)->blsft(32);
}
primitive_ok int => $toobig, undef;
} "Avro::BinaryEncoder::Error", "33 bits";
throws_ok {
primitive_ok int => Math::BigInt->new(1)->blsft(63), undef;
} "Avro::BinaryEncoder::Error", "65 bits";
for (qw(long int)) {
throws_ok {
primitive_ok $_ => "x", undef;
} 'Avro::BinaryEncoder::Error', 'numeric values only';
};
# In Unicode, there are decimals that aren't 0-9.
# Make sure we handle non-ascii decimals cleanly.
for (qw(long int)) {
throws_ok {
primitive_ok $_ => "\N{U+0661}", undef;
} 'Avro::BinaryEncoder::Error', 'ascii decimals only';
};
}
## spec examples
{
my $enc = '';
my $schema = Avro::Schema->parse(q({ "type": "string" }));
Avro::BinaryEncoder->encode(
schema => $schema,
data => "foo",
emit_cb => sub { $enc .= ${ $_[0] } },
);
is $enc, "\x06\x66\x6f\x6f", "Binary_Encodings.Primitive_Types";
$schema = Avro::Schema->parse(<<EOJ);
{
"type": "record",
"name": "test",
"fields" : [
{"name": "a", "type": "long"},
{"name": "b", "type": "string"}
]
}
EOJ
$enc = '';
Avro::BinaryEncoder->encode(
schema => $schema,
data => { a => 27, b => 'foo' },
emit_cb => sub { $enc .= ${ $_[0] } },
);
is $enc, "\x36\x06\x66\x6f\x6f", "Binary_Encodings.Complex_Types.Records";
$enc = '';
$schema = Avro::Schema->parse(q({"type": "array", "items": "long"}));
Avro::BinaryEncoder->encode(
schema => $schema,
data => [3, 27],
emit_cb => sub { $enc .= ${ $_[0] } },
);
is $enc, "\x04\x06\x36\x00", "Binary_Encodings.Complex_Types.Arrays";
$enc = '';
$schema = Avro::Schema->parse(q(["string","null"]));
Avro::BinaryEncoder->encode(
schema => $schema,
data => undef,
emit_cb => sub { $enc .= ${ $_[0] } },
);
is $enc, "\x02", "Binary_Encodings.Complex_Types.Unions-null";
$enc = '';
Avro::BinaryEncoder->encode(
schema => $schema,
data => "a",
emit_cb => sub { $enc .= ${ $_[0] } },
);
is $enc, "\x00\x02\x61", "Binary_Encodings.Complex_Types.Unions-a";
}
done_testing;