#! /usr/bin/env perl
use strict;
use warnings;
use Test::TAPv13 ":all";
use Test::Deep;
use Test::More tests => 3;
use Data::DPath 'dpath';
use Data::Dumper;
use Clone 'clone';
use Benchmark ':all', ':hireswallclock';
use Devel::Size 'total_size';
# local $Data::DPath::DEBUG = 1;
local $Data::DPath::USE_SAFE = 0;
BEGIN {
use_ok( 'Data::DPath' );
}
my $base_data = {
'parse_errors' => [
'Bad plan. You planned 6 tests but ran 8.'
],
'tests_run' => 8,
'version' => 13,
'exit' => 0,
'start_time' => '1236463400.25151',
'skip_all' => undef,
'lines' => [
{
'is_comment' => 0,
'has_skip' => 0,
'as_string' => 'TAP version 13',
'is_test' => 0,
'is_yaml' => 0,
'is_plan' => 0,
'is_actual_ok' => 0,
'is_unknown' => 0,
'has_todo' => 0,
'is_bailout' => 0,
'is_pragma' => 0,
'is_version' => 1,
'raw' => 'TAP version 13'
},
{
'is_comment' => 0,
'has_skip' => 0,
'as_string' => '1..6',
'is_test' => 0,
'is_yaml' => 0,
'is_plan' => 1,
'is_actual_ok' => 0,
'is_unknown' => 0,
'has_todo' => 0,
'is_bailout' => 0,
'is_pragma' => 0,
'is_version' => 0,
'raw' => '1..6'
},
{
'is_comment' => 0,
'is_yaml' => 0,
'is_plan' => 0,
'number' => '1',
'is_unknown' => 0,
'is_bailout' => 0,
'is_pragma' => 0,
'is_unplanned' => 0,
'as_string' => 'ok 1 - use Data::DPath;',
'has_skip' => 0,
'is_test' => 1,
'_children' => [
{
'is_comment' => 0,
'has_skip' => 0,
'as_string' => ' ---
- name: \'Hash one\'
value: 1
- name: \'Hash two\'
value: 2
...',
'is_test' => 0,
'is_yaml' => 1,
'is_plan' => 0,
'data' => [
{
'value' => '1',
'name' => 'Hash one'
},
{
'value' => '2',
'name' => 'Hash two'
}
],
'is_actual_ok' => 0,
'is_unknown' => 0,
'has_todo' => 0,
'is_bailout' => 0,
'is_pragma' => 0,
'is_version' => 0,
'raw' => ' ---
- name: \'Hash one\'
value: 1
- name: \'Hash two\'
value: 2
...'
}
],
'is_actual_ok' => 0,
'description' => '- use Data::DPath;',
'is_ok' => 1,
'has_todo' => 0,
'explanation' => '',
'directive' => '',
'type' => 'test',
'is_version' => 0,
'raw' => 'ok 1 - use Data::DPath;'
},
{
'is_comment' => 0,
'is_yaml' => 0,
'is_plan' => 0,
'number' => '2',
'is_unknown' => 0,
'is_bailout' => 0,
'is_pragma' => 0,
'is_unplanned' => 0,
'as_string' => 'ok 2 - KEYs + PARENT',
'has_skip' => 0,
'is_test' => 1,
'is_actual_ok' => 0,
'description' => '- KEYs + PARENT',
'is_ok' => 1,
'has_todo' => 0,
'explanation' => '',
'directive' => '',
'type' => 'test',
'is_version' => 0,
'raw' => 'ok 2 - KEYs + PARENT'
},
{
'is_comment' => 0,
'is_yaml' => 0,
'is_plan' => 0,
'number' => '3',
'is_unknown' => 0,
'is_bailout' => 0,
'is_pragma' => 0,
'is_unplanned' => 0,
'as_string' => 'ok 3 - quoted KEY containg slash',
'has_skip' => 0,
'is_test' => 1,
'is_actual_ok' => 0,
'description' => '- quoted KEY containg slash',
'is_ok' => 1,
'has_todo' => 0,
'explanation' => '',
'directive' => '',
'type' => 'test',
'is_version' => 0,
'raw' => 'ok 3 - quoted KEY containg slash'
},
{
'is_comment' => 0,
'has_skip' => 0,
'as_string' => 'pragma +strict',
'is_test' => 0,
'is_yaml' => 0,
'is_plan' => 0,
'is_actual_ok' => 0,
'is_unknown' => 0,
'has_todo' => 0,
'is_bailout' => 0,
'is_pragma' => 1,
'is_version' => 0,
'raw' => 'pragma +strict'
},
{
'is_comment' => 0,
'is_yaml' => 0,
'is_plan' => 0,
'number' => '4',
'is_unknown' => 0,
'is_bailout' => 0,
'is_pragma' => 0,
'is_unplanned' => 0,
'as_string' => 'not ok 4 # TODO spec only',
'has_skip' => 0,
'is_test' => 1,
'_children' => [
{
'is_comment' => 1,
'has_skip' => 0,
'as_string' => '# Failed (TODO) test at t/data_dpath.t line 144.',
'is_test' => 0,
'is_yaml' => 0,
'is_plan' => 0,
'is_actual_ok' => 0,
'is_unknown' => 0,
'has_todo' => 0,
'is_bailout' => 0,
'is_pragma' => 0,
'is_version' => 0,
'raw' => '# Failed (TODO) test at t/data_dpath.t line 144.'
},
{
'is_comment' => 1,
'has_skip' => 0,
'as_string' => '# Structures begin differing at:',
'is_test' => 0,
'is_yaml' => 0,
'is_plan' => 0,
'is_actual_ok' => 0,
'is_unknown' => 0,
'has_todo' => 0,
'is_bailout' => 0,
'is_pragma' => 0,
'is_version' => 0,
'raw' => '# Structures begin differing at:'
},
{
'is_comment' => 1,
'has_skip' => 0,
'as_string' => '# $got->[0] = Does not exist',
'is_test' => 0,
'is_yaml' => 0,
'is_plan' => 0,
'is_actual_ok' => 0,
'is_unknown' => 0,
'has_todo' => 0,
'is_bailout' => 0,
'is_pragma' => 0,
'is_version' => 0,
'raw' => '# $got->[0] = Does not exist'
},
{
'is_comment' => 1,
'has_skip' => 0,
'as_string' => '# $expected->[0] = ARRAY(0x8e4c238)',
'is_test' => 0,
'is_yaml' => 0,
'is_plan' => 0,
'is_actual_ok' => 0,
'is_unknown' => 0,
'has_todo' => 0,
'is_bailout' => 0,
'is_pragma' => 0,
'is_version' => 0,
'raw' => '# $expected->[0] = ARRAY(0x8e4c238)'
}
],
'is_actual_ok' => 0,
'description' => '',
'is_ok' => 1,
'has_todo' => 1,
'explanation' => 'spec only',
'directive' => 'TODO',
'type' => 'test',
'is_version' => 0,
'raw' => 'not ok 4 # TODO spec only'
},
{
'is_comment' => 0,
'is_yaml' => 0,
'is_plan' => 0,
'number' => '5',
'is_unknown' => 0,
'is_bailout' => 0,
'is_pragma' => 0,
'is_unplanned' => 0,
'as_string' => 'ok 5 - ANYWHERE + KEY + FILTER int # TODO spec only',
'has_skip' => 0,
'is_test' => 1,
'is_actual_ok' => 1,
'description' => '- ANYWHERE + KEY + FILTER int',
'is_ok' => 1,
'has_todo' => 1,
'explanation' => 'spec only',
'directive' => 'TODO',
'type' => 'test',
'is_version' => 0,
'raw' => 'ok 5 - ANYWHERE + KEY + FILTER int # TODO spec only'
},
{
'is_comment' => 0,
'is_yaml' => 0,
'is_plan' => 0,
'number' => '6',
'is_unknown' => 0,
'is_bailout' => 0,
'is_pragma' => 0,
'is_unplanned' => 0,
'as_string' => 'ok 6 # SKIP rethink twice',
'has_skip' => 1,
'is_test' => 1,
'is_actual_ok' => 0,
'description' => '',
'is_ok' => 1,
'has_todo' => 0,
'explanation' => 'rethink twice',
'directive' => 'SKIP',
'type' => 'test',
'is_version' => 0,
'raw' => 'ok 6 # skip rethink twice'
},
{
'is_comment' => 0,
'is_yaml' => 0,
'is_plan' => 0,
'number' => '7',
'is_unknown' => 0,
'is_bailout' => 0,
'is_pragma' => 0,
'is_unplanned' => 1,
'as_string' => 'not ok 7 # TODO spec only',
'has_skip' => 0,
'is_test' => 1,
'_children' => [
{
'is_comment' => 1,
'has_skip' => 0,
'as_string' => '# Failed (TODO) test at t/data_dpath.t line 356.',
'is_test' => 0,
'is_yaml' => 0,
'is_plan' => 0,
'is_actual_ok' => 0,
'is_unknown' => 0,
'has_todo' => 0,
'is_bailout' => 0,
'is_pragma' => 0,
'is_version' => 0,
'raw' => '# Failed (TODO) test at t/data_dpath.t line 356.'
},
{
'is_comment' => 1,
'has_skip' => 0,
'as_string' => '# Structures begin differing at:',
'is_test' => 0,
'is_yaml' => 0,
'is_plan' => 0,
'is_actual_ok' => 0,
'is_unknown' => 0,
'has_todo' => 0,
'is_bailout' => 0,
'is_pragma' => 0,
'is_version' => 0,
'raw' => '# Structures begin differing at:'
},
{
'is_comment' => 1,
'has_skip' => 0,
'as_string' => '# $got->[0] = Does not exist',
'is_test' => 0,
'is_yaml' => 0,
'is_plan' => 0,
'is_actual_ok' => 0,
'is_unknown' => 0,
'has_todo' => 0,
'is_bailout' => 0,
'is_pragma' => 0,
'is_version' => 0,
'raw' => '# $got->[0] = Does not exist'
},
{
'is_comment' => 1,
'has_skip' => 0,
'as_string' => '# $expected->[0] = \'interesting value\'',
'is_test' => 0,
'is_yaml' => 0,
'is_plan' => 0,
'is_actual_ok' => 0,
'is_unknown' => 0,
'has_todo' => 0,
'is_bailout' => 0,
'is_pragma' => 0,
'is_version' => 0,
'raw' => '# $expected->[0] = \'interesting value\''
}
],
'is_actual_ok' => 0,
'description' => '',
'is_ok' => 0,
'has_todo' => 1,
'explanation' => 'spec only',
'directive' => 'TODO',
'type' => 'test',
'is_version' => 0,
'raw' => 'not ok 7 # TODO spec only'
},
{
'is_comment' => 0,
'is_yaml' => 0,
'is_plan' => 0,
'number' => '8',
'is_unknown' => 0,
'is_bailout' => 0,
'is_pragma' => 0,
'is_unplanned' => 1,
'as_string' => 'ok 8 - FILTER eval regex # TODO too dirty, first cleanup _filter_eval',
'has_skip' => 0,
'is_test' => 1,
'is_actual_ok' => 1,
'description' => '- FILTER eval regex',
'is_ok' => 0,
'has_todo' => 1,
'explanation' => 'too dirty, first cleanup _filter_eval',
'directive' => 'TODO',
'type' => 'test',
'is_version' => 0,
'raw' => 'ok 8 - FILTER eval regex # TODO too dirty, first cleanup _filter_eval'
},
],
'is_good_plan' => 0,
'has_problems' => 2,
'end_time' => '1236463400.25468',
'pragmas' => [
'strict'
],
'plan' => '1..6',
'tests_planned' => 6
};
my $resultlist;
# ---------- prepare ----------
my $path = '//lines//description[ value =~ m(use Data::DPath) ]/../_children//data//name[ value eq "Hash two"]/../value';
my $expected = "2";
$resultlist = [ dpath($path)->match($base_data) ];
# diag Dumper($resultlist);
cmp_deeply $resultlist, [ $expected ], "base_data";
diag "Prepare big data...";
my $huge_data;
my $multi = 1000;
my @huge_expected = map { $expected } 1..$multi;
$huge_data->{$_} = clone ( $base_data ) foreach 1..$multi;
diag "Data size: ".total_size ($huge_data);
diag "Running benchmark. Can take some time ...";
my $count = 3;
my $t = timeit ($count, sub { $resultlist = [ dpath($path)->match($huge_data) ] });
my $n = $t->[5];
my $throughput = $n / $t->[0];
#diag Dumper($huge_data);
# diag Dumper(\@huge_expected);
# diag Dumper($resultlist);
diag Dumper($t);
cmp_deeply $resultlist, [ @huge_expected ], "huge_data";
tap13_yaml({ benchmark => {
timestr => timestr($t),
wallclock => $t->[0],
usr => $t->[1],
sys => $t->[2],
throughput => $throughput,
},
});