Ever More Testy Moose
It is go back again day here in the Moose-pen
In my last bunch of posts I though I had finally got all my element view, parentheses and 'AND' ; checking coming out all OK so I started today by going back to here I left off in Driver::DBI. The first thing I did was re-run the test suite and I ran into this
# Failed test 'Where with function and 1 param SQL correct' # at D:\GitHub\database-accessor-driver-dbi\t\lib/Test/Utils.pm line 56. # Expected SQL--> SELECT people.first_name, people.last_name, people.user_id FROM people WHERE length(people.last_name) = ? # Generated SQL-> SELECT people.first_name, people.last_name, people.user_id FROM people WHERE AND length(people.last_name) = ?
in the '20_where_basic.t' case and similar one all over the rest of the test cases. I guess I am adding an 'AND' in there when there is only one condition. Back to Database::Accessor I go.
The first thing I forgot to do it put in a test in '58_parenthes.t' that tests for no add of 'AND' when there is only one condition. This leads to this question what if the user adds in only one conditions and leaves in a 'condition' attribute, like this;
$da->add_condition(
{
left => $expression,
right => { value => '201' },
operator => '=',
condition => 'AND',
}
);
Now do I fail the above or do I play smarty pants and just drop the 'AND' before I send it to the DAD. As I am doing the same sort of thing with 'view', by inheriting the DA's view I think I will do the same sort of thing here.
Now my test looks like this;
$da = Database::Accessor->new($in_hash);
$da->add_condition(
{
left => $expression,
right => { value => '201' },
operator => '=',
}
);
ok(
$da->retrieve( Data::Test->new(), $return ),
"Balanced nested elements on condition"
);
$dad = $da->result->error();
ok( !$da->result->error->conditions->[0]->predicates->condition() ,
'AND condition not added when only 1 condition in conditions array' );
$da->reset_conditions();
$da->add_condition(
{
left => $expression,
right => { value => '201' },
operator => '=',
condition => 'AND',
}
);
$da->retrieve( Data::Test->new(), $return );
ok( !$da->result->error->conditions->[0]->predicates->condition(),
'AND condition ignored when present and only 1 condition in conditions array' );
$da->reset_conditions();
$da->add_condition([
{
left => $expression,
right => { value => '201' },
operator => '=',
},
{
left => $expression,
right => { value => '201' },
operator => '=',
}]
);
$da->retrieve( Data::Test->new(), $return );
ok(! $da->result->error->conditions->[0]->predicates->condition(),
'AND not present on first condition predicate' );
ok( $da->result->error->conditions->[1]->predicates->condition() eq 'AND',
'AND present on second condition predicate' );
...
which should cover all the possibilities. Of course when I run the above I get I will get one pass and three expected fails;
not ok 14 - AND condition not added when only 1 condition in conditions array
not ok 15 - AND condition ignored when present and only 1 condition in conditions array
not ok 16 - AND not present on first condition predicate
ok 17 - AND present on second condition predicate
After a little while tracing this back the first thing that I notices was that my '_has_conditions' count was accumulating way off between 'executes' and I fixed that by adding this in
...
private_method _elements_check => sub {
my $self = shift;
my ($action) = @_;
$self->_reset_parens();
++ $self->_reset_conditions();
…
That did not solve my problem directly but it was the first step as next all I had to do was check to see if my count is two or more like this;
...
elsif (ref($element) eq 'Database::Accessor::Condition'){
$element->predicates->condition(Database::Accessor::Constants::AND)
-- if ( $self->_has_conditions and !$element->predicates->condition() );
++ if ( $self->_has_conditions>=2 and !$element->predicates->condition() );
…
and that squishes two fails
ok 14 - AND condition not added when only 1 condition in conditions array
not ok 15 - AND condition ignored when present and only 1 condition in conditions array
ok 16 - AND not present on first condition predicate
ok 17 - AND present on second condition predicate
Next a line to take out the 'AND', or any other condition, if there is only one condition is present;
...
$element->predicates->condition(Database::Accessor::Constants::AND)
if ( $self->_has_conditions>=2 and !$element->predicates->condition() );
++ $element->predicates->condition(undef)
++ if ( $self->_has_conditions<=1);
$self->_check_parentheses($element->predicates);
…
and now
...
ok 14 - AND condition not added when only 1 condition in conditions array
ok 15 - AND condition ignored when present and only 1 condition in conditions array
ok 16 - AND not present on first condition predicate
ok 17 - AND present on second condition predicate
…
When I go back and run '20_where_basic.t' from Driver::DBI I now get the correct
SELECT people.first_name, people.last_name, people.user_id FROM people WHERE length(people.last_name) = ?
for my SQL.
Next will be to add in a bunch more tests the check for the same sort of thing where other conditions are used but I am not going to bore you with those!
Leave a comment