File Coverage

blib/lib/XAO/testcases/FS/placeholders.pm
Criterion Covered Total %
statement 12 248 4.8
branch 0 4 0.0
condition 0 6 0.0
subroutine 4 24 16.6
pod 0 8 0.0
total 16 290 5.5


line stmt bran cond sub pod time code
1             package XAO::testcases::FS::placeholders;
2 1     1   678 use strict;
  1         2  
  1         27  
3 1     1   469 use XAO::Utils;
  1         18877  
  1         65  
4 1     1   7 use Error qw(:try);
  1         2  
  1         4  
5              
6 1     1   169 use base qw(XAO::testcases::FS::base);
  1         1  
  1         454  
7              
8             # If we have /Customers/Orders and /Orders and then drop_placeholder on
9             # /Customers it also drops /Orders from _MEMORY_, not from the
10             # database. Should not do that!
11             #
12             # AM: 2003-10-09
13             #
14             sub test_double_drop_20031009 {
15 0     0 0   my $self=shift;
16 0           my $odb=$self->get_odb();
17              
18 0           my $root=$odb->fetch('/');
19 0           $root->add_placeholder(
20             name => 'Orders',
21             type => 'list',
22             class => 'Data::Order',
23             key => 'order_id',
24             );
25              
26 0           $self->assert($root->exists('Orders'),
27             "Orders was not created");
28              
29 0           my $c1=$root->get('Customers')->get('c1');
30 0           $c1->add_placeholder(
31             name => 'Orders',
32             type => 'list',
33             class => 'Data::Product',
34             key => 'order_id',
35             );
36              
37 0           $self->assert($c1->exists('Orders'),
38             "c1/Orders was not created");
39              
40 0           $root->drop_placeholder('Customers');
41              
42 0           $self->assert(!$root->exists('Customers'),
43             "Customers exists after drop_placeholder (1)");
44 0           $self->assert($root->exists('Orders'),
45             "Orders does not exist, but should");
46              
47 0           $root->add_placeholder(
48             name => 'Customers',
49             type => 'list',
50             class => 'Data::Customer',
51             key => 'order_id',
52             );
53              
54 0           $self->assert($root->exists('Customers'),
55             "Customers was not created");
56              
57 0           $root->drop_placeholder('Customers');
58              
59 0           $self->assert(!$root->exists('Customers'),
60             "Customers exists after drop_placeholder (2)");
61 0           $self->assert($root->exists('Orders'),
62             "Orders does not exist, but should");
63              
64 0           $root->drop_placeholder('Orders');
65              
66 0           $self->assert(!$root->exists('Customers'),
67             "Customers exists after drop_placeholder (3)");
68 0           $self->assert(!$root->exists('Orders'),
69             "Orders exists after drop_placeholder");
70             }
71              
72             ###############################################################################
73              
74             sub test_key_charset {
75 0     0 0   my $self=shift;
76              
77 0           my $odb=$self->get_odb();
78              
79 0           my $customer=$odb->fetch('/Customers/c1');
80 0           $self->assert(ref($customer),
81             "Can't fetch /Customers/c1");
82              
83 0           $customer->add_placeholder(
84             name => 'Orders',
85             type => 'list',
86             class => 'Data::Order',
87             key => 'order_id',
88             );
89              
90 0           my $orders=$customer->get('Orders');
91 0           my $no=$orders->get_new;
92              
93 0           my $cs=$no->describe('order_id')->{'key_charset'};
94 0           $self->assert($cs eq 'binary',
95             "Got wrong key_charset, method 1, expected 'binary', got '$cs'");
96              
97 0           $cs=$orders->key_charset;
98 0           $self->assert($cs eq 'binary',
99             "Got wrong key_charset, method 2, expected 'binary', got '$cs'");
100              
101 0           $no->add_placeholder(
102             name => 'name',
103             type => 'text',
104             maxlength => 10,
105             );
106              
107 0           my $k1='ABCdef';
108 0           my $k2='abcDEF';
109              
110 0           $no->put(name => 'k1');
111 0           $orders->put($k1 => $no);
112              
113 0           $no->put(name => 'k2');
114 0           $orders->put($k2 => $no);
115              
116 0           my $v1=$orders->get($k1)->get('name');
117 0           my $v2=$orders->get($k2)->get('name');
118              
119 0           $self->assert($v1 eq 'k1',
120             "Expected 'k1', got '$v1', key_charset 'binary'");
121 0           $self->assert($v2 eq 'k2',
122             "Expected 'k2', got '$v2', key_charset 'binary'");
123              
124 0           $customer->drop_placeholder('Orders');
125              
126             ##
127             # Now checking on latin1 key_charset, it should be case insensitive
128             #
129 0           $customer->add_placeholder(
130             name => 'Orders',
131             type => 'list',
132             class => 'Data::Order',
133             key => 'order_id',
134             key_charset => 'latin1',
135             );
136              
137 0           $orders=$customer->get('Orders');
138 0           $no=$orders->get_new;
139              
140 0           $cs=$no->describe('order_id')->{'key_charset'};
141 0           $self->assert($cs eq 'latin1',
142             "Got wrong key_charset, method 1, expected 'latin1', got '$cs'");
143              
144 0           $cs=$orders->key_charset;
145 0           $self->assert($cs eq 'latin1',
146             "Got wrong key_charset, method 2, expected 'latin1', got '$cs'");
147              
148 0           $no->add_placeholder(
149             name => 'name',
150             type => 'text',
151             maxlength => 10,
152             );
153              
154 0           my $k='abcdeFGHIK';
155 0           $no->put(name => 'zzzzzz');
156 0           $orders->put($k => $no);
157              
158 0           for($k,lc($k),uc($k)) {
159 0           $self->assert($orders->exists($_),
160             "Expected '$_' to exist, key_charset 'latin1'");
161             }
162             }
163              
164             ###############################################################################
165              
166             sub test_key_length {
167 0     0 0   my $self=shift;
168              
169 0           my $odb=$self->get_odb();
170              
171 0           my $customer=$odb->fetch('/Customers/c1');
172 0           $self->assert(ref($customer),
173             "Can't fetch /Customers/c1");
174              
175 0           $customer->add_placeholder(
176             name => 'Orders',
177             type => 'list',
178             class => 'Data::Order',
179             key => 'order_id',
180             key_length => 40,
181             );
182              
183 0           my $orders=$customer->get('Orders');
184 0           my $no=$orders->get_new;
185              
186 0           my $kl=$no->describe('order_id')->{'key_length'};
187 0           $self->assert($kl == 40,
188             "Got wrong key length, method 1");
189              
190 0           $kl=$orders->key_length;
191 0           $self->assert($kl == 40,
192             "Got wrong key length, method 2");
193              
194 0           $no->add_placeholder(
195             name => 'name',
196             type => 'text',
197             maxlength => 10,
198             );
199              
200 0           my $k1=('Z' x 35) . '11';
201 0           my $k2=('Z' x 35) . '22';
202              
203 0           $no->put(name => 'k1');
204 0           $orders->put($k1 => $no);
205              
206 0           $no->put(name => 'k2');
207 0           $orders->put($k2 => $no);
208              
209 0           my $v1=$orders->get($k1)->get('name');
210 0           my $v2=$orders->get($k2)->get('name');
211              
212 0           $self->assert($v1 eq 'k1',
213             "Expected 'k1', got '$v1'");
214 0           $self->assert($v2 eq 'k2',
215             "Expected 'k2', got '$v2'");
216             }
217              
218             ###############################################################################
219              
220             sub test_same_field_name {
221 0     0 0   my $self=shift;
222              
223 0           my $odb=$self->get_odb();
224              
225 0           my $customer=$odb->fetch('/Customers/c1');
226 0           $self->assert(ref($customer),
227             "Can't fetch /Customers/c1");
228              
229 0           $customer->add_placeholder(name => 'first_name',
230             type => 'text',
231             maxlength => 20);
232              
233 0           my $thrown=1;
234             try {
235 0     0     $customer->add_placeholder(name => 'first_name',
236             type => 'text',
237             maxlength => 20);
238             } otherwise {
239 0     0     $thrown=1;
240 0           };
241              
242 0           $self->assert($thrown,
243             "Succeeded in adding new placeholder with already used name!");
244              
245 0           $customer->drop_placeholder('first_name');
246             }
247              
248             ###############################################################################
249              
250             sub test_data_placeholder {
251 0     0 0   my $self=shift;
252              
253 0           my $odb=$self->get_odb();
254              
255 0           my $customer=$odb->fetch('/Customers/c1');
256 0           $self->assert(ref($customer),
257             "Can't fetch /Customers/c1");
258              
259 0           $customer->add_placeholder(name => 'first_name',
260             type => 'text',
261             maxlength => 20);
262              
263 0           my $name='John Doe';
264 0           $customer->put(first_name => $name);
265 0           my $got=$customer->get('first_name');
266 0           $self->assert($name eq $got,
267             "Got ($got) not what was stored ($name)");
268              
269 0           $customer->drop_placeholder('first_name');
270             }
271              
272             ###############################################################################
273              
274             sub test_list_placeholder {
275 0     0 0   my $self=shift;
276              
277 0           my $odb=$self->get_odb();
278              
279 0           my $customer=$odb->fetch('/Customers/c1');
280 0           $self->assert(ref($customer),
281             "Can't fetch /Customers/c1");
282              
283 0           $customer->add_placeholder(name => 'Orders',
284             type => 'list',
285             class => 'Data::Order',
286             key => 'order_id');
287              
288 0           my $cust_orders=$customer->get('Orders');
289 0           $self->assert(ref($cust_orders),
290             "Can't get reference to Orders list from /Customers/c1");
291              
292 0           my $o1=$odb->new(objname => 'Data::Order');
293 0           $self->assert(ref($o1),
294             "Can't create an empty order");
295              
296 0           $o1->add_placeholder(name => 'foo', type => 'text', maxlength => 50);
297 0           $o1->put(foo => 'bar');
298              
299 0           $cust_orders->put(o0 => $o1);
300 0           $cust_orders->put(o1 => $o1);
301 0           $cust_orders->put(o2 => $o1);
302 0           my $order=$odb->fetch('/Customers/c1/Orders/o1');
303 0           $self->assert(ref($order),
304             "Can't save order into /Customers/c1");
305 0           my $got=$order->get('foo');
306 0           $self->assert($got eq 'bar',
307             "Got wrong value in the order ($got!='bar')");
308              
309 0           my @k=sort $cust_orders->keys;
310 0           $self->assert($k[2] eq 'o2',
311             "Got wrong key in the key list (".join(',',@k).")");
312              
313 0           $order->put(foo => 'new');
314 0           $got=$odb->fetch('/Customers/c1/Orders/o1/foo');
315 0           $self->assert($got eq 'new',
316             "Got wrong value in the order ($got!='new')");
317              
318             # Checking how automatic naming works
319             #
320 0           my $c2orders=$odb->fetch('/Customers/c2/Orders');
321 0           $self->assert(ref($c2orders),
322             "Can't fetch /Customers/c2/Orders");
323              
324 0           $o1->put(foo => 'under c2');
325 0           my $newname=$c2orders->put($o1);
326 0           $got=$odb->fetch("/Customers/c2/Orders/$newname/foo");
327 0           $self->assert($got eq 'under c2',
328             "Got wrong value in the order ($got!='under c2')");
329              
330             # Adding third level placeholder on Order.
331             #
332 0           $order->add_placeholder(name => 'Products',
333             type => 'list',
334             class => 'Data::Product',
335             key => 'product_id');
336 0           my $products=$order->get('Products');
337 0           $self->assert(ref($products),
338             "Can't get reference to Products list from /Customers/c1/Orders/o1");
339 0           my $product=$products->get_new();
340 0           $product->add_placeholder(name => 'name',
341             type => 'text',
342             maxlength => 50);
343 0           $product->put(name => 'test');
344 0           my $newprod=$products->put($product);
345 0           $product=$products->get($newprod);
346 0           $self->assert(ref($product),
347             "Can't put test product into Products");
348 0           $got=$product->get('name');
349 0           $self->assert($got eq 'test',
350             "Got not what was stored into product ($got!='test')");
351              
352             ##
353             # Deleting
354             #
355 0           $cust_orders->delete('o1');
356 0           my $thrown=0;
357             try {
358 0     0     $cust_orders->get('o1');
359             } otherwise {
360 0     0     $thrown=1;
361 0           };
362 0           $self->assert($thrown,
363             "Can still retrieve deleted Order");
364 0           $c2orders->delete($newname);
365 0           $thrown=0;
366             try {
367 0     0     $c2orders->get($newname);
368             } otherwise {
369 0     0     $thrown=1;
370 0           };
371 0           $self->assert($thrown,
372             "Deleted order c2/$newname is still there");
373              
374             ##
375             # Deleting lists
376             #
377 0           $customer->drop_placeholder('Orders');
378 0           $got=1;
379             try {
380 0     0     $order=$customer->get('Orders');
381             } otherwise {
382 0     0     $got=0;
383 0           };
384 0           $self->assert(!$got,
385             "Still can retrieve Orders after dropping placeholder");
386             }
387              
388             ###############################################################################
389              
390             # Checking that it is impossible to create more then one list for the
391             # same class.
392              
393             sub test_multiple_same_class {
394 0     0 0   my $self=shift;
395              
396 0           my $odb=$self->get_odb();
397              
398 0           my $customer=$odb->fetch('/Customers/c1');
399 0           $self->assert(ref($customer),
400             "Can't fetch /Customers/c1");
401              
402 0           $customer->add_placeholder(name => 'Orders',
403             type => 'list',
404             class => 'Data::Order',
405             key => 'order_id');
406              
407 0           my $root=$odb->fetch('/');
408 0           $self->assert(ref($root),
409             "Can't fetch reference to /");
410              
411 0           my $created=1;
412             try {
413 0     0     $root->add_placeholder(name => 'rootorders',
414             type => 'list',
415             class => 'Data::Order',
416             key => 'root_order_id',
417             connector => 'root_uid');
418             } otherwise {
419 0     0     $created=0;
420 0           };
421 0           $self->assert(! $created,
422             "Succeeded in creating second list of the same class");
423              
424 0           my $got=1;
425             try {
426 0     0     $root->get('rootorders');
427             } otherwise {
428 0     0     $got=0;
429 0           };
430 0           $self->assert(!$got,
431             "Succeeded in creating second list of the same class (After error! Weird..)");
432             }
433              
434             ###############################################################################
435              
436             sub test_build_structure {
437 0     0 0   my $self=shift;
438 0           my $odb=$self->get_odb;
439              
440 0           my $cust=$odb->fetch('/Customers/c1');
441              
442             # Otherwise UNIQUE option would not work
443             #
444 0           $odb->fetch('/Customers')->delete('c2');
445              
446 0           my %structure=(
447             name => {
448             type => 'text',
449             maxlength => 40,
450             },
451             text => {
452             type => 'text',
453             maxlength => 200,
454             index => 1,
455             },
456             blob => {
457             type => 'blob',
458             maxlength => 10000,
459             },
460             integer => {
461             type => 'integer',
462             minvalue => 0,
463             maxvalue => 100
464             },
465             uns => {
466             type => 'integer',
467             minvalue => 0,
468             },
469             uq => {
470             type => 'real',
471             minvalue => 123,
472             maxvalue => 234,
473             unique => 1,
474             },
475             Orders => {
476             type => 'list',
477             class => 'Data::Order',
478             key => 'order_id',
479             structure => {
480             total => {
481             type => 'real',
482             default => 123.34,
483             },
484             foo => {
485             type => 'text',
486             maxlength => 50,
487             },
488             },
489             },
490             );
491              
492 0           my $res=$cust->build_structure(\%structure);
493              
494 0   0       $self->assert($res && ref $res eq 'HASH',
495             "Expected a hash from build_structure (A)");
496              
497 0           $self->assert($res->{'added'} == 8,
498             "Expected build_structure to report 8 additions (A)");
499              
500 0           $self->assert($res->{'changed'} == 0,
501             "Expected build_structure to report no changes (A)");
502              
503 0           $self->assert(!@{$res->{'orphans'}},
  0            
504             "Expected build_structure to report no orphans (A)");
505              
506 0           foreach my $name (qw(name text integer Orders)) {
507 0           $self->assert($cust->exists($name),
508             "Field ($name) doesn't exist after build_structure()");
509             }
510              
511 0           $self->assert($cust->describe('blob')->{'maxlength'} == 10000,
512             "Maxlength is not 10000 on 'blob'");
513              
514             # Reconnecting to the database, getting a new database object with a
515             # new structure loaded from disk.
516             #
517 0           $odb=$self->reconnect();
518 0           $cust=$odb->fetch('/Customers/c1');
519              
520             # Checking how field length and charset changes work
521             #
522 0           $structure{'name'}->{'charset'}='latin1';
523 0           $structure{'name'}->{'_force'}=1;
524              
525 0           $cust->build_structure(\%structure);
526              
527 0           $odb=$self->reconnect();
528 0           $cust=$odb->fetch('/Customers/c1');
529              
530 0           $self->assert($cust->describe('name')->{'charset'} eq 'latin1',
531             "Failed to change charset to 'latin1' on 'name'");
532              
533 0           $structure{'blob'}->{'maxlength'}=20000;
534 0           $structure{'name'}->{'maxlength'}=50;
535 0           $structure{'name'}->{'charset'}='utf8';
536 0           $structure{'text'}->{'charset'}='utf8';
537              
538 0           $res=$cust->build_structure(\%structure);
539              
540 0           $self->assert($res->{'changed'} == 4,
541             "Expected build_structure to report 4 changes (B)");
542              
543 0           $odb=$self->reconnect();
544 0           $cust=$odb->fetch('/Customers/c1');
545              
546 0           $self->assert($cust->describe('blob')->{'maxlength'} == 20000,
547             "Failed to change maxlength to 20000 on 'blob'");
548              
549 0           $self->assert($cust->describe('name')->{'maxlength'} == 50,
550             "Failed to change maxlength to 50 on 'name'");
551              
552 0           $self->assert($cust->describe('name')->{'charset'} eq 'utf8',
553             "Failed to change charset to 'utf8' on 'name'");
554              
555 0           $self->assert($cust->describe('text')->{'charset'} eq 'utf8',
556             "Failed to change charset to 'utf8' on 'text'");
557              
558             # A new field
559             #
560             $structure{newf}={
561 0           type => 'real',
562             minvalue => 123,
563             maxvalue => 234,
564             index => 1,
565             };
566              
567 0           $res=$cust->build_structure(\%structure);
568              
569 0           $self->assert($res->{'added'} == 1,
570             "Expected build_structure to report 1 added (C)");
571              
572 0           foreach my $name (qw(newf name text integer uns Orders)) {
573 0           $self->assert($cust->exists($name),
574             "Field ($name) doesn't exist after build_structure()");
575 0 0         if($name eq 'uns') {
576 0           my $min=$cust->describe($name)->{minvalue};
577             $self->assert($min == $structure{uns}->{minvalue},
578 0           "Minvalue is wrong for 'uns' ($min)");
579 0           my $max=$cust->describe($name)->{maxvalue};
580 0           $self->assert($max == 0xFFFFFFFF,
581             "Maxvalue is wrong for 'uns' ($max)");
582             }
583              
584 0 0         next unless $name eq 'newf';
585             $self->assert($cust->describe($name)->{index},
586 0           "No indication of index in the created field ($name)");
587             }
588              
589             # Removing some fields from the structure prototype and checking
590             # that build structure returns the difference between on-disk and
591             # given.
592             #
593 0           delete $structure{'blob'};
594 0           delete $structure{'uq'};
595 0           delete $structure{'Orders'}->{'structure'}->{'foo'};
596              
597 0           $odb=$self->reconnect();
598              
599 0           $res=$cust->build_structure(\%structure);
600              
601 0   0       $self->assert($res && ref $res eq 'HASH',
602             "Expected a hash from build_structure (D)");
603              
604 0           $self->assert($res->{'added'} == 0,
605             "Expected build_structure to report no additions (D)");
606              
607 0           $self->assert($res->{'changed'} == 0,
608             "Expected build_structure to report no changes (D)");
609              
610 0           $self->assert(@{$res->{'orphans'}} == 3,
  0            
611             "Expected build_structure to report 3 orphans (D)");
612              
613             # Actually dropping orphans and checking results
614             #
615 0           $cust->sync_structure(\%structure);
616              
617 0           $self->assert(! $cust->describe('blob'),
618             "Expected 'blob' to be gone");
619              
620 0           $self->assert(! $cust->describe('uq'),
621             "Expected 'uq' to be gone");
622              
623 0           $self->assert(! $cust->get('Orders')->get_new()->describe('foo'),
624             "Expected 'Orders/foo' to be gone");
625              
626             # Whole table
627             #
628 0           delete $structure{'Orders'};
629              
630 0           $cust->sync_structure(\%structure);
631              
632 0           $self->assert(! $cust->describe('Orders'),
633             "Expected 'Orders' to be gone");
634             }
635              
636             ###############################################################################
637              
638             1;