summaryrefslogtreecommitdiff
path: root/t/05concathash.t
diff options
context:
space:
mode:
Diffstat (limited to 't/05concathash.t')
-rw-r--r--t/05concathash.t190
1 files changed, 190 insertions, 0 deletions
diff --git a/t/05concathash.t b/t/05concathash.t
new file mode 100644
index 0000000..554fc34
--- /dev/null
+++ b/t/05concathash.t
@@ -0,0 +1,190 @@
+# Before `make install' is performed this script should be runnable with
+# `make test'. After `make install' it should work as `perl CatHash.t'
+
+#########################
+
+# change 'tests => 1' to 'tests => last_test_to_print';
+
+use strict;
+use Benchmark qw(:all);
+use Scalar::Util qw(looks_like_number);
+no warnings 'uninitialized';
+
+use Test::More tests => 41;
+
+BEGIN { use_ok('DBI') };
+
+# null and undefs -- segfaults?;
+is (DBI::_concat_hash_sorted(undef, "=", ":", 0, undef), undef);
+is (DBI::_concat_hash_sorted({ }, "=", ":", 0, undef), "");
+eval { DBI::_concat_hash_sorted([], "=", ":", 0, undef) };
+like ($@ || "", qr/is not a hash reference/);
+is (DBI::_concat_hash_sorted({ }, undef, ":", 0, undef), "");
+is (DBI::_concat_hash_sorted({ }, "=", undef, 0, undef), "");
+is (DBI::_concat_hash_sorted({ }, "=", ":", undef, undef),"");
+
+# simple cases
+is (DBI::_concat_hash_sorted({ 1=>"a", 2=>"b" }, "=", ", ", undef, undef), "1='a', 2='b'");
+# nul byte in key sep and pair sep
+# (nul byte in hash not supported)
+is DBI::_concat_hash_sorted({ 1=>"a", 2=>"b" }, "=\000=", ":\000:", undef, undef),
+ "1=\000='a':\000:2=\000='b'", 'should work with nul bytes in kv_sep and pair_sep';
+is DBI::_concat_hash_sorted({ 1=>"a\000a", 2=>"b" }, "=", ":", 1, undef),
+ "1='a.a':2='b'", 'should work with nul bytes in hash value (neat)';
+is DBI::_concat_hash_sorted({ 1=>"a\000a", 2=>"b" }, "=", ":", 0, undef),
+ "1='a\000a':2='b'", 'should work with nul bytes in hash value (not neat)';
+
+# Simple stress tests
+# limit stress when performing automated testing
+# eg http://www.nntp.perl.org/group/perl.cpan.testers/2009/06/msg4374116.html
+my $stress = $ENV{AUTOMATED_TESTING} ? 1_000 : 10_000;
+ok(DBI::_concat_hash_sorted({bob=>'two', fred=>'one' }, "="x$stress, ":", 1, undef));
+ok(DBI::_concat_hash_sorted({bob=>'two', fred=>'one' }, "=", ":"x$stress, 1, undef));
+ok(DBI::_concat_hash_sorted({map {$_=>undef} (1..1000)}, "="x$stress, ":", 1, undef));
+ok(DBI::_concat_hash_sorted({map {$_=>undef} (1..1000)}, "=", ":"x$stress, 1, undef), 'test');
+ok(DBI::_concat_hash_sorted({map {$_=>undef} (1..100)}, "="x$stress, ":"x$stress, 1, undef), 'test');
+
+my $simple_hash = {
+ bob=>"there",
+ jack=>12,
+ fred=>"there",
+ norman=>"there",
+ # sam =>undef
+};
+
+my $simple_numeric = {
+ 1=>"there",
+ 2=>"there",
+ 16 => 'yo',
+ 07 => "buddy",
+ 49 => undef,
+};
+
+my $simple_mixed = {
+ bob=>"there",
+ jack=>12,
+ fred=>"there",
+ sam =>undef,
+ 1=>"there",
+ 32=>"there",
+ 16 => 'yo',
+ 07 => "buddy",
+ 49 => undef,
+};
+
+my $simple_float = {
+ 1.12 =>"there",
+ 3.1415926 =>"there",
+ 32=>"there",
+ 1.6 => 'yo',
+ 0.78 => "buddy",
+ 49 => undef,
+};
+
+#eval {
+# DBI::_concat_hash_sorted($simple_hash, "=",,":",1,12);
+#};
+ok(1," Unknown sort order");
+#like ($@, qr/Unknown sort order/, "Unknown sort order");
+
+
+
+## Loopify and Add Neat
+
+
+my %neats = (
+ "Neat"=>0,
+ "Not Neat"=> 1
+);
+my %sort_types = (
+ guess=>undef,
+ numeric => 1,
+ lexical=> 0
+);
+my %hashes = (
+ Numeric=>$simple_numeric,
+ "Simple Hash" => $simple_hash,
+ "Mixed Hash" => $simple_mixed,
+ "Float Hash" => $simple_float
+);
+
+for my $sort_type (keys %sort_types){
+ for my $neat (keys %neats) {
+ for my $hash (keys %hashes) {
+ test_concat_hash($hash, $neat, $sort_type);
+ }
+ }
+}
+
+sub test_concat_hash {
+ my ($hash, $neat, $sort_type) = @_;
+ my @args = ($hashes{$hash}, "=", ":",$neats{$neat}, $sort_types{$sort_type});
+ is (
+ DBI::_concat_hash_sorted(@args),
+ _concat_hash_sorted(@args),
+ "$hash - $neat $sort_type"
+ );
+}
+
+if (0) {
+ eval {
+ cmpthese(200_000, {
+ Perl => sub {_concat_hash_sorted($simple_hash, "=", ":",0,undef); },
+ C=> sub {DBI::_concat_hash_sorted($simple_hash, "=", ":",0,1);}
+ });
+
+ print "\n";
+ cmpthese(200_000, {
+ NotNeat => sub {DBI::_concat_hash_sorted(
+ $simple_hash, "=", ":",1,undef);
+ },
+ Neat => sub {DBI::_concat_hash_sorted(
+ $simple_hash, "=", ":",0,undef);
+ }
+ });
+ };
+}
+#CatHash::_concat_hash_values({ }, ":-",,"::",1,1);
+
+
+sub _concat_hash_sorted {
+ my ( $hash_ref, $kv_separator, $pair_separator, $use_neat, $num_sort ) = @_;
+ # $num_sort: 0=lexical, 1=numeric, undef=try to guess
+
+ return undef unless defined $hash_ref;
+ die "hash is not a hash reference" unless ref $hash_ref eq 'HASH';
+ my $keys = _get_sorted_hash_keys($hash_ref, $num_sort);
+ my $string = '';
+ for my $key (@$keys) {
+ $string .= $pair_separator if length $string > 0;
+ my $value = $hash_ref->{$key};
+ if ($use_neat) {
+ $value = DBI::neat($value, 0);
+ }
+ else {
+ $value = (defined $value) ? "'$value'" : 'undef';
+ }
+ $string .= $key . $kv_separator . $value;
+ }
+ return $string;
+}
+
+sub _get_sorted_hash_keys {
+ my ($hash_ref, $sort_type) = @_;
+ if (not defined $sort_type) {
+ my $sort_guess = 1;
+ $sort_guess = (not looks_like_number($_)) ? 0 : $sort_guess
+ for keys %$hash_ref;
+ $sort_type = $sort_guess;
+ }
+
+ my @keys = keys %$hash_ref;
+ no warnings 'numeric';
+ my @sorted = ($sort_type)
+ ? sort { $a <=> $b or $a cmp $b } @keys
+ : sort @keys;
+ #warn "$sort_type = @sorted\n";
+ return \@sorted;
+}
+
+1;