PHP on T R A X
Rapid Application Development Made Easy

root/trunk/trax/test/ActiveRecordTest.php

Revision 208, 36.9 kB (checked in by john, 3 years ago)

fixing test for new format

  • Property svn:executable set to *
  • Property svn:keywords set to Id
Line 
1 <?php
2 /**
3  *  File for the ActiveRecordTest class
4  *
5  * (PHP 5)
6  *
7  * @package PHPonTraxTest
8  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
9  * @copyright (c) Walter O. Haas 2006
10  * @version $Id$
11  * @author Walt Haas <haas@xmission.com>
12  */
13
14 echo "testing ActiveRecord\n";
15 require_once 'testenv.php';
16
17 //  We need to load a mock DB class to test ActiveRecord.
18 //  Change the include path to put the mockDB/ directory first, so
19 //  that when ActiveRecord loads it will pick up the mock class.
20 @ini_set('include_path','./mockDB:'.ini_get('include_path'));
21 require_once "active_record.php";
22
23 // Call ActiveRecordTest::main() if this source file is executed directly.
24 if (!defined("PHPUnit2_MAIN_METHOD")) {
25     define("PHPUnit2_MAIN_METHOD", "ActiveRecordTest::main");
26 }
27
28 require_once "PHPUnit2/Framework/TestCase.php";
29 require_once "PHPUnit2/Framework/TestSuite.php";
30
31 /**
32  *  Require classes that are too trivial to bother making mocks
33  */
34 require_once 'trax_exceptions.php';
35 require_once 'inflector.php';
36
37 // You may remove the following line when all tests have been implemented.
38 require_once "PHPUnit2/Framework/IncompleteTestError.php";
39
40 // Set Trax operating mode
41 define("TRAX_ENV",   "development");
42
43 /**
44  *  Regression tester for the ActiveRecord class
45  *
46  *  This class is used only in regression testing of the ActiveRecord
47  *  class, but you might find some useful examples by reading it.
48  */
49   class PersonName extends ActiveRecord {
50       //  Function to validate prefix attribute
51       function validate_prefix() {
52           if ($this->prefix == '') {
53               return array(false, "prefix empty");
54           } else {
55               return array(true);
56           }
57       }
58
59       //  Create another copy of this class
60       function new_obj($attributes) {
61           return $this->create($attributes);
62       }
63 }
64
65 class DB_find_all_result extends DB_result {
66     // Data to be returned by fetchMode
67     private $data = array(array('id' => '17',
68                                 'prefix' => '',
69                                 'first_name' => 'Ben',
70                                 'mi' => '',
71                                 'last_name' => 'Dover',
72                                 'suffix' => ''),
73                           array('id' => '23',
74                                 'prefix' => '',
75                                 'first_name' => 'Eileen',
76                                 'mi' => '',
77                                 'last_name' => 'Dover',
78                                 'suffix' => '')
79                           );
80
81     private $row_num = 0;
82
83     function fetchRow() {
84         if ($this->row_num >= count($this->data)) {
85             return null;
86         }
87         return $this->data[$this->row_num++];
88     }
89 }
90
91 /**
92  * Test class for {@link ActiveRecord}
93  */
94 class ActiveRecordTest extends PHPUnit2_Framework_TestCase {
95
96     /**
97      * Runs the test methods of this class.
98      *
99      * @access public
100      * @static
101      */
102     public static function main() {
103         require_once "PHPUnit2/TextUI/TestRunner.php";
104
105         $suite  = new PHPUnit2_Framework_TestSuite("ActiveRecordTest");
106         $result = PHPUnit2_TextUI_TestRunner::run($suite);
107     }
108
109     /**
110      *  Set the environment ActiveRecord expects
111      */
112     protected function setUp() {
113
114         //  Force constructor to get a connection
115         Trax::$active_record_connections = array();
116
117         // Set up information that normally comes from database.ini
118         Trax::$database_settings[TRAX_ENV]
119             = array('phptype'    => 'mysql',
120                     'database'   => 'database_development',
121                     'hostspec'   => 'localhost',
122                     'username'   => 'root',
123                     'password'   => '',
124                     'persistent' => true);
125     }
126
127     /**
128      *  This method is called after a test is executed.
129      */
130     protected function tearDown() {
131     }
132
133     /**
134      *  Test constructor
135      */
136     public function test__construct() {
137         $p = new PersonName;
138         $this->assertEquals(get_class($p), 'PersonName');
139         $this->assertEquals($p->table_name, 'person_names');
140         $this->assertTrue(Trax::$active_record_connections[TRAX_ENV]->options['persistent']);
141         //  We don't completely check content_columns
142         $this->assertTrue(is_array($p->content_columns));
143         $this->assertEquals(count($p->content_columns),6);
144         //  There are a lot of notice level error messages in normal
145         //  operation.  We know about them and don't want to confuse
146         //  testing with them.
147         error_reporting(E_USER_WARNING);
148
149         $p = new PersonName(array('id' => '17', 'first_name' => 'Boris',
150                                   'last_name' => 'Tudeth'));
151         $this->assertEquals($p->first_name,'Boris');
152         $this->assertEquals($p->last_name,'Tudeth');
153         error_reporting(E_USER_NOTICE);
154     }
155
156     /**
157      *  Test the get_attributes() method
158      */
159     public function testGet_attributes() {
160         $p = new PersonName;
161         //  Constructor initializes all attributes to null
162         //  There are a lot of notice level error messages in normal
163         //  operation.  We know about them and don't want to confuse
164         //  testing with them.
165         error_reporting(E_USER_WARNING);
166         $attrs = $p->get_attributes();
167         $this->assertEquals($attrs,array('id'         => null,
168                                          'prefix'     => null,
169                                          'first_name' => null,
170                                          'mi'         => null,
171                                          'last_name'  => null,
172                                          'suffix'     => null));
173         //  Assign some attribute values
174         $p->id         = 17;
175         $p->prefix     = 'Dr.';
176         $p->first_name = 'Anon';
177         $p->mi         = 'E';
178         $p->last_name  = 'Moose';
179         $p->suffix     = 'Ph.D.';
180
181         //  This shouldn't produce notice level messages
182         error_reporting(E_USER_NOTICE);
183
184         //  get_attributes() should return the same values
185         $attrs = $p->get_attributes();
186         $this->assertEquals($attrs,array('id'         => 17,
187                                          'prefix'     => 'Dr.',
188                                          'first_name' => 'Anon',
189                                          'mi'         => 'E',
190                                          'last_name'  => 'Moose',
191                                          'suffix'     => 'Ph.D.'));
192     }
193
194     /**
195      *  Test the update_attributes() method
196      *  @todo Figure out the datetime thing and how to test it
197      */
198     public function testUpdate_attributes() {
199         $p = new PersonName;
200         $p->update_attributes(array('id'         => 17,
201                                     'prefix'     => 'Dr.',
202                                     'first_name' => 'Anon',
203                                     'mi'         => 'E',
204                                     'last_name'  => 'Moose',
205                                     'suffix'     => 'Ph.D.'));
206         $attrs = $p->get_attributes();
207         $this->assertEquals($attrs,array('id'         => 17,
208                                          'prefix'     => 'Dr.',
209                                          'first_name' => 'Anon',
210                                          'mi'         => 'E',
211                                          'last_name'  => 'Moose',
212                                          'suffix'     => 'Ph.D.'));
213         // Remove the following line when you complete this test.
214         throw new PHPUnit2_Framework_IncompleteTestError;
215     }
216
217     /**
218      *  Test the quoted_attributes() method
219      *  @todo Figure out how to test timestamp updating
220      */
221     public function testQuoted_attributes() {
222         $p = new PersonName;
223         //  Constructor initializes all attributes to null.
224         //  quoted_attributes() returns null as null string
225         $attrs = $p->quoted_attributes();
226         $this->assertEquals($attrs,array('id'         => "''",
227                                          'prefix'     => "''",
228                                          'first_name' => "''",
229                                          'mi'         => "''",
230                                          'last_name'  => "''",
231                                          'suffix'     => "''"));
232         //  Assign some attribute values
233         $p->id         = 17;
234         $p->prefix     = '"Dr."';
235         $p->first_name = 'Nobody';
236         $p->mi         = 'X';
237         $p->last_name  = 'O\'Reilly';
238         $p->suffix     = 'Back\\slash';
239         //  Get attributes with quotes
240         $attrs = $p->quoted_attributes();
241         $this->assertEquals($attrs,array('id'         => "'17'",
242                                          'prefix'     => "'\\\"Dr.\\\"'",
243                                          'first_name' => "'Nobody'",
244                                          'mi'         => "'X'",
245                                          'last_name'  => "'O\'Reilly'",
246                                          'suffix'     => "'Back\\\\slash'"));
247         // Test the optional argument
248         $p = new PersonName;
249         $attrs = $p->quoted_attributes(
250                                array('id'         => 17,
251                                      'prefix'     => '"Dr."',
252                                      'first_name' => 'Nobody',
253                                      'mi'         => 'X',
254                                      'last_name'  => 'O\'Reilly',
255                                      'suffix'     => 'Back\\slash'));
256         $this->assertEquals($attrs,array('id'         => "'17'",
257                                          'prefix'     => "'\\\"Dr.\\\"'",
258                                          'first_name' => "'Nobody'",
259                                          'mi'         => "'X'",
260                                          'last_name'  => "'O\'Reilly'",
261                                          'suffix'     => "'Back\\\\slash'"));
262     }
263
264     /**
265      *  Test the validate_model_attributes() method
266      */
267     public function testValidate_model_attributes() {
268         $p = new PersonName;
269         $p->update_attributes(array('id'         => 17,
270                                     'prefix'     => 'Dr.',
271                                     'first_name' => 'Anon',
272                                     'mi'         => 'E',
273                                     'last_name'  => 'Moose',
274                                     'suffix'     => 'Ph.D.'));
275         //  With failing validation, should return false and error msg
276         $p->prefix = '';
277         $result = $p->validate_model_attributes();
278         $this->assertFalse($result);
279         $this->assertEquals(count($p->errors),1);
280         $this->assertEquals($p->errors['prefix'], 'prefix empty');
281     }
282
283     /**
284      *  Test the query() method
285      */
286     public function testQuery() {
287         //  Test normal case: send query, get result
288         $p = new PersonName;
289         Trax::$active_record_connections[TRAX_ENV]->expect_query('foo','bar');
290         $result = $p->query('foo');
291         $this->assertEquals($result,'bar');
292     }
293
294     /**
295      *  Test the get_insert_id() method
296      */
297     public function testGet_insert_id() {
298         $p = new PersonName;
299         Trax::$active_record_connections[TRAX_ENV]->expect_query("SELECT LAST_INSERT_ID();",
300                                                    '17');
301         $result =& $p->get_insert_id();
302         $this->assertEquals($result,'17');
303     }
304
305     /**
306      *  Test the is_error() method
307      */
308     public function testIs_error() {
309         $p = new PersonName;
310         //  Create a new harmless object, test it's not an error
311         $obj = new PHPUnit2_Framework_Assert;
312         $this->assertFalse($p->is_error($obj));
313         //  Create a PHP 4 error, test it is detected
314         $obj = new PEAR_Error('testing');
315         $this->assertTrue($p->is_error($obj));
316         //  Create a DB error, test it is detected
317         $obj = new DB_Error('testing');
318         $this->assertTrue($p->is_error($obj));
319     }
320
321     /**
322      *  Test the get_primary_key_conditions() method
323      */
324     public function testGet_primary_key_conditions() {
325         $p = new PersonName;
326         //  Default is primary key is 'id', no value
327         $result = $p->get_primary_key_conditions();
328         $this->assertEquals($result,"id = ''");
329         //  Now give the primary key a value
330         $p->id = 11;
331         $result = $p->get_primary_key_conditions();
332         $this->assertEquals($result,"id = '11'");
333         //  Try a different column as primary key
334         $p->primary_keys=array('last_name');
335         $result = $p->get_primary_key_conditions();
336         $this->assertEquals($result,"last_name = ''");
337         $p->last_name = "Smith";
338         $result = $p->get_primary_key_conditions();
339         $this->assertEquals($result,"last_name = 'Smith'");
340         //  Try two columns as primary key
341         $p->primary_keys=array('id', 'last_name');
342         $result = $p->get_primary_key_conditions();
343         $this->assertEquals($result,"id = '11' AND last_name = 'Smith'");
344     }
345
346     /**
347      *  Test the get_updates_sql() method
348      */
349     public function testGet_updates_sql() {
350         //  Apply some attributes
351         $p = new PersonName;
352         $p->id         = 17;
353         $p->prefix     = 'Dr.';
354         $p->first_name = 'Anon';
355         $p->mi         = 'E';
356         $p->last_name  = 'Moose';
357         $p->suffix     = 'Ph.D.';
358         $result = $p->get_updates_sql();
359         $this->assertEquals($result,
360                        "prefix = 'Dr.', first_name = 'Anon',"
361                       ." mi = 'E', last_name = 'Moose', suffix = 'Ph.D.'");
362         //  Assign some attribute values that need to be quoted
363         $p = new PersonName;
364         $p->id         = 17;
365         $p->prefix     = '"Dr."';
366         $p->first_name = 'Nobody';
367         $p->mi         = 'X';
368         $p->last_name  = 'O\'Reilly';
369         $p->suffix     = 'Back\\slash';
370         $result = $p->get_updates_sql();
371         $this->assertEquals($result,
372              "prefix = '\\\"Dr.\\\"', first_name = 'Nobody',"
373             ." mi = 'X', last_name = 'O\'Reilly', suffix = 'Back\\\\slash'");
374     }
375
376     /**
377      *  Test the save() method
378      *  @todo Write test of save() of existing row
379      */
380     public function testSave() {
381         //  A valid new row should be inserted
382         $p = new PersonName;
383         Trax::$active_record_connections[TRAX_ENV]->expect_queries(array(
384           array('query' => "INSERT INTO person_names"
385              ." (id, prefix, first_name, mi, last_name, suffix)"
386              ." VALUES ('', 'Dr.', 'Anon', 'E', 'Moose', 'Ph.D.')",
387                 'result' => DB_OK),
388           array('query' => "SELECT LAST_INSERT_ID();",
389                 'result' => '17')));
390         $result = $p->save(array('prefix'     => 'Dr.',
391                                  'first_name' => 'Anon',
392                                  'mi'         => 'E',
393                                  'last_name'  => 'Moose',
394                                  'suffix'     => 'Ph.D.'));
395         $this->assertTrue($result);
396         //  Verify DB received all expected queries
397         Trax::$active_record_connections[TRAX_ENV]->tally_queries();
398
399         // An invalid row should fail immediately
400         $p = new PersonName;
401         $result = $p->save(array('first_name' => 'Anon',
402                                  'mi'         => 'E',
403                                  'last_name'  => 'Moose',
404                                  'suffix'     => 'Ph.D.'));
405         $this->assertFalse($result);
406         $this->assertEquals(count($p->errors),1);
407         $this->assertEquals($p->errors['prefix'], 'prefix empty');
408
409         //  An invalid new row with validation disabled should be inserted
410         $p = new PersonName;
411         Trax::$active_record_connections[TRAX_ENV]->expect_queries(array(
412           array('query' => "INSERT INTO person_names"
413              ." (id, prefix, first_name, mi, last_name, suffix)"
414              ." VALUES ('', '', 'Anon', 'E', 'Moose', 'Ph.D.')",
415                 'result' => DB_OK),
416           array('query' => "SELECT LAST_INSERT_ID();",
417                 'result' => '17')));
418         $result = $p->save(array('first_name' => 'Anon',
419                                  'mi'         => 'E',
420                                  'last_name'  => 'Moose',
421                                  'suffix'     => 'Ph.D.'),true);
422         $this->assertTrue($result);
423         //  Verify DB received all expected queries
424         Trax::$active_record_connections[TRAX_ENV]->tally_queries();
425         // Remove the following line when you complete this test.
426         throw new PHPUnit2_Framework_IncompleteTestError;
427     }
428
429     /**
430      *  Test the add_error() method
431      */
432     public function testAdd_error() {
433         $p = new PersonName;
434         $this->assertTrue(is_array($p->errors));
435         $this->assertEquals(count($p->errors),0);
436         $p->add_error('mumble is scrogged','mumble');
437         $this->assertEquals($p->errors,
438                             array('mumble' => 'mumble is scrogged'));
439         $p->add_error('veeblefitzer foobar');
440         $this->assertEquals($p->errors,
441                             array('mumble' => 'mumble is scrogged',
442                                   '0' => 'veeblefitzer foobar'));
443     }
444
445
446     /**
447      *  Test the find_all() method
448      *  @todo Tests for limit, joins parameters
449      */
450     public function testFind_all() {
451
452