Subversion Repositories SmartDukaan

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
16591 anikendra 1
<?php
2
/**
3
 * Test for Schema database management
4
 *
5
 * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
6
 * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
7
 *
8
 * Licensed under The MIT License
9
 * For full copyright and license information, please see the LICENSE.txt
10
 * Redistributions of files must retain the above copyright notice
11
 *
12
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
13
 * @link          http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
14
 * @package       Cake.Test.Case.Model
15
 * @since         CakePHP(tm) v 1.2.0.5550
16
 * @license       http://www.opensource.org/licenses/mit-license.php MIT License
17
 */
18
 
19
App::uses('CakeSchema', 'Model');
20
App::uses('CakeTestFixture', 'TestSuite/Fixture');
21
 
22
/**
23
 * Test for Schema database management
24
 *
25
 * @package       Cake.Test.Case.Model
26
 */
27
class MyAppSchema extends CakeSchema {
28
 
29
/**
30
 * connection property
31
 *
32
 * @var string
33
 */
34
	public $connection = 'test';
35
 
36
/**
37
 * comments property
38
 *
39
 * @var array
40
 */
41
	public $comments = array(
42
		'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
43
		'post_id' => array('type' => 'integer', 'null' => false, 'default' => 0),
44
		'user_id' => array('type' => 'integer', 'null' => false),
45
		'title' => array('type' => 'string', 'null' => false, 'length' => 100),
46
		'comment' => array('type' => 'text', 'null' => false, 'default' => null),
47
		'published' => array('type' => 'string', 'null' => true, 'default' => 'N', 'length' => 1),
48
		'created' => array('type' => 'datetime', 'null' => true, 'default' => null),
49
		'updated' => array('type' => 'datetime', 'null' => true, 'default' => null),
50
		'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => true)),
51
	);
52
 
53
/**
54
 * posts property
55
 *
56
 * @var array
57
 */
58
	public $posts = array(
59
		'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
60
		'author_id' => array('type' => 'integer', 'null' => true, 'default' => ''),
61
		'title' => array('type' => 'string', 'null' => false, 'default' => 'Title'),
62
		'body' => array('type' => 'text', 'null' => true, 'default' => null),
63
		'summary' => array('type' => 'text', 'null' => true),
64
		'published' => array('type' => 'string', 'null' => true, 'default' => 'Y', 'length' => 1),
65
		'created' => array('type' => 'datetime', 'null' => true, 'default' => null),
66
		'updated' => array('type' => 'datetime', 'null' => true, 'default' => null),
67
		'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => true)),
68
	);
69
 
70
/**
71
 * _foo property
72
 *
73
 * @var array
74
 */
75
	protected $_foo = array('bar');
76
 
77
/**
78
 * getVar method
79
 *
80
 * @param string $var Name of var
81
 * @return mixed
82
 */
83
	public function getVar($var) {
84
		if (!isset($this->$var)) {
85
			return null;
86
		}
87
		return $this->$var;
88
	}
89
 
90
}
91
 
92
/**
93
 * TestAppSchema class
94
 *
95
 * @package       Cake.Test.Case.Model
96
 */
97
class TestAppSchema extends CakeSchema {
98
 
99
/**
100
 * name property
101
 *
102
 * @var string
103
 */
104
	public $name = 'MyApp';
105
 
106
/**
107
 * comments property
108
 *
109
 * @var array
110
 */
111
	public $comments = array(
112
		'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
113
		'article_id' => array('type' => 'integer', 'null' => false),
114
		'user_id' => array('type' => 'integer', 'null' => false),
115
		'comment' => array('type' => 'text', 'null' => true, 'default' => null),
116
		'published' => array('type' => 'string', 'null' => true, 'default' => 'N', 'length' => 1),
117
		'created' => array('type' => 'datetime', 'null' => true, 'default' => null),
118
		'updated' => array('type' => 'datetime', 'null' => true, 'default' => null),
119
		'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => true)),
120
		'tableParameters' => array(),
121
	);
122
 
123
/**
124
 * posts property
125
 *
126
 * @var array
127
 */
128
	public $posts = array(
129
		'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
130
		'author_id' => array('type' => 'integer', 'null' => false),
131
		'title' => array('type' => 'string', 'null' => false),
132
		'body' => array('type' => 'text', 'null' => true, 'default' => null),
133
		'published' => array('type' => 'string', 'null' => true, 'default' => 'N', 'length' => 1),
134
		'created' => array('type' => 'datetime', 'null' => true, 'default' => null),
135
		'updated' => array('type' => 'datetime', 'null' => true, 'default' => null),
136
		'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => true)),
137
		'tableParameters' => array(),
138
	);
139
 
140
/**
141
 * posts_tags property
142
 *
143
 * @var array
144
 */
145
	public $posts_tags = array(
146
		'post_id' => array('type' => 'integer', 'null' => false, 'key' => 'primary'),
147
		'tag_id' => array('type' => 'string', 'null' => false, 'key' => 'primary'),
148
		'indexes' => array('posts_tag' => array('column' => array('tag_id', 'post_id'), 'unique' => 1)),
149
		'tableParameters' => array()
150
	);
151
 
152
/**
153
 * tags property
154
 *
155
 * @var array
156
 */
157
	public $tags = array(
158
		'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
159
		'tag' => array('type' => 'string', 'null' => false),
160
		'created' => array('type' => 'datetime', 'null' => true, 'default' => null),
161
		'updated' => array('type' => 'datetime', 'null' => true, 'default' => null),
162
		'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => true)),
163
		'tableParameters' => array()
164
	);
165
 
166
/**
167
 * datatypes property
168
 *
169
 * @var array
170
 */
171
	public $datatypes = array(
172
		'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
173
		'float_field' => array('type' => 'float', 'null' => false, 'length' => '5,2', 'default' => ''),
174
		'decimal_field' => array('type' => 'decimal', 'length' => '6,3', 'default' => '0.000'),
175
		'huge_int' => array('type' => 'biginteger'),
176
		'bool' => array('type' => 'boolean', 'null' => false, 'default' => false),
177
		'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => true)),
178
		'tableParameters' => array()
179
	);
180
 
181
/**
182
 * setup method
183
 *
184
 * @param mixed $version
185
 * @return void
186
 */
187
	public function setup($version) {
188
	}
189
 
190
/**
191
 * teardown method
192
 *
193
 * @param mixed $version
194
 * @return void
195
 */
196
	public function teardown($version) {
197
	}
198
 
199
}
200
 
201
/**
202
 * SchemaPost class
203
 *
204
 * @package       Cake.Test.Case.Model
205
 */
206
class SchemaPost extends CakeTestModel {
207
 
208
/**
209
 * useTable property
210
 *
211
 * @var string
212
 */
213
	public $useTable = 'posts';
214
 
215
/**
216
 * hasMany property
217
 *
218
 * @var array
219
 */
220
	public $hasMany = array('SchemaComment');
221
 
222
/**
223
 * hasAndBelongsToMany property
224
 *
225
 * @var array
226
 */
227
	public $hasAndBelongsToMany = array('SchemaTag');
228
}
229
 
230
/**
231
 * SchemaComment class
232
 *
233
 * @package       Cake.Test.Case.Model
234
 */
235
class SchemaComment extends CakeTestModel {
236
 
237
/**
238
 * useTable property
239
 *
240
 * @var string
241
 */
242
	public $useTable = 'comments';
243
 
244
/**
245
 * belongsTo property
246
 *
247
 * @var array
248
 */
249
	public $belongsTo = array('SchemaPost');
250
}
251
 
252
/**
253
 * SchemaTag class
254
 *
255
 * @package       Cake.Test.Case.Model
256
 */
257
class SchemaTag extends CakeTestModel {
258
 
259
/**
260
 * useTable property
261
 *
262
 * @var string
263
 */
264
	public $useTable = 'tags';
265
 
266
/**
267
 * hasAndBelongsToMany property
268
 *
269
 * @var array
270
 */
271
	public $hasAndBelongsToMany = array('SchemaPost');
272
}
273
 
274
/**
275
 * SchemaDatatype class
276
 *
277
 * @package       Cake.Test.Case.Model
278
 */
279
class SchemaDatatype extends CakeTestModel {
280
 
281
/**
282
 * useTable property
283
 *
284
 * @var string
285
 */
286
	public $useTable = 'datatypes';
287
}
288
 
289
/**
290
 * Testdescribe class
291
 *
292
 * This class is defined purely to inherit the cacheSources variable otherwise
293
 * testSchemaCreateTable will fail if listSources has already been called and
294
 * its source cache populated - I.e. if the test is run within a group
295
 *
296
 * @uses          CakeTestModel
297
 * @package       Cake.Test.Case.Model
298
 */
299
class Testdescribe extends CakeTestModel {
300
}
301
 
302
/**
303
 * SchemaCrossDatabase class
304
 *
305
 * @package       Cake.Test.Case.Model
306
 */
307
class SchemaCrossDatabase extends CakeTestModel {
308
 
309
/**
310
 * useTable property
311
 *
312
 * @var string
313
 */
314
	public $useTable = 'cross_database';
315
 
316
/**
317
 * useDbConfig property
318
 *
319
 * @var string
320
 */
321
	public $useDbConfig = 'test2';
322
}
323
 
324
/**
325
 * SchemaCrossDatabaseFixture class
326
 *
327
 * @package       Cake.Test.Case.Model
328
 */
329
class SchemaCrossDatabaseFixture extends CakeTestFixture {
330
 
331
/**
332
 * name property
333
 *
334
 * @var string
335
 */
336
	public $name = 'CrossDatabase';
337
 
338
/**
339
 * table property
340
 *
341
 * @var string
342
 */
343
	public $table = 'cross_database';
344
 
345
/**
346
 * fields property
347
 *
348
 * @var array
349
 */
350
	public $fields = array(
351
		'id' => array('type' => 'integer', 'key' => 'primary'),
352
		'name' => 'string'
353
	);
354
 
355
/**
356
 * records property
357
 *
358
 * @var array
359
 */
360
	public $records = array(
361
		array('id' => 1, 'name' => 'First'),
362
		array('id' => 2, 'name' => 'Second'),
363
	);
364
}
365
 
366
/**
367
 * SchemaPrefixAuthUser class
368
 *
369
 * @package       Cake.Test.Case.Model
370
 */
371
class SchemaPrefixAuthUser extends CakeTestModel {
372
 
373
/**
374
 * table prefix
375
 *
376
 * @var string
377
 */
378
	public $tablePrefix = 'auth_';
379
 
380
/**
381
 * useTable
382
 *
383
 * @var string
384
 */
385
	public $useTable = 'users';
386
}
387
 
388
/**
389
 * CakeSchemaTest
390
 *
391
 * @package       Cake.Test.Case.Model
392
 */
393
class CakeSchemaTest extends CakeTestCase {
394
 
395
/**
396
 * fixtures property
397
 *
398
 * @var array
399
 */
400
	public $fixtures = array(
401
		'core.post', 'core.tag', 'core.posts_tag', 'core.test_plugin_comment',
402
		'core.datatype', 'core.auth_user', 'core.author',
403
		'core.test_plugin_article', 'core.user', 'core.comment',
404
		'core.prefix_test'
405
	);
406
 
407
/**
408
 * setUp method
409
 *
410
 * @return void
411
 */
412
	public function setUp() {
413
		parent::setUp();
414
		ConnectionManager::getDataSource('test')->cacheSources = false;
415
		$this->Schema = new TestAppSchema();
416
	}
417
 
418
/**
419
 * tearDown method
420
 *
421
 * @return void
422
 */
423
	public function tearDown() {
424
		parent::tearDown();
425
		if (file_exists(TMP . 'tests' . DS . 'schema.php')) {
426
			unlink(TMP . 'tests' . DS . 'schema.php');
427
		}
428
		unset($this->Schema);
429
		CakePlugin::unload();
430
	}
431
 
432
/**
433
 * testSchemaName method
434
 *
435
 * @return void
436
 */
437
	public function testSchemaName() {
438
		$Schema = new CakeSchema();
439
		$this->assertEquals('App', $Schema->name);
440
	}
441
 
442
/**
443
 * testSchemaRead method
444
 *
445
 * @return void
446
 */
447
	public function testSchemaRead() {
448
		$read = $this->Schema->read(array(
449
			'connection' => 'test',
450
			'name' => 'TestApp',
451
			'models' => array('SchemaPost', 'SchemaComment', 'SchemaTag', 'SchemaDatatype')
452
		));
453
		unset($read['tables']['missing']);
454
 
455
		$expected = array('comments', 'datatypes', 'posts', 'posts_tags', 'tags');
456
		foreach ($expected as $table) {
457
			$this->assertTrue(isset($read['tables'][$table]), 'Missing table ' . $table);
458
		}
459
		foreach ($this->Schema->tables as $table => $fields) {
460
			$this->assertEquals(array_keys($fields), array_keys($read['tables'][$table]));
461
		}
462
 
463
		if (isset($read['tables']['datatypes']['float_field']['length'])) {
464
			$this->assertEquals(
465
				$read['tables']['datatypes']['float_field']['length'],
466
				$this->Schema->tables['datatypes']['float_field']['length']
467
			);
468
		}
469
 
470
		$this->assertEquals(
471
			$read['tables']['datatypes']['float_field']['type'],
472
			$this->Schema->tables['datatypes']['float_field']['type']
473
		);
474
 
475
		$this->assertEquals(
476
			$read['tables']['datatypes']['float_field']['null'],
477
			$this->Schema->tables['datatypes']['float_field']['null']
478
		);
479
 
480
		$db = ConnectionManager::getDataSource('test');
481
		$config = $db->config;
482
		$config['prefix'] = 'schema_test_prefix_';
483
		ConnectionManager::create('schema_prefix', $config);
484
		$read = $this->Schema->read(array('connection' => 'schema_prefix', 'models' => false));
485
		$this->assertTrue(empty($read['tables']));
486
 
487
		$read = $this->Schema->read(array(
488
			'connection' => 'test',
489
			'name' => 'TestApp',
490
			'models' => array('SchemaComment', 'SchemaTag', 'SchemaPost')
491
		));
492
		$this->assertFalse(isset($read['tables']['missing']['posts_tags']), 'Join table marked as missing');
493
	}
494
 
495
/**
496
 * testSchemaReadWithAppModel method
497
 *
498
 * @return void
499
 */
500
	public function testSchemaReadWithAppModel() {
501
		$connections = ConnectionManager::enumConnectionObjects();
502
		ConnectionManager::drop('default');
503
		ConnectionManager::create('default', $connections['test']);
504
		try {
505
			$this->Schema->read(array(
506
				'connection' => 'default',
507
				'name' => 'TestApp',
508
				'models' => array('AppModel')
509
			));
510
		} catch(MissingTableException $mte) {
511
			ConnectionManager::drop('default');
512
			$this->fail($mte->getMessage());
513
		}
514
		ConnectionManager::drop('default');
515
	}
516
 
517
/**
518
 * testSchemaReadWithOddTablePrefix method
519
 *
520
 * @return void
521
 */
522
	public function testSchemaReadWithOddTablePrefix() {
523
		$config = ConnectionManager::getDataSource('test')->config;
524
		$this->skipIf(!empty($config['prefix']), 'This test can not be executed with datasource prefix set.');
525
 
526
		$SchemaPost = ClassRegistry::init('SchemaPost');
527
		$SchemaPost->tablePrefix = 'po';
528
		$SchemaPost->useTable = 'sts';
529
		$read = $this->Schema->read(array(
530
			'connection' => 'test',
531
			'name' => 'TestApp',
532
			'models' => array('SchemaPost')
533
		));
534
 
535
		$this->assertFalse(isset($read['tables']['missing']['posts']), 'Posts table was not read from tablePrefix');
536
	}
537
 
538
/**
539
 * test read() with tablePrefix properties.
540
 *
541
 * @return void
542
 */
543
	public function testSchemaReadWithTablePrefix() {
544
		$config = ConnectionManager::getDataSource('test')->config;
545
		$this->skipIf(!empty($config['prefix']), 'This test can not be executed with datasource prefix set.');
546
 
547
		$Schema = new CakeSchema();
548
		$read = $Schema->read(array(
549
			'connection' => 'test',
550
			'name' => 'TestApp',
551
			'models' => array('SchemaPrefixAuthUser')
552
		));
553
		unset($read['tables']['missing']);
554
		$this->assertTrue(isset($read['tables']['auth_users']), 'auth_users key missing %s');
555
	}
556
 
557
/**
558
 * test reading schema with config prefix.
559
 *
560
 * @return void
561
 */
562
	public function testSchemaReadWithConfigPrefix() {
563
		$this->skipIf($this->db instanceof Sqlite, 'Cannot open 2 connections to Sqlite');
564
 
565
		$db = ConnectionManager::getDataSource('test');
566
		$config = $db->config;
567
		$this->skipIf(!empty($config['prefix']), 'This test can not be executed with datasource prefix set.');
568
 
569
		$config['prefix'] = 'schema_test_prefix_';
570
		ConnectionManager::create('schema_prefix', $config);
571
		$read = $this->Schema->read(array('connection' => 'schema_prefix', 'models' => false));
572
		$this->assertTrue(empty($read['tables']));
573
 
574
		$config['prefix'] = 'prefix_';
575
		ConnectionManager::create('schema_prefix2', $config);
576
		$read = $this->Schema->read(array(
577
			'connection' => 'schema_prefix2',
578
			'name' => 'TestApp',
579
			'models' => false));
580
		$this->assertTrue(isset($read['tables']['prefix_tests']));
581
	}
582
 
583
/**
584
 * test reading schema from plugins.
585
 *
586
 * @return void
587
 */
588
	public function testSchemaReadWithPlugins() {
589
		App::objects('model', null, false);
590
		App::build(array(
591
			'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
592
		));
593
		CakePlugin::load('TestPlugin');
594
 
595
		$Schema = new CakeSchema();
596
		$Schema->plugin = 'TestPlugin';
597
		$read = $Schema->read(array(
598
			'connection' => 'test',
599
			'name' => 'TestApp',
600
			'models' => true
601
		));
602
		unset($read['tables']['missing']);
603
		$this->assertTrue(isset($read['tables']['auth_users']));
604
		$this->assertTrue(isset($read['tables']['authors']));
605
		$this->assertTrue(isset($read['tables']['test_plugin_comments']));
606
		$this->assertTrue(isset($read['tables']['posts']));
607
		$this->assertTrue(count($read['tables']) >= 4);
608
 
609
		App::build();
610
	}
611
 
612
/**
613
 * test reading schema with tables from another database.
614
 *
615
 * @return void
616
 */
617
	public function testSchemaReadWithCrossDatabase() {
618
		$config = ConnectionManager::enumConnectionObjects();
619
		$this->skipIf(
620
			!isset($config['test']) || !isset($config['test2']),
621
			'Primary and secondary test databases not configured, ' .
622
			'skipping cross-database join tests. ' .
623
			'To run these tests, you must define $test and $test2 in your database configuration.'
624
		);
625
 
626
		$db = ConnectionManager::getDataSource('test2');
627
		$fixture = new SchemaCrossDatabaseFixture();
628
		$fixture->create($db);
629
		$fixture->insert($db);
630
 
631
		$read = $this->Schema->read(array(
632
			'connection' => 'test',
633
			'name' => 'TestApp',
634
			'models' => array('SchemaCrossDatabase', 'SchemaPost')
635
		));
636
		$this->assertTrue(isset($read['tables']['posts']));
637
		$this->assertFalse(isset($read['tables']['cross_database']), 'Cross database should not appear');
638
		$this->assertFalse(isset($read['tables']['missing']['cross_database']), 'Cross database should not appear');
639
 
640
		$read = $this->Schema->read(array(
641
			'connection' => 'test2',
642
			'name' => 'TestApp',
643
			'models' => array('SchemaCrossDatabase', 'SchemaPost')
644
		));
645
		$this->assertFalse(isset($read['tables']['posts']), 'Posts should not appear');
646
		$this->assertFalse(isset($read['tables']['posts']), 'Posts should not appear');
647
		$this->assertTrue(isset($read['tables']['cross_database']));
648
 
649
		$fixture->drop($db);
650
	}
651
 
652
/**
653
 * test that tables are generated correctly
654
 *
655
 * @return void
656
 */
657
	public function testGenerateTable() {
658
		$posts = array(
659
			'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
660
			'author_id' => array('type' => 'integer', 'null' => false),
661
			'title' => array('type' => 'string', 'null' => false),
662
			'body' => array('type' => 'text', 'null' => true, 'default' => null),
663
			'published' => array('type' => 'string', 'null' => true, 'default' => 'N', 'length' => 1),
664
			'created' => array('type' => 'datetime', 'null' => true, 'default' => null),
665
			'updated' => array('type' => 'datetime', 'null' => true, 'default' => null),
666
			'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => true)),
667
		);
668
		$result = $this->Schema->generateTable('posts', $posts);
669
		$this->assertRegExp('/public \$posts/', $result);
670
 
671
		$posts = array(
672
			'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
673
			'author_id' => array('type' => 'integer', 'null' => false),
674
			'title' => array('type' => 'string', 'null' => false),
675
			'body' => array('type' => 'text', 'null' => true, 'default' => null),
676
			'published' => array('type' => 'string', 'null' => true, 'default' => 'N', 'length' => 1),
677
			'created' => array('type' => 'datetime', 'null' => true, 'default' => null),
678
			'updated' => array('type' => 'datetime', 'null' => true, 'default' => null),
679
			'indexes' => array(
680
				'PRIMARY' => array('column' => 'id', 'unique' => true),
681
				'MyFtIndex' => array('column' => array('title', 'body'), 'type' => 'fulltext')
682
			)
683
		);
684
		$result = $this->Schema->generateTable('fields', $posts);
685
		$this->assertRegExp('/public \$fields/', $result);
686
		$this->assertRegExp('/\'type\' \=\> \'fulltext\'/', $result);
687
	}
688
 
689
/**
690
 * testSchemaWrite method
691
 *
692
 * @return void
693
 */
694
	public function testSchemaWrite() {
695
		$write = $this->Schema->write(array(
696
			'name' => 'MyOtherApp',
697
			'tables' => $this->Schema->tables,
698
			'path' => TMP . 'tests'
699
		));
700
		$file = file_get_contents(TMP . 'tests' . DS . 'schema.php');
701
		$this->assertEquals($write, $file);
702
 
703
		require_once TMP . 'tests' . DS . 'schema.php';
704
		$OtherSchema = new MyOtherAppSchema();
705
		$this->assertEquals($this->Schema->tables, $OtherSchema->tables);
706
	}
707
 
708
/**
709
 * testSchemaComparison method
710
 *
711
 * @return void
712
 */
713
	public function testSchemaComparison() {
714
		$New = new MyAppSchema();
715
		$compare = $New->compare($this->Schema);
716
		$expected = array(
717
			'comments' => array(
718
				'add' => array(
719
					'post_id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'after' => 'id'),
720
					'title' => array('type' => 'string', 'null' => false, 'length' => 100, 'after' => 'user_id'),
721
				),
722
				'drop' => array(
723
					'article_id' => array('type' => 'integer', 'null' => false),
724
					'tableParameters' => array(),
725
				),
726
				'change' => array(
727
					'comment' => array('type' => 'text', 'null' => false, 'default' => null),
728
				)
729
			),
730
			'posts' => array(
731
				'add' => array(
732
					'summary' => array('type' => 'text', 'null' => true, 'after' => 'body'),
733
				),
734
				'drop' => array(
735
					'tableParameters' => array(),
736
				),
737
				'change' => array(
738
					'author_id' => array('type' => 'integer', 'null' => true, 'default' => ''),
739
					'title' => array('type' => 'string', 'null' => false, 'default' => 'Title'),
740
					'published' => array('type' => 'string', 'null' => true, 'default' => 'Y', 'length' => 1)
741
				)
742
			),
743
		);
744
		$this->assertEquals($expected, $compare);
745
		$this->assertNull($New->getVar('comments'));
746
		$this->assertEquals(array('bar'), $New->getVar('_foo'));
747
 
748
		$tables = array(
749
			'missing' => array(
750
				'categories' => array(
751
					'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'key' => 'primary'),
752
					'created' => array('type' => 'datetime', 'null' => false, 'default' => null),
753
					'modified' => array('type' => 'datetime', 'null' => false, 'default' => null),
754
					'name' => array('type' => 'string', 'null' => false, 'default' => null, 'length' => 100),
755
					'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1)),
756
					'tableParameters' => array('charset' => 'latin1', 'collate' => 'latin1_swedish_ci', 'engine' => 'MyISAM')
757
				)
758
			),
759
			'ratings' => array(
760
				'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'key' => 'primary'),
761
				'foreign_key' => array('type' => 'integer', 'null' => false, 'default' => null),
762
				'model' => array('type' => 'varchar', 'null' => false, 'default' => null),
763
				'value' => array('type' => 'float', 'null' => false, 'length' => '5,2', 'default' => null),
764
				'created' => array('type' => 'datetime', 'null' => false, 'default' => null),
765
				'modified' => array('type' => 'datetime', 'null' => false, 'default' => null),
766
				'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1)),
767
				'tableParameters' => array('charset' => 'latin1', 'collate' => 'latin1_swedish_ci', 'engine' => 'MyISAM')
768
			)
769
		);
770
		$compare = $New->compare($this->Schema, $tables);
771
		$expected = array(
772
			'ratings' => array(
773
				'create' => array(
774
					'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'key' => 'primary'),
775
					'foreign_key' => array('type' => 'integer', 'null' => false, 'default' => null),
776
					'model' => array('type' => 'varchar', 'null' => false, 'default' => null),
777
					'value' => array('type' => 'float', 'null' => false, 'length' => '5,2', 'default' => null),
778
					'created' => array('type' => 'datetime', 'null' => false, 'default' => null),
779
					'modified' => array('type' => 'datetime', 'null' => false, 'default' => null),
780
					'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1)),
781
					'tableParameters' => array('charset' => 'latin1', 'collate' => 'latin1_swedish_ci', 'engine' => 'MyISAM')
782
				)
783
			)
784
		);
785
		$this->assertEquals($expected, $compare);
786
	}
787
 
788
/**
789
 * test comparing '' and null and making sure they are different.
790
 *
791
 * @return void
792
 */
793
	public function testCompareEmptyStringAndNull() {
794
		$One = new CakeSchema(array(
795
			'posts' => array(
796
				'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'key' => 'primary'),
797
				'name' => array('type' => 'string', 'null' => false, 'default' => '')
798
			)
799
		));
800
		$Two = new CakeSchema(array(
801
			'posts' => array(
802
				'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'key' => 'primary'),
803
				'name' => array('type' => 'string', 'null' => false, 'default' => null)
804
			)
805
		));
806
		$compare = $One->compare($Two);
807
		$expected = array(
808
			'posts' => array(
809
				'change' => array(
810
					'name' => array('type' => 'string', 'null' => false, 'default' => null)
811
				)
812
			)
813
		);
814
		$this->assertEquals($expected, $compare);
815
	}
816
 
817
/**
818
 * Test comparing tableParameters and indexes.
819
 *
820
 * @return void
821
 */
822
	public function testTableParametersAndIndexComparison() {
823
		$old = array(
824
			'posts' => array(
825
				'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
826
				'author_id' => array('type' => 'integer', 'null' => false),
827
				'title' => array('type' => 'string', 'null' => false),
828
				'indexes' => array(
829
					'PRIMARY' => array('column' => 'id', 'unique' => true)
830
				),
831
				'tableParameters' => array(
832
					'charset' => 'latin1',
833
					'collate' => 'latin1_general_ci'
834
				)
835
			),
836
			'comments' => array(
837
				'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
838
				'post_id' => array('type' => 'integer', 'null' => false, 'default' => 0),
839
				'comment' => array('type' => 'text'),
840
				'indexes' => array(
841
					'PRIMARY' => array('column' => 'id', 'unique' => true),
842
					'post_id' => array('column' => 'post_id'),
843
				),
844
				'tableParameters' => array(
845
					'engine' => 'InnoDB',
846
					'charset' => 'latin1',
847
					'collate' => 'latin1_general_ci'
848
				)
849
			)
850
		);
851
		$new = array(
852
			'posts' => array(
853
				'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
854
				'author_id' => array('type' => 'integer', 'null' => false),
855
				'title' => array('type' => 'string', 'null' => false),
856
				'indexes' => array(
857
					'PRIMARY' => array('column' => 'id', 'unique' => true),
858
					'author_id' => array('column' => 'author_id'),
859
				),
860
				'tableParameters' => array(
861
					'charset' => 'utf8',
862
					'collate' => 'utf8_general_ci',
863
					'engine' => 'MyISAM'
864
				)
865
			),
866
			'comments' => array(
867
				'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
868
				'post_id' => array('type' => 'integer', 'null' => false, 'default' => 0),
869
				'comment' => array('type' => 'text'),
870
				'indexes' => array(
871
					'PRIMARY' => array('column' => 'id', 'unique' => true),
872
				),
873
				'tableParameters' => array(
874
					'charset' => 'utf8',
875
					'collate' => 'utf8_general_ci'
876
				)
877
			)
878
		);
879
		$compare = $this->Schema->compare($old, $new);
880
		$expected = array(
881
			'posts' => array(
882
				'add' => array(
883
					'indexes' => array('author_id' => array('column' => 'author_id')),
884
				),
885
				'change' => array(
886
					'tableParameters' => array(
887
						'charset' => 'utf8',
888
						'collate' => 'utf8_general_ci',
889
						'engine' => 'MyISAM'
890
					)
891
				)
892
			),
893
			'comments' => array(
894
				'drop' => array(
895
					'indexes' => array('post_id' => array('column' => 'post_id')),
896
				),
897
				'change' => array(
898
					'tableParameters' => array(
899
						'charset' => 'utf8',
900
						'collate' => 'utf8_general_ci',
901
					)
902
				)
903
			)
904
		);
905
		$this->assertEquals($expected, $compare);
906
	}
907
 
908
/**
909
 * Test comparing with field changed from VARCHAR to DATETIME
910
 *
911
 * @return void
912
 */
913
	public function testCompareVarcharToDatetime() {
914
		$old = array(
915
			'posts' => array(
916
				'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
917
				'author_id' => array('type' => 'integer', 'null' => false),
918
				'title' => array('type' => 'string', 'null' => true, 'length' => 45),
919
				'indexes' => array(
920
					'PRIMARY' => array('column' => 'id', 'unique' => true)
921
				),
922
				'tableParameters' => array(
923
					'charset' => 'latin1',
924
					'collate' => 'latin1_general_ci'
925
				)
926
			),
927
		);
928
		$new = array(
929
			'posts' => array(
930
				'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
931
				'author_id' => array('type' => 'integer', 'null' => false),
932
				'title' => array('type' => 'datetime', 'null' => false),
933
				'indexes' => array(
934
					'PRIMARY' => array('column' => 'id', 'unique' => true)
935
				),
936
				'tableParameters' => array(
937
					'charset' => 'latin1',
938
					'collate' => 'latin1_general_ci'
939
				)
940
			),
941
		);
942
		$compare = $this->Schema->compare($old, $new);
943
		$expected = array(
944
			'posts' => array(
945
				'change' => array(
946
					'title' => array(
947
						'type' => 'datetime',
948
						'null' => false,
949
					)
950
				)
951
			),
952
		);
953
		$this->assertEquals($expected, $compare, 'Invalid SQL, datetime does not have length');
954
	}
955
 
956
/**
957
 * testSchemaLoading method
958
 *
959
 * @return void
960
 */
961
	public function testSchemaLoading() {
962
		$Other = $this->Schema->load(array('name' => 'MyOtherApp', 'path' => TMP . 'tests'));
963
		$this->assertEquals('MyOtherApp', $Other->name);
964
		$this->assertEquals($Other->tables, $this->Schema->tables);
965
	}
966
 
967
/**
968
 * test loading schema files inside of plugins.
969
 *
970
 * @return void
971
 */
972
	public function testSchemaLoadingFromPlugin() {
973
		App::build(array(
974
			'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
975
		));
976
		CakePlugin::load('TestPlugin');
977
		$Other = $this->Schema->load(array('name' => 'TestPluginApp', 'plugin' => 'TestPlugin'));
978
		$this->assertEquals('TestPluginApp', $Other->name);
979
		$this->assertEquals(array('test_plugin_acos'), array_keys($Other->tables));
980
 
981
		App::build();
982
	}
983
 
984
/**
985
 * testSchemaCreateTable method
986
 *
987
 * @return void
988
 */
989
	public function testSchemaCreateTable() {
990
		$db = ConnectionManager::getDataSource('test');
991
		$db->cacheSources = false;
992
 
993
		$Schema = new CakeSchema(array(
994
			'connection' => 'test',
995
			'testdescribes' => array(
996
				'id' => array('type' => 'integer', 'key' => 'primary'),
997
				'int_null' => array('type' => 'integer', 'null' => true),
998
				'int_not_null' => array('type' => 'integer', 'null' => false),
999
			),
1000
		));
1001
		$sql = $db->createSchema($Schema);
1002
 
1003
		$col = $Schema->tables['testdescribes']['int_null'];
1004
		$col['name'] = 'int_null';
1005
		$column = $this->db->buildColumn($col);
1006
		$this->assertRegExp('/' . preg_quote($column, '/') . '/', $sql);
1007
 
1008
		$col = $Schema->tables['testdescribes']['int_not_null'];
1009
		$col['name'] = 'int_not_null';
1010
		$column = $this->db->buildColumn($col);
1011
		$this->assertRegExp('/' . preg_quote($column, '/') . '/', $sql);
1012
	}
1013
}