Yaffs site version 1.1
[yaffs-website] / vendor / gabordemooij / redbean / testing / RedUNIT / Base / Typechecking.php
1 <?php
2
3 namespace RedUNIT\Base;
4
5 use RedUNIT\Base as Base;
6 use RedBeanPHP\Facade as R;
7 use RedBeanPHP\RedException as RedException;
8 use RedBeanPHP\OODBBean as OODBBean;
9
10 /**
11  * Typechecking
12  *
13  * Tests whether RedBeanPHP handles type casting correctly.
14  *
15  * @file    RedUNIT/Base/Typechecking.php
16  * @desc    Tests basic bean validation rules; invalid bean handling.
17  * @author  Gabor de Mooij and the RedBeanPHP Community
18  * @license New BSD/GPLv2
19  *
20  * (c) G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community.
21  * This source file is subject to the New BSD/GPLv2 License that is bundled
22  * with this source code in the file license.txt.
23  */
24 class Typechecking extends Base
25 {
26         /**
27          * Test types.
28          * Test how RedBeanPHP OODB and OODBBean handle type and type casts.
29          *
30          * Rules:
31          *
32          * 1. before storing a bean all types are preserved except booleans (they are converted to STRINGS '0' or '1')
33          * 2. after store-reload all bean property values are STRINGS or NULL
34          *    (or ARRAYS but that's only from a user perspective because these are lazy loaded)
35          * 3. the ID returned by store() is an INTEGER (if possible; on 32 bit systems overflowing values will be cast to STRINGS!)
36          *
37          * After loading:
38          * ALL VALUES EXCEPT NULL -> STRING
39          * NULL -> NULL
40          *
41          * @note Why not simply return bean->id in store()? Because not every driver returns the same type:
42          * databases without insert_id support require a separate query or a suffix returning STRINGS, not INTEGERS.
43          *
44          * @note Why not preserve types? I.e. I store integer, why do I get back a string?
45          * Answer: types are handled different across database platforms, would cause overhead to inspect every value for type,
46          * also PHP is a dynamically typed language so types should not matter that much. Another reason: due to the nature
47          * of RB columns in the database might change (INT -> STRING) this would cause return types to change as well which would
48          * cause 'cascading errors', i.e. a column gets widened and suddenly your code would break.
49          *
50          * @note Unfortunately the 32/64-bit issue cannot be tested fully. Return-strategy store() is probably the safest
51          * solution.
52          *
53          * @return void
54          */
55         public function testTypes()
56         {
57                 testpack( 'Beans can only contain STRING and NULL after reload' );
58                 R::nuke();
59                 $bean = R::dispense( 'bean' );
60                 $bean->number   = 123;
61                 $bean->float    = 12.3;
62                 $bean->bool     = false;
63                 $bean->bool2    = true;
64                 $bean->text     = 'abc';
65                 $bean->null     = null;
66                 $bean->datetime = new\DateTime( 'NOW', new\DateTimeZone( 'Europe/Amsterdam' ) );
67                 $id = R::store( $bean );
68                 asrt( is_int( $id ), TRUE );
69                 asrt( is_float( $bean->float ), TRUE );
70                 asrt( is_integer( $bean->number ), TRUE );
71                 asrt( is_string( $bean->bool ), TRUE );
72                 asrt( is_string( $bean->bool2 ), TRUE );
73                 asrt( is_string( $bean->datetime ), TRUE );
74                 asrt( is_string( $bean->text ), TRUE );
75                 asrt( is_null( $bean->null ), TRUE );
76                 $bean = R::load('bean', $id );
77                 asrt( is_string( $bean->id ), TRUE );
78                 asrt( is_string( $bean->float ), TRUE );
79                 asrt( is_string( $bean->number ), TRUE );
80                 asrt( is_string( $bean->bool ), TRUE );
81                 asrt( is_string( $bean->bool2 ), TRUE );
82                 asrt( is_string( $bean->datetime ), TRUE );
83                 asrt( is_string( $bean->text ), TRUE );
84                 asrt( is_null( $bean->null ), TRUE );
85                 asrt( $bean->bool, '0' );
86                 asrt( $bean->bool2, '1' );
87         }
88
89         /**
90          * Test bean type checking.
91          *
92          * @return void
93          */
94         public function testBeanTypeChecking()
95         {
96                 $redbean = R::getRedBean();
97                 $bean    = $redbean->dispense( "page" );
98                 // Set some illegal values in the bean; this should trigger Security exceptions.
99                 // Arrays are not allowed.
100                 $bean->name = array( "1" );
101                 try {
102                         $redbean->store( $bean );
103                         fail();
104                 } catch ( RedException $e ) {
105                         pass();
106                 }
107                 try {
108                         $redbean->check( $bean );
109                         fail();
110                 } catch ( RedException $e ) {
111                         pass();
112                 }
113                 $bean->name = new OODBBean;
114                 try {
115                         $redbean->check( $bean );
116                         fail();
117                 } catch ( RedException $e ) {
118                         pass();
119                 }
120                 // Property names should be alphanumeric
121                 $prop        = ".";
122                 $bean->$prop = 1;
123                 try {
124                         $redbean->store( $bean );
125                         fail();
126                 } catch ( RedException $e ) {
127                         pass();
128                 }
129                 try {
130                         $redbean->check( $bean );
131                         fail();
132                 } catch ( RedException $e ) {
133                         pass();
134                 }
135                 // Really...
136                 $prop        = "-";
137                 $bean->$prop = 1;
138                 try {
139                         $redbean->store( $bean );
140                         fail();
141                 } catch ( RedException $e ) {
142                         pass();
143                 }
144                 try {
145                         $redbean->check( $bean );
146                         fail();
147                 } catch ( RedException $e ) {
148                         pass();
149                 }
150         }
151 }