#!/usr/bin/perl
my
$RUNS
= 500;
my
$DEEP
= 2;
my
$KEYS
= 20;
plan
tests
=>
$RUNS
;
use
BSON
qw/encode decode/
;
srand
;
my
$level
= 0;
my
@codex
= (
\
&int32
, \
&doub
, \
&str
, \
&hash
, \
&arr
, \
&dt
, \
&bin
,
\
&re
, \
&oid
, \
&min
, \
&max
, \
&ts
, \
&null
, \
&bool
, \
&code
);
if
(
$Config
{
'use64bitint'
} ) {
push
@codex
, \
&int64
;
}
for
my
$count
( 1 ..
$RUNS
) {
my
$ar
= hash(
$KEYS
);
my
$bson
= encode(
$ar
);
my
$ar1
= decode(
$bson
);
is_deeply(
$ar
,
$ar1
);
}
sub
int32 {
return
int
(
rand
( 2**32 / 2 ) ) * (
int
(
rand
(2) ) ? -1 : 1 );
}
sub
int64 {
return
int
(
rand
( 2**32 / 2 ) + 2**32 ) * (
int
(
rand
(2) ) ? -1 : 1 );
}
sub
doub {
return
rand
( 2**64 ) * (
int
(
rand
(2) ) ? -1 : 1 );
}
sub
str {
my
$len
=
int
(
rand
(255) ) + 1;
my
@a
=
map
{
(
'A'
..
'Z'
,
'a'
..
'z'
,
' '
,
'0'
..
'9'
)[
rand
( 26 + 26 + 11 ) ]
} 1 ..
$len
;
return
BSON::String->new(
join
(
''
,
@a
) );
}
sub
dt { BSON::Time->new(
abs
( int32() ) ) }
sub
bin { BSON::Binary->new( str(),
int
(
rand
(5) ) ) }
sub
re {
qr/\w\a+\s$/
i }
sub
oid { BSON::ObjectId->new }
sub
min { BSON::MinKey->new }
sub
max { BSON::MaxKey->new }
sub
ts { BSON::Timestamp->new(
abs
( int32() ),
abs
( int32() ) ) }
sub
null {
undef
}
sub
bool { BSON::Bool->new(
int
(
rand
(2) ) ) }
sub
code { BSON::Code->new( str(), hash() ) }
sub
rnd {
my
$sub
=
$codex
[
int
(
rand
(
@codex
) ) ];
return
$sub
->(
$level
);
}
sub
arr {
return
[]
if
$level
>
$DEEP
;
$level
++;
my
$len
=
int
(
rand
(20) ) + 1;
my
@a
= ();
for
( 1 ..
$len
) {
push
@a
, rnd(
$level
+ 1 );
}
$level
--;
return
\
@a
;
}
sub
hash {
return
{}
if
$level
>
$DEEP
;
$level
++;
my
$hash
= {};
for
my
$idx
( 1 ..
$KEYS
) {
$hash
->{
"key_$idx"
} = rnd(
$level
+ 1 );
}
$level
--;
return
$hash
;
}