How much is too much Moose Testing

Its test test and test again day here in the Moose-pen

Today I added in over 70+ tests into '20_fields.t' and I went though almost every conflagration of fields, params, expression and functions I could think of even the expression from hell from this post.

I did today's work by the book meaning I did all the tests first then I did the debugging. Now I am not going to dump 450 plus lines of hash key value pairs here as that would really piss a few people off and I might loose a reader of two, as if anyone really reads this anyway.

I will just give you what I ran into today. First there was the same bug as yesterday only this time on 'Functions'

Can't locate object method "alias" via package "Database::Accessor::Function" at D:\GitHub\database-accessor-driver-dbi\lib/Database/Accessor/Driver/ line 412.

Now if I got that error I am sure as Sherlock going to get the same thing on a 'Database::Accessor::Expression' class as well so I think I will nip both in the bud.

This requires a change in Database::Accessor and the simple solution would be to just add in the 'Database::Accessor::Roles::Alias' role to the 'with' statements of 'Expression' and 'Function' classes. Myself being myself I never like the simple solution So I look at a re factoring my Databse::Accessor roles a little.

Right now as it stands the matrix of my roles vs classes is as follows

| Class | Roles |
| | Alias | Element | Comparators |
| Element | x | x | |
| Function | | x | x |
| Param | x | | x |
| Expression | | x | |

which makes it very clear to me that I should move the 'Alias' role in to the 'Element' role as all four need that 'Alias'

A quick add to the 'Element' role;

        use Moose::Role;
++      with (qw(Database::Accessor::Roles::Alias));
        use namespace::autoclean;

and a quick change to the 'Element' class

        use Moose;
        extends 'Database::Accessor::Base';
--      with qw(Database::Accessor::Roles::Alias
        with qw(
                Database::Accessor::Roles::Element );

and finally a change to the 'Param' class

use Moose;
extends 'Database::Accessor::Base';
-- with qw(Database::Accessor::Roles::Alias);
++ with qw(Database::Accessor::Roles::Element);

and now I no longer get that fail but now I am getting ten fails and they are all the same;

not ok 72 - 2 Fields and a function in an expression and function in an expression all with alias retrieve SQL correct

Looking at the some of the fails I see for the above example I do get this warning coming up

# Expected SQL--> SELECT people.first_name, people.last_name, people.bonus * abs(?) FROM people
# Generated SQL-> SELECT people.first_name, people.last_name, bonus * abs(?) FROM people

So I am missing the default 'view/table' on that 'bonus' and looking at the rest of the warings I see it is the same error, functions and expressions are not using or getting the 'view'.

Now where to track this down. I know that this Database::Accessor test case '57_dad_elements.t' is testing for the correct inheritance of the 'View' down from the DA to the DAD and it is running 100% correct so it it a good chance that the bug is in my Driver::DBI code someplace. So in we go.

After a few mins it all leads to this call in the '_fields_sql' sub

my $sql = $self->_field_sql($field,1);

I am passing in a '1' here after the field to tell the '_field_sql' function that the passed in field should use the 'view/table' name. The error comes with the fact that the '_filed_sql' sub is recursive and I forgot to pass that '1' param into the recursive calls. Keeping that in mind this quick patch;

my ($element,$use_view) = @_;
  if (ref($element) eq "Database::Accessor::Expression"){
      my $left_sql;
      $left_sql = Database::Accessor::Driver::DBI::SQL::OPEN_PARENS
         if ( $element->open_parentheses() );   
--    $left_sql .= $self->_field_sql($element->left());
++      $left_sql .= $self->_field_sql($element->left(),$use_view);
      foreach my $param (@{$element->right()}){
--      push(@right_sql,$self->_field_sql($param));
++        push(@right_sql,$self->_field_sql($param),$use_view);
      my $right_sql = join(',',@right_sql);
      $right_sql   .= Database::Accessor::Driver::DBI::SQL::CLOSE_PARENS

  elsif (ref($element) eq "Database::Accessor::Function"){
--    my $left_sql = $self->_field_sql($element->left());
++      my $left_sql = $self->_field_sql($element->left(),$use_view);
      my @right_sql;
      my $comma = "";

        foreach my $param (@{$element->right()}){
--        push(@right_sql,$self->_field_sql($param));
++          push(@right_sql,$self->_field_sql($param,$use_view));

and unfortunately that is only a partial fix as now I get 8 fails and now I am getting warings like this one

Expected SQL--> SELECT people.first_name, people.last_name, people.bonus * abs(?) FROM people
# Generated SQL-> SELECT people.first_name, people.last_name, people.bonus * abs(?),1 FROM people

Somehow an exta ',1' in there after the funcuntion. Oh well a topic for tomorrow's post.


Leave a comment

About byterock

user-pic Long time Perl guy, a few CPAN mods allot of work on DBD::Oracle and a few YAPC presentations