diff options
author | Jason Cooper <scrapheap@heckrothindustries.co.uk> | 2019-12-22 20:07:57 +0000 |
---|---|---|
committer | Jason Cooper <scrapheap@heckrothindustries.co.uk> | 2019-12-22 20:07:57 +0000 |
commit | 163f1b63f70c6c5831e15cb5485538d40ec33468 (patch) | |
tree | f41d7ac084ae407261b3769b3ed2278f1adf5a62 | |
parent | 5fd586cb8a2591a142c4b38249589c338e97e25b (diff) | |
parent | 77da0c34a95ec1554db47a71edb17447de6eda86 (diff) |
Merge branch 'feature/one-shot-failure' into 'master'
Feature: one shot failure
Closes #2
See merge request scrapheap/DBD-Mock!19
-rw-r--r-- | lib/DBD/Mock.pm | 25 | ||||
-rw-r--r-- | lib/DBD/Mock/db.pm | 56 | ||||
-rw-r--r-- | t/023_statement_failure.t | 21 |
3 files changed, 70 insertions, 32 deletions
diff --git a/lib/DBD/Mock.pm b/lib/DBD/Mock.pm index be239ac..3f81a68 100644 --- a/lib/DBD/Mock.pm +++ b/lib/DBD/Mock.pm @@ -447,7 +447,7 @@ according to the value of C<mock_can_connect>. So if C<mock_can_connect> were to be set to C<0> (or off), then both C<Active> and C<ping> would return false values (or C<0>). -=item B<C<mock_add_resultset( \@resultset | \%sql_and_resultset )>> +=item B<C<mock_add_resultset( \@resultset | \%resultset_and_options )>> This stocks the database handle with a record set, allowing you to seed data for your application to see if it works properly. Each recordset is a simple @@ -498,7 +498,21 @@ Here is a sample usage, partially from the test suite: # this will fetch rows from the second resultset... my $row = $sth->fetchrow_arrayref; -You can also associate a resultset with a particular SQL statement instead of +It is possible to assign a hashref where the resultset must be given as +value for the C<results> key: + + $dbh->{mock_add_resultset} = { + results => [ + [ 'foo', 'bar' ], + [ 'this_one', 'that_one' ], + [ 'this_two', 'that_two' ], + ], + }; + +The reason for the hashref form is that you can add options as described +in the following. + +You can associate a resultset with a particular SQL statement instead of adding them in the order they will be fetched: $dbh->{mock_add_resultset} = { @@ -601,6 +615,13 @@ number and error string, in that order. failure => [ 5, 'Ooops!' ], }; +Without the C<sql> attribute the next statement will fail in any case: + + $dbh->{mock_add_resultset} = { + results => DBD::Mock->NULL_RESULTSET, + failure => [ 5, 'Ooops!' ], + }; + =item B<C<mock_get_info>> This attribute can be used to set up values for C<get_info()>. It takes a diff --git a/lib/DBD/Mock/db.pm b/lib/DBD/Mock/db.pm index 5c65788..80ba29d 100644 --- a/lib/DBD/Mock/db.pm +++ b/lib/DBD/Mock/db.pm @@ -110,19 +110,22 @@ sub prepare { else { # If we have available resultsets seed the tracker with one - my $rs; - my $callback; + my ($rs, $callback, $failure); + if ( my $all_rs = $dbh->{mock_rs} ) { if ( my $by_name = defined $all_rs->{named}{$statement} ? $all_rs->{named}{$statement} : first { $statement =~ m/$_->{regexp}/ } @{ $all_rs->{matching} } ) { # We want to copy this, because it is meant to be reusable $rs = [ @{ $by_name->{results} } ]; $callback = $by_name->{callback}; - if ( exists $by_name->{failure} ) { - $track_params{failure} = [ @{ $by_name->{failure} } ]; - } + $failure = $by_name->{failure}; } else { $rs = shift @{ $all_rs->{ordered} }; + if (ref($rs) eq 'HASH') { + $callback = $rs->{callback}; + $failure = $rs->{failure}; + $rs = [ @{ $rs->{results} } ]; + } } } @@ -131,6 +134,7 @@ sub prepare { $track_params{return_data} = $rs; $track_params{fields} = $fields; $track_params{callback} = $callback; + $track_params{failure} = $failure; if( $fields ) { $sth->STORE( NAME => $fields ); @@ -344,51 +348,55 @@ sub STORE { return $value; } elsif ( $attrib eq 'mock_add_resultset' ) { + my @copied_values; + $dbh->{mock_rs} ||= { named => {}, ordered => [], matching => [], }; + if ( ref $value eq 'ARRAY' ) { - my @copied_values = @{$value}; + @copied_values = @{$value}; push @{ $dbh->{mock_rs}{ordered} }, \@copied_values; - return \@copied_values; } elsif ( ref $value eq 'HASH' ) { my $name = $value->{sql}; - unless ($name) { - die "Indexing resultset by name requires passing in 'sql' ", - "as hashref key to 'mock_add_resultset'.\n"; - } - my @copied_values = @{ $value->{results} ? $value->{results} : [] }; + @copied_values = @{ $value->{results} ? $value->{results} : [] }; - if ( ref $name eq "Regexp" ) { + if (not defined $name) { + push @{ $dbh->{mock_rs}{ordered} }, { + results => \@copied_values, + callback => $value->{callback}, + failure => ref($value->{failure}) ? [ @{ $value->{failure} } ] : undef, + }; + } + elsif ( ref $name eq "Regexp" ) { my $matching = { regexp => $name, results => \@copied_values, callback => $value->{callback}, - + failure => ref($value->{failure}) ? [ @{ $value->{failure} } ] : undef, }; - if ( exists $value->{failure} ) { - $matching->{failure} = [ @{ $value->{failure} }, ]; - } # either replace existing match or push grep { $_->{regexp} eq $name && ($_ = $matching) } @{ $dbh->{mock_rs}{matching} } or push @{ $dbh->{mock_rs}{matching} }, $matching; - } else { - $dbh->{mock_rs}{named}{$name} = { results => \@copied_values, callback => $value->{callback} }; - if ( exists $value->{failure} ) { - $dbh->{mock_rs}{named}{$name}{failure} = [ @{ $value->{failure} }, ]; - } } - - return \@copied_values; + else { + $dbh->{mock_rs}{named}{$name} = { + results => \@copied_values, + callback => $value->{callback}, + failure => ref($value->{failure}) ? [ @{ $value->{failure} } ] : undef, + }; + } } else { die "Must provide an arrayref or hashref when adding ", "resultset via 'mock_add_resultset'.\n"; } + + return \@copied_values; } elsif ( $attrib eq 'mock_start_insert_id' ) { if ( ref $value eq 'ARRAY' ) { diff --git a/t/023_statement_failure.t b/t/023_statement_failure.t index 7ae8df4..873565a 100644 --- a/t/023_statement_failure.t +++ b/t/023_statement_failure.t @@ -13,19 +13,28 @@ BEGIN { # test misc. attributes { - my $dbh = DBI->connect('DBI:Mock:', 'user', 'pass'); + my $dbh = DBI->connect('DBI:Mock:', '', '', {RaiseError => 1, PrintError => 0}); isa_ok($dbh, 'DBI::db'); - + + $dbh->{mock_add_resultset} = { + results => DBD::Mock->NULL_RESULTSET, + failure => [ 3, 'Ohlala!' ], + }; + + my $sth = eval { $dbh->prepare('INSERT INTO bar (foo) VALUES (?)') }; + ok(!$@, '$sth handle prepared correctly'); + isa_ok($sth, 'DBI::st'); + + eval { $sth->execute('baz') }; + ok( $@, '$sth handled executed and died' ); + $dbh->{mock_add_resultset} = { sql => qr/SELECT/, results => DBD::Mock->NULL_RESULTSET, failure => [ 5, 'Ooops!' ], }; - $dbh->{PrintError} = 0; - $dbh->{RaiseError} = 1; - - my $sth = eval { $dbh->prepare('SELECT foo FROM bar') }; + $sth = eval { $dbh->prepare('SELECT foo FROM bar') }; ok(!$@, '$sth handle prepared correctly'); isa_ok($sth, 'DBI::st'); |