use Test::More;
use Data::Dumper;
-plan tests => 5;
+plan tests => 11;
use_ok('Parse::Binary::Nested');
-my $example = Parse::Binary::Nested->new([
+my @example = (
foos => [
'C',
message => 'Z*',
- period => 'C',
+ period => 'a',
],
trail => 'a*',
-]);
-ok($example, 'example parser');
-my $data = $example->unpackf("\2foo\0!\0.rest");
-is(ref $data, 'HASH', 'output structure');
-is($data->{foos}->[1]->{period}, ord '.', 'sample element');
+);
+my $testdata = "\2foo\0!\0.rest";
+my $testresult = {
+ foos => [
+ {message => 'foo', period => '!'},
+ {message => '', period => '.'},
+ ],
+ trail => 'rest',
+};
+my $parser = Parse::Binary::Nested->new(\@example);
+ok($parser, 'new object');
+is_deeply($parser->unpackf($testdata), $testresult, 'object unpackf');
+
+Parse::Binary::Nested->import('unpackf');
is_deeply(
- Parse::Binary::Nested->new(
- [ lstr => 'Ca3', rest => 'a*' ]
- )->unpackf("\2quux"),
+ unpackf(\@example, $testdata),
+ $testresult,
+ 'unprepared unpackf'
+);
+
+my @commonargs = ('cxaXv', "\1\2hi\0");
+is_deeply(
+ [ values %{ unpackf(@commonargs) } ],
+ [[ unpack($commonargs[0], $commonargs[1]) ]],
+ 'unpack compatibility'
+);
+
+is_deeply(
+ unpackf([ lstr => 'C/a3', rest => 'a*' ], "\2quux"),
{ lstr => 'qu', rest => 'x' },
'length string'
);
+is_deeply(
+ unpackf([ ignoreme => 'x2X', value => 'xC' ], "\0\1\2"),
+ { value => 2 },
+ 'empty values'
+);
+
+is_deeply(
+ unpackf([
+ begin => 'c',
+ asciiz => ['?0', lead => 'v', string => 'Z*'],
+ end => 'c',
+ ], "\377\1\0Hi\0\2\0zer0\0\0\376"),
+ {
+ begin => -1,
+ asciiz => [
+ { lead => 1, string => 'Hi' },
+ { lead => 2, string => 'zer0' },
+ ],
+ end => -2,
+ },
+ 'zero-terminated group'
+);
+
+my $looptest = Parse::Binary::Nested->new([
+ begin => 'xc',
+ loop => ['?1', lead => 'c', string => 'Z*'],
+ end => '=.',
+]);
+is_deeply(
+ $looptest->unpackf("\0\1\0Hello\0\377bye"),
+ {
+ begin => 1,
+ loop => [
+ { lead => 0, string => 'Hello' },
+ { lead => -1, string => 'bye' },
+ ],
+ end => 15,
+ },
+ 'unterminated group'
+);
+is_deeply(
+ $looptest->unpackf("\0\1\1trailing"),
+ {
+ begin => 1,
+ end => 3,
+ },
+ 'preterminated group'
+);
+
+is_deeply(
+ unpackf([
+ loop => ['?0', byte => 'C'],
+ ], "\1\2\3"),
+ {
+ loop => [map { {byte => $_} } 1..3],
+ },
+ 'last byte in unterminated loop'
+);
+