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/DBI.pm 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;


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

and a quick change to the 'Element' class

    Database::Accessor::Element;
        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

package
Database::Accessor::Param;
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 = "";

       $element->right([$param]);
        }
        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.

hp3877.jpg

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