Completed
Push — 3.4 ( 17c658...420cba )
by Daniel
10:26
created

DataListTest::testToNestedArray()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 31
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 26
nc 1
nop 0
dl 0
loc 31
rs 8.8571
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * @package framework
5
 * @subpackage tests
6
 */
7
class DataListTest extends SapphireTest {
8
9
	// Borrow the model from DataObjectTest
10
	protected static $fixture_file = 'DataObjectTest.yml';
11
12
	protected $extraDataObjects = array(
13
		'DataObjectTest_Team',
14
		'DataObjectTest_Fixture',
15
		'DataObjectTest_SubTeam',
16
		'OtherSubclassWithSameField',
17
		'DataObjectTest_FieldlessTable',
18
		'DataObjectTest_FieldlessSubTable',
19
		'DataObjectTest_ValidatedObject',
20
		'DataObjectTest_Player',
21
		'DataObjectTest_TeamComment',
22
		'DataObjectTest_ExtendedTeamComment',
23
		'DataObjectTest_EquipmentCompany',
24
		'DataObjectTest_SubEquipmentCompany',
25
		'DataObjectTest\NamespacedClass',
26
		'DataObjectTest_Sortable',
27
		'DataObjectTest_Company',
28
		'DataObjectTest_Fan',
29
		'ManyManyListTest_Product',
30
		'ManyManyListTest_Category',
31
	);
32
33
	public function testFilterDataObjectByCreatedDate() {
34
		// create an object to test with
35
		$obj1 = new DataObjectTest_ValidatedObject();
36
		$obj1->Name = 'test obj 1';
0 ignored issues
show
Documentation introduced by
The property Name does not exist on object<DataObjectTest_ValidatedObject>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
37
		$obj1->write();
38
		$this->assertTrue($obj1->isInDB());
39
40
		// reload the object from the database and reset its Created timestamp to a known value
41
		$obj1 = DataObjectTest_ValidatedObject::get()->filter(array('Name' => 'test obj 1'))->first();
42
		$this->assertTrue(is_object($obj1));
43
		$this->assertEquals('test obj 1', $obj1->Name);
44
		$obj1->Created = '2013-01-01 00:00:00';
45
		$obj1->write();
46
47
		// reload the object again and make sure that our Created date was properly persisted
48
		$obj1 = DataObjectTest_ValidatedObject::get()->filter(array('Name' => 'test obj 1'))->first();
49
		$this->assertTrue(is_object($obj1));
50
		$this->assertEquals('test obj 1', $obj1->Name);
51
		$this->assertEquals('2013-01-01 00:00:00', $obj1->Created);
52
53
		// now save a second object to the DB with an automatically-set Created value
54
		$obj2 = new DataObjectTest_ValidatedObject();
55
		$obj2->Name = 'test obj 2';
0 ignored issues
show
Documentation introduced by
The property Name does not exist on object<DataObjectTest_ValidatedObject>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
56
		$obj2->write();
57
		$this->assertTrue($obj2->isInDB());
58
59
		// and a third object
60
		$obj3 = new DataObjectTest_ValidatedObject();
61
		$obj3->Name = 'test obj 3';
0 ignored issues
show
Documentation introduced by
The property Name does not exist on object<DataObjectTest_ValidatedObject>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
62
		$obj3->write();
63
		$this->assertTrue($obj3->isInDB());
64
65
		// now test the filtering based on Created timestamp
66
		$list = DataObjectTest_ValidatedObject::get()
67
			->filter(array('Created:GreaterThan' => '2013-02-01 00:00:00'))
68
			->toArray();
69
		$this->assertEquals(2, count($list));
70
71
	}
72
73
	public function testSubtract(){
74
		$comment1 = $this->objFromFixture('DataObjectTest_TeamComment', 'comment1');
75
		$subtractList = DataObjectTest_TeamComment::get()->filter('ID', $comment1->ID);
76
		$fullList = DataObjectTest_TeamComment::get();
77
		$newList = $fullList->subtract($subtractList);
78
		$this->assertEquals(2, $newList->Count(), 'List should only contain two objects after subtraction');
79
	}
80
81
	public function testSubtractBadDataclassThrowsException(){
82
		$this->setExpectedException('InvalidArgumentException');
83
		$teamsComments = DataObjectTest_TeamComment::get();
84
		$teams = DataObjectTest_Team::get();
85
		$teamsComments->subtract($teams);
86
	}
87
88
	public function testListCreationSortAndLimit() {
89
		// By default, a DataList will contain all items of that class
90
		$list = DataObjectTest_TeamComment::get()->sort('ID');
91
92
		// We can iterate on the DataList
93
		$names = array();
94
		foreach($list as $item) {
95
			$names[] = $item->Name;
96
		}
97
		$this->assertEquals(array('Joe', 'Bob', 'Phil'), $names);
98
99
		// If we don't want to iterate, we can extract a single column from the list with column()
100
		$this->assertEquals(array('Joe', 'Bob', 'Phil'), $list->column('Name'));
101
102
		// We can sort a list
103
		$list = $list->sort('Name');
104
		$this->assertEquals(array('Bob', 'Joe', 'Phil'), $list->column('Name'));
105
106
		// We can also restrict the output to a range
107
		$this->assertEquals(array('Joe', 'Phil'), $list->limit(2, 1)->column('Name'));
108
	}
109
110
	public function testLimitAndOffset() {
111
		$list = DataObjectTest_TeamComment::get();
112
		$check = $list->limit(3);
113
114
		$this->assertEquals(3, $check->count());
115
116
		$check = $list->limit(1);
117
		$this->assertEquals(1, $check->count());
118
119
		$check = $list->limit(1, 1);
120
		$this->assertEquals(1, $check->count());
121
122
		$check = $list->limit(false);
123
		$this->assertEquals(3, $check->count());
124
125
		$check = $list->limit(null);
126
		$this->assertEquals(3, $check->count());
127
128
		$check = $list->limit(null, 2);
129
		$this->assertEquals(1, $check->count());
130
131
		// count()/first()/last() methods may alter limit/offset, so run the query and manually check the count
132
		$check = $list->limit(null, 1)->toArray();
133
		$this->assertEquals(2, count($check));
134
	}
135
136
	public function testDistinct() {
137
		$list = DataObjectTest_TeamComment::get();
138
		$this->assertContains('SELECT DISTINCT', $list->dataQuery()->sql($params), 'Query is set as distinct by default');
139
140
		$list = $list->distinct(false);
141
		$this->assertNotContains('SELECT DISTINCT', $list->dataQuery()->sql($params), 'Query does not contain distinct');
142
143
		$list = $list->distinct(true);
144
		$this->assertContains('SELECT DISTINCT', $list->dataQuery()->sql($params), 'Query contains distinct');
145
	}
146
147
	public function testDataClass() {
148
		$list = DataObjectTest_TeamComment::get();
149
		$this->assertEquals('DataObjectTest_TeamComment',$list->dataClass());
150
	}
151
152
	public function testDataClassCaseInsensitive() {
153
		$list = DataList::create('dataobjecttest_teamcomment');
154
		$this->assertTrue($list->exists());
155
	}
156
157
	public function testClone() {
158
		$list = DataObjectTest_TeamComment::get();
159
		$this->assertEquals($list, clone($list));
160
	}
161
162
	public function testSql() {
163
		$db = DB::get_conn();
164
		$list = DataObjectTest_TeamComment::get();
165
		$expected = 'SELECT DISTINCT "DataObjectTest_TeamComment"."ClassName", '
166
			. '"DataObjectTest_TeamComment"."LastEdited", "DataObjectTest_TeamComment"."Created", '
167
			. '"DataObjectTest_TeamComment"."Name", "DataObjectTest_TeamComment"."Comment", '
168
			. '"DataObjectTest_TeamComment"."TeamID", "DataObjectTest_TeamComment"."ID", '
169
			. 'CASE WHEN "DataObjectTest_TeamComment"."ClassName" IS NOT NULL '
170
			. 'THEN "DataObjectTest_TeamComment"."ClassName" ELSE '
171
			. $db->quoteString('DataObjectTest_TeamComment')
172
			. ' END AS "RecordClassName" FROM "DataObjectTest_TeamComment"'
173
			. ' ORDER BY "DataObjectTest_TeamComment"."Name" ASC';
174
		$this->assertSQLEquals($expected, $list->sql($parameters));
175
	}
176
177
	public function testInnerJoin() {
178
		$db = DB::get_conn();
179
180
		$list = DataObjectTest_TeamComment::get();
181
		$list = $list->innerJoin(
182
			'DataObjectTest_Team',
183
			'"DataObjectTest_Team"."ID" = "DataObjectTest_TeamComment"."TeamID"',
184
			'Team'
185
		);
186
187
		$expected = 'SELECT DISTINCT "DataObjectTest_TeamComment"."ClassName", '
188
			. '"DataObjectTest_TeamComment"."LastEdited", "DataObjectTest_TeamComment"."Created", '
189
			. '"DataObjectTest_TeamComment"."Name", "DataObjectTest_TeamComment"."Comment", '
190
			. '"DataObjectTest_TeamComment"."TeamID", "DataObjectTest_TeamComment"."ID", '
191
			. 'CASE WHEN "DataObjectTest_TeamComment"."ClassName" IS NOT NULL'
192
			. ' THEN "DataObjectTest_TeamComment"."ClassName" ELSE '
193
			. $db->quoteString('DataObjectTest_TeamComment')
194
			. ' END AS "RecordClassName" FROM "DataObjectTest_TeamComment" INNER JOIN '
195
			. '"DataObjectTest_Team" AS "Team" ON "DataObjectTest_Team"."ID" = '
196
			. '"DataObjectTest_TeamComment"."TeamID"'
197
			. ' ORDER BY "DataObjectTest_TeamComment"."Name" ASC';
198
199
200
		$this->assertSQLEquals($expected, $list->sql($parameters));
201
		$this->assertEmpty($parameters);
202
	}
203
204
	public function testInnerJoinParameterised() {
205
		$db = DB::get_conn();
206
207
		$list = DataObjectTest_TeamComment::get();
208
		$list = $list->innerJoin(
209
			'DataObjectTest_Team',
210
			'"DataObjectTest_Team"."ID" = "DataObjectTest_TeamComment"."TeamID" '
211
			. 'AND "DataObjectTest_Team"."Title" LIKE ?',
212
			'Team',
213
			20,
214
			array('Team%')
215
		);
216
217
		$expected = 'SELECT DISTINCT "DataObjectTest_TeamComment"."ClassName", '
218
			. '"DataObjectTest_TeamComment"."LastEdited", "DataObjectTest_TeamComment"."Created", '
219
			. '"DataObjectTest_TeamComment"."Name", "DataObjectTest_TeamComment"."Comment", '
220
			. '"DataObjectTest_TeamComment"."TeamID", "DataObjectTest_TeamComment"."ID", '
221
			. 'CASE WHEN "DataObjectTest_TeamComment"."ClassName" IS NOT NULL'
222
			. ' THEN "DataObjectTest_TeamComment"."ClassName" ELSE '
223
			. $db->quoteString('DataObjectTest_TeamComment')
224
			. ' END AS "RecordClassName" FROM "DataObjectTest_TeamComment" INNER JOIN '
225
			. '"DataObjectTest_Team" AS "Team" ON "DataObjectTest_Team"."ID" = '
226
			. '"DataObjectTest_TeamComment"."TeamID" '
227
			. 'AND "DataObjectTest_Team"."Title" LIKE ?'
228
			. ' ORDER BY "DataObjectTest_TeamComment"."Name" ASC';
229
230
		$this->assertSQLEquals($expected, $list->sql($parameters));
231
		$this->assertEquals(array('Team%'), $parameters);
232
	}
233
234
	public function testLeftJoin() {
235
		$db = DB::get_conn();
236
237
		$list = DataObjectTest_TeamComment::get();
238
		$list = $list->leftJoin(
239
			'DataObjectTest_Team',
240
			'"DataObjectTest_Team"."ID" = "DataObjectTest_TeamComment"."TeamID"',
241
			'Team'
242
		);
243
244
		$expected = 'SELECT DISTINCT "DataObjectTest_TeamComment"."ClassName", '
245
			. '"DataObjectTest_TeamComment"."LastEdited", "DataObjectTest_TeamComment"."Created", '
246
			. '"DataObjectTest_TeamComment"."Name", "DataObjectTest_TeamComment"."Comment", '
247
			. '"DataObjectTest_TeamComment"."TeamID", "DataObjectTest_TeamComment"."ID", '
248
			. 'CASE WHEN "DataObjectTest_TeamComment"."ClassName" IS NOT NULL '
249
			. 'THEN "DataObjectTest_TeamComment"."ClassName" ELSE '
250
			. $db->quoteString('DataObjectTest_TeamComment')
251
			. ' END AS "RecordClassName" FROM "DataObjectTest_TeamComment" LEFT JOIN "DataObjectTest_Team" '
252
			. 'AS "Team" ON "DataObjectTest_Team"."ID" = "DataObjectTest_TeamComment"."TeamID"'
253
			. ' ORDER BY "DataObjectTest_TeamComment"."Name" ASC';
254
255
256
		$this->assertSQLEquals($expected, $list->sql($parameters));
257
		$this->assertEmpty($parameters);
258
259
		// Test with namespaces (with non-sensical join, but good enough for testing)
260
		$list = DataObjectTest_TeamComment::get();
261
		$list = $list->leftJoin(
262
			'DataObjectTest\NamespacedClass',
263
			'"DataObjectTest\NamespacedClass"."ID" = "DataObjectTest_TeamComment"."ID"'
264
		);
265
266
		$expected = 'SELECT DISTINCT "DataObjectTest_TeamComment"."ClassName", '
267
			. '"DataObjectTest_TeamComment"."LastEdited", '
268
			. '"DataObjectTest_TeamComment"."Created", '
269
			. '"DataObjectTest_TeamComment"."Name", '
270
			. '"DataObjectTest_TeamComment"."Comment", '
271
			. '"DataObjectTest_TeamComment"."TeamID", '
272
			. '"DataObjectTest_TeamComment"."ID", '
273
			. 'CASE WHEN "DataObjectTest_TeamComment"."ClassName" IS NOT NULL '
274
			. 'THEN "DataObjectTest_TeamComment"."ClassName" '
275
			. 'ELSE ' . $db->quoteString('DataObjectTest_TeamComment') . ' END AS "RecordClassName" '
276
			. 'FROM "DataObjectTest_TeamComment" '
277
			. 'LEFT JOIN "DataObjectTest\NamespacedClass" ON '
278
			. '"DataObjectTest\NamespacedClass"."ID" = "DataObjectTest_TeamComment"."ID"'
279
			. ' ORDER BY "DataObjectTest_TeamComment"."Name" ASC';
280
		$this->assertSQLEquals($expected, $list->sql($parameters), 'Retains backslashes in namespaced classes');
281
		$this->assertEmpty($parameters);
282
283
	}
284
285
	public function testLeftJoinParameterised() {
286
		$db = DB::get_conn();
287
288
		$list = DataObjectTest_TeamComment::get();
289
		$list = $list->leftJoin(
290
			'DataObjectTest_Team',
291
			'"DataObjectTest_Team"."ID" = "DataObjectTest_TeamComment"."TeamID" '
292
			. 'AND "DataObjectTest_Team"."Title" LIKE ?',
293
			'Team',
294
			20,
295
			array('Team%')
296
		);
297
298
		$expected = 'SELECT DISTINCT "DataObjectTest_TeamComment"."ClassName", '
299
			. '"DataObjectTest_TeamComment"."LastEdited", "DataObjectTest_TeamComment"."Created", '
300
			. '"DataObjectTest_TeamComment"."Name", "DataObjectTest_TeamComment"."Comment", '
301
			. '"DataObjectTest_TeamComment"."TeamID", "DataObjectTest_TeamComment"."ID", '
302
			. 'CASE WHEN "DataObjectTest_TeamComment"."ClassName" IS NOT NULL'
303
			. ' THEN "DataObjectTest_TeamComment"."ClassName" ELSE '
304
			. $db->quoteString('DataObjectTest_TeamComment')
305
			. ' END AS "RecordClassName" FROM "DataObjectTest_TeamComment" LEFT JOIN '
306
			. '"DataObjectTest_Team" AS "Team" ON "DataObjectTest_Team"."ID" = '
307
			. '"DataObjectTest_TeamComment"."TeamID" '
308
			. 'AND "DataObjectTest_Team"."Title" LIKE ?'
309
			. ' ORDER BY "DataObjectTest_TeamComment"."Name" ASC';
310
311
		$this->assertSQLEquals($expected, $list->sql($parameters));
312
		$this->assertEquals(array('Team%'), $parameters);
313
	}
314
315
	public function testToNestedArray() {
316
		$list = DataObjectTest_TeamComment::get()->sort('ID');
317
		$nestedArray = $list->toNestedArray();
318
		$expected = array(
319
			0=>
320
			array(
321
				'ClassName'=>'DataObjectTest_TeamComment',
322
				'Name'=>'Joe',
323
				'Comment'=>'This is a team comment by Joe',
324
				'TeamID'=> $this->objFromFixture('DataObjectTest_TeamComment', 'comment1')->TeamID,
325
			),
326
			1=>
327
			array(
328
				'ClassName'=>'DataObjectTest_TeamComment',
329
				'Name'=>'Bob',
330
				'Comment'=>'This is a team comment by Bob',
331
				'TeamID'=> $this->objFromFixture('DataObjectTest_TeamComment', 'comment2')->TeamID,
332
			),
333
			2=>
334
			array(
335
				'ClassName'=>'DataObjectTest_TeamComment',
336
				'Name'=>'Phil',
337
				'Comment'=>'Phil is a unique guy, and comments on team2',
338
				'TeamID'=> $this->objFromFixture('DataObjectTest_TeamComment', 'comment3')->TeamID,
339
			),
340
		);
341
		$this->assertEquals(3, count($nestedArray));
342
		$this->assertEquals($expected[0]['Name'], $nestedArray[0]['Name']);
343
		$this->assertEquals($expected[1]['Comment'], $nestedArray[1]['Comment']);
344
		$this->assertEquals($expected[2]['TeamID'], $nestedArray[2]['TeamID']);
345
	}
346
347
	public function testMap() {
348
		$map = DataObjectTest_TeamComment::get()->map()->toArray();
349
		$expected = array(
350
			$this->idFromFixture('DataObjectTest_TeamComment', 'comment1') => 'Joe',
351
			$this->idFromFixture('DataObjectTest_TeamComment', 'comment2') => 'Bob',
352
			$this->idFromFixture('DataObjectTest_TeamComment', 'comment3') => 'Phil'
353
		);
354
355
		$this->assertEquals($expected, $map);
356
		$otherMap = DataObjectTest_TeamComment::get()->map('Name', 'TeamID')->toArray();
357
		$otherExpected = array(
358
			'Joe' => $this->objFromFixture('DataObjectTest_TeamComment', 'comment1')->TeamID,
359
			'Bob' => $this->objFromFixture('DataObjectTest_TeamComment', 'comment2')->TeamID,
360
			'Phil' => $this->objFromFixture('DataObjectTest_TeamComment', 'comment3')->TeamID
361
		);
362
363
		$this->assertEquals($otherExpected, $otherMap);
364
	}
365
366
	public function testEach() {
367
		$list = DataObjectTest_TeamComment::get();
368
369
		$count = 0;
370
		$test = $this;
371
372
		$list->each(function($item) use (&$count, $test) {
373
			$count++;
374
375
			$test->assertTrue(is_a($item, "DataObjectTest_TeamComment"));
376
		});
377
378
		$this->assertEquals($list->Count(), $count);
379
	}
380
381
	public function testWhere() {
382
		// We can use raw SQL queries with where.  This is only recommended for advanced uses;
383
		// if you can, you should use filter().
384
		$list = DataObjectTest_TeamComment::get();
385
386
		// where() returns a new DataList, like all the other modifiers, so it can be chained.
387
		$list2 = $list->where('"Name" = \'Joe\'');
388
		$this->assertEquals(array('This is a team comment by Joe'), $list2->column('Comment'));
389
390
		// The where() clauses are chained together with AND
391
		$list3 = $list2->where('"Name" = \'Bob\'');
392
		$this->assertEquals(array(), $list3->column('Comment'));
393
	}
394
395
	/**
396
	 * Test DataList->byID()
397
	 */
398
	public function testByID() {
399
		// We can get a single item by ID.
400
		$id = $this->idFromFixture('DataObjectTest_Team','team2');
401
		$team = DataObjectTest_Team::get()->byID($id);
402
403
		// byID() returns a DataObject, rather than a DataList
404
		$this->assertInstanceOf('DataObjectTest_Team', $team);
405
		$this->assertEquals('Team 2', $team->Title);
406
407
		// Assert that filtering on ID searches by the base table, not the child table field
408
		$query = DataObjectTest_SubTeam::get()->filter('ID', 4)->sql($parameters);
409
		$this->assertContains('WHERE ("DataObjectTest_Team"."ID" = ?)', $query);
410
		$this->assertNotContains('WHERE ("DataObjectTest_SubTeam"."ID" = ?)', $query);
411
	}
412
413
	public function testByIDs() {
414
		$knownIDs = $this->allFixtureIDs('DataObjectTest_Player');
415
		$removedID = array_pop($knownIDs);
416
		$filteredPlayers = DataObjectTest_Player::get()->byIDs($knownIDs);
417
		foreach ($filteredPlayers as $player) {
418
			$this->assertContains($player->ID, $knownIDs);
419
			$this->assertNotEquals($removedID, $player->ID);
420
		}
421
	}
422
423
	/**
424
	 * Test DataList->removeByID()
425
	 */
426
	public function testRemoveByID() {
427
		$list = DataObjectTest_Team::get();
428
		$id = $this->idFromFixture('DataObjectTest_Team','team2');
429
430
		$this->assertNotNull($list->byID($id));
431
		$list->removeByID($id);
432
		$this->assertNull($list->byID($id));
433
	}
434
435
	/**
436
	 * Test DataList->canSortBy()
437
	 */
438
	public function testCanSortBy() {
439
		// Basic check
440
		$team = DataObjectTest_Team::get();
441
		$this->assertTrue($team->canSortBy("Title"));
442
		$this->assertFalse($team->canSortBy("SomethingElse"));
443
444
		// Subclasses
445
		$subteam = DataObjectTest_SubTeam::get();
446
		$this->assertTrue($subteam->canSortBy("Title"));
447
		$this->assertTrue($subteam->canSortBy("SubclassDatabaseField"));
448
	}
449
450
	public function testDataListArrayAccess() {
451
		$list = DataObjectTest_Team::get()->sort('Title');
452
453
		// We can use array access to refer to single items in the DataList, as if it were an array
454
		$this->assertEquals("Subteam 1", $list[0]->Title);
455
		$this->assertEquals("Subteam 3", $list[2]->Title);
456
		$this->assertEquals("Team 2", $list[4]->Title);
457
	}
458
459
	public function testFind() {
460
		$list = DataObjectTest_Team::get();
461
		$record = $list->find('Title', 'Team 1');
462
		$this->assertEquals($this->idFromFixture('DataObjectTest_Team', 'team1'), $record->ID);
463
	}
464
465
	public function testFindById() {
466
		$list = DataObjectTest_Team::get();
467
		$record = $list->find('ID', $this->idFromFixture('DataObjectTest_Team', 'team1'));
468
		$this->assertEquals('Team 1', $record->Title);
469
		// Test that you can call it twice on the same list
470
		$record = $list->find('ID', $this->idFromFixture('DataObjectTest_Team', 'team2'));
471
		$this->assertEquals('Team 2', $record->Title);
472
	}
473
474
	public function testSimpleSort() {
475
		$list = DataObjectTest_TeamComment::get();
476
		$list = $list->sort('Name');
477
		$this->assertEquals('Bob', $list->first()->Name, 'First comment should be from Bob');
478
		$this->assertEquals('Phil', $list->last()->Name, 'Last comment should be from Phil');
479
	}
480
481
	public function testSimpleSortOneArgumentASC() {
482
		$list = DataObjectTest_TeamComment::get();
483
		$list = $list->sort('Name ASC');
484
		$this->assertEquals('Bob', $list->first()->Name, 'First comment should be from Bob');
485
		$this->assertEquals('Phil', $list->last()->Name, 'Last comment should be from Phil');
486
	}
487
488
	public function testSimpleSortOneArgumentDESC() {
489
		$list = DataObjectTest_TeamComment::get();
490
		$list = $list->sort('Name DESC');
491
		$this->assertEquals('Phil', $list->first()->Name, 'Last comment should be from Phil');
492
		$this->assertEquals('Bob', $list->last()->Name, 'First comment should be from Bob');
493
	}
494
495
	public function testSortOneArgumentMultipleColumns() {
496
		$list = DataObjectTest_TeamComment::get();
497
		$list = $list->sort('TeamID ASC, Name DESC');
498
		$this->assertEquals('Joe', $list->first()->Name, 'First comment should be from Bob');
499
		$this->assertEquals('Phil', $list->last()->Name, 'Last comment should be from Phil');
500
	}
501
502
	public function testSimpleSortASC() {
503
		$list = DataObjectTest_TeamComment::get();
504
		$list = $list->sort('Name', 'asc');
505
		$this->assertEquals('Bob', $list->first()->Name, 'First comment should be from Bob');
506
		$this->assertEquals('Phil', $list->last()->Name, 'Last comment should be from Phil');
507
	}
508
509
	public function testSimpleSortDESC() {
510
		$list = DataObjectTest_TeamComment::get();
511
		$list = $list->sort('Name', 'desc');
512
		$this->assertEquals('Phil', $list->first()->Name, 'Last comment should be from Phil');
513
		$this->assertEquals('Bob', $list->last()->Name, 'First comment should be from Bob');
514
	}
515
516
	public function testSortWithArraySyntaxSortASC() {
517
		$list = DataObjectTest_TeamComment::get();
518
		$list = $list->sort(array('Name'=>'asc'));
519
		$this->assertEquals('Bob', $list->first()->Name, 'First comment should be from Bob');
520
		$this->assertEquals('Phil', $list->last()->Name, 'Last comment should be from Phil');
521
	}
522
523
	public function testSortWithArraySyntaxSortDESC() {
524
		$list = DataObjectTest_TeamComment::get();
525
		$list = $list->sort(array('Name'=>'desc'));
526
		$this->assertEquals('Phil', $list->first()->Name, 'Last comment should be from Phil');
527
		$this->assertEquals('Bob', $list->last()->Name, 'First comment should be from Bob');
528
	}
529
530
	public function testSortWithMultipleArraySyntaxSort() {
531
		$list = DataObjectTest_TeamComment::get();
532
		$list = $list->sort(array('TeamID'=>'asc','Name'=>'desc'));
533
		$this->assertEquals('Joe', $list->first()->Name, 'First comment should be from Bob');
534
		$this->assertEquals('Phil', $list->last()->Name, 'Last comment should be from Phil');
535
	}
536
537
	public function testSortNumeric() {
538
		$list = DataObjectTest_Sortable::get();
539
		$list1 = $list->sort('Sort', 'ASC');
540
		$this->assertEquals(array(
541
			-10,
542
			-2,
543
			-1,
544
			0,
545
			1,
546
			2,
547
			10
548
		), $list1->column('Sort'));
549
	}
550
551
	public function testSortMixedCase() {
552
		$list = DataObjectTest_Sortable::get();
553
		$list1 = $list->sort('Name', 'ASC');
554
		$this->assertEquals(array(
555
            'Bob',
556
            'bonny',
557
            'jane',
558
            'John',
559
            'sam',
560
            'Steve',
561
            'steven'
562
		), $list1->column('Name'));
563
	}
564
565
	/**
566
	 * Test DataList->canFilterBy()
567
	 */
568
	public function testCanFilterBy() {
569
		// Basic check
570
		$team = DataObjectTest_Team::get();
571
		$this->assertTrue($team->canFilterBy("Title"));
572
		$this->assertFalse($team->canFilterBy("SomethingElse"));
573
574
		// Has one
575
		$this->assertTrue($team->canFilterBy("CaptainID"));
576
		$this->assertTrue($team->canFilterBy("Captain.ShirtNumber"));
577
		$this->assertFalse($team->canFilterBy("SomethingElse.ShirtNumber"));
578
		$this->assertFalse($team->canFilterBy("Captain.SomethingElse"));
579
		$this->assertTrue($team->canFilterBy("Captain.FavouriteTeam.Captain.ShirtNumber"));
580
581
		// Has many
582
		$this->assertTrue($team->canFilterBy("Fans.Name"));
583
		$this->assertFalse($team->canFilterBy("SomethingElse.Name"));
584
		$this->assertFalse($team->canFilterBy("Fans.SomethingElse"));
585
586
		// Many many
587
		$this->assertTrue($team->canFilterBy("Players.FirstName"));
588
		$this->assertFalse($team->canFilterBy("SomethingElse.FirstName"));
589
		$this->assertFalse($team->canFilterBy("Players.SomethingElse"));
590
591
		// Subclasses
592
		$subteam = DataObjectTest_SubTeam::get();
593
		$this->assertTrue($subteam->canFilterBy("Title"));
594
		$this->assertTrue($subteam->canFilterBy("SubclassDatabaseField"));
595
	}
596
597
	/**
598
	 * $list->filter('Name', 'bob'); // only bob in the list
599
	 */
600
	public function testSimpleFilter() {
601
		$list = DataObjectTest_Team::get();
602
		$list = $list->filter('Title','Team 2');
603
		$this->assertEquals(1, $list->count());
604
		$this->assertEquals('Team 2', $list->first()->Title, 'List should only contain Team 2');
605
		$this->assertEquals('Team 2', $list->last()->Title, 'Last should only contain Team 2');
606
	}
607
608
	public function testSimpleFilterEndsWith() {
609
		$list = DataObjectTest_TeamComment::get();
610
		$list = $list->filter('Name:EndsWith', 'b');
611
		$this->assertEquals(1, $list->count());
612
		$this->assertEquals('Bob', $list->first()->Name, 'First comment should be from Bob');
613
	}
614
615
	public function testSimpleFilterExactMatchFilter() {
616
		$list = DataObjectTest_TeamComment::get();
617
		$list = $list->filter('Name:ExactMatch', 'Bob');
618
		$this->assertEquals(1, $list->count());
619
		$this->assertEquals('Bob', $list->first()->Name, 'First comment should be from Bob');
620
	}
621
622
	public function testSimpleFilterGreaterThanFilter() {
623
		$list = DataObjectTest_TeamComment::get();
624
		$list = $list->filter('TeamID:GreaterThan', $this->idFromFixture('DataObjectTest_Team', 'team1'));
625
		$this->assertEquals(1, $list->count());
626
		$this->assertEquals('Phil', $list->first()->Name, 'First comment should be from Phil');
627
	}
628
629
	public function testSimpleFilterGreaterThanOrEqualFilter() {
630
		$list = DataObjectTest_TeamComment::get();
631
		$list = $list->filter('TeamID:GreaterThanOrEqual',
632
			$this->idFromFixture('DataObjectTest_Team', 'team1'))->sort("ID");
633
		$this->assertEquals(3, $list->count());
634
		$this->assertEquals('Joe', $list->first()->Name, 'First comment should be from Joe');
635
		$this->assertEquals('Phil', $list->last()->Name, 'Last comment should be from Phil');
636
	}
637
638
	public function testSimpleFilterLessThanFilter() {
639
		$list = DataObjectTest_TeamComment::get();
640
		$list = $list->filter('TeamID:LessThan',
641
			$this->idFromFixture('DataObjectTest_Team', 'team2'))->sort('Name');
642
		$this->assertEquals(2, $list->count());
643
		$this->assertEquals('Bob', $list->first()->Name, 'First comment should be from Bob');
644
		$this->assertEquals('Joe', $list->Last()->Name, 'Last comment should be from Joe');
645
	}
646
647
	public function testSimpleFilterLessThanOrEqualFilter() {
648
		$list = DataObjectTest_TeamComment::get();
649
		$list = $list->filter('TeamID:LessThanOrEqual',
650
			$this->idFromFixture('DataObjectTest_Team', 'team1'))->sort('ID');
651
		$this->assertEquals(2, $list->count());
652
		$this->assertEquals('Joe', $list->first()->Name, 'First comment should be from Joe');
653
		$this->assertEquals('Bob', $list->Last()->Name, 'Last comment should be from Bob');
654
	}
655
656
	public function testSimplePartialMatchFilter() {
657
		$list = DataObjectTest_TeamComment::get();
658
		$list = $list->filter('Name:PartialMatch', 'o')->sort('Name');
659
		$this->assertEquals(2, $list->count());
660
		$this->assertEquals('Bob', $list->first()->Name, 'First comment should be from Bob');
661
		$this->assertEquals('Joe', $list->last()->Name, 'First comment should be from Joe');
662
	}
663
664
	public function testSimpleFilterStartsWith() {
665
		$list = DataObjectTest_TeamComment::get();
666
		$list = $list->filter('Name:StartsWith', 'B');
667
		$this->assertEquals(1, $list->count());
668
		$this->assertEquals('Bob', $list->first()->Name, 'First comment should be from Bob');
669
	}
670
671
	public function testSimpleFilterWithNonExistingComparisator() {
672
		$this->setExpectedException('InvalidArgumentException');
673
		$list = DataObjectTest_TeamComment::get();
674
		$list = $list->filter('Comment:Bogus', 'team comment');
675
	}
676
677
	/**
678
	 * $list->filter('Name', array('aziz', 'bob'); // aziz and bob in list
679
	 */
680
	public function testSimpleFilterWithMultiple() {
681
		$list = DataObjectTest_TeamComment::get();
682
		$list = $list->filter('Name', array('Bob','Phil'));
683
		$list = $list->sort('Name', 'ASC');
684
		$this->assertEquals(2, $list->count());
685
		$this->assertEquals('Bob', $list->first()->Name, 'First comment should be from Bob');
686
		$this->assertEquals('Phil', $list->last()->Name, 'Last comment should be from Phil');
687
	}
688
689
	public function testMultipleFilterWithNoMatch() {
690
		$list = DataObjectTest_TeamComment::get();
691
		$list = $list->filter(array('Name'=>'Bob', 'Comment'=>'Phil is a unique guy, and comments on team2'));
692
		$this->assertEquals(0, $list->count());
693
	}
694
695
	/**
696
	 *  $list->filter(array('Name'=>'bob, 'Age'=>21)); // bob with the age 21
697
	 */
698
	public function testFilterMultipleArray() {
699
		$list = DataObjectTest_TeamComment::get();
700
		$list = $list->filter(array('Name'=>'Bob', 'Comment'=>'This is a team comment by Bob'));
701
		$list = $list->sort('Name', 'ASC');
702
		$this->assertEquals(1, $list->count());
703
		$this->assertEquals('Bob', $list->first()->Name, 'Only comment should be from Bob');
704
	}
705
706
	public function testFilterMultipleWithTwoMatches() {
707
		$list = DataObjectTest_TeamComment::get();
708
		$list = $list->filter(array('TeamID'=>$this->idFromFixture('DataObjectTest_Team', 'team1')));
709
		$this->assertEquals(2, $list->count());
710
	}
711
712
	public function testFilterMultipleWithArrayFilter() {
713
		$list = DataObjectTest_TeamComment::get();
714
		$list = $list->filter(array('Name'=>array('Bob','Phil')));
715
		$list = $list->sort('Name', 'ASC');
716
		$this->assertEquals(2, $list->count(), 'There should be two comments');
717
		$this->assertEquals('Bob', $list->first()->Name, 'First comment should be from Bob');
718
		$this->assertEquals('Phil', $list->last()->Name, 'Last comment should be from Phil');
719
	}
720
721
	public function testFilterMultipleWithArrayFilterAndModifiers() {
722
		$list = DataObjectTest_TeamComment::get();
723
		$list = $list->filter(array('Name:StartsWith'=>array('Bo', 'Jo')));
724
		$list = $list->sort('Name', 'ASC');
725
		$this->assertEquals(2, $list->count());
726
		$this->assertEquals('Bob', $list->first()->Name);
727
		$this->assertEquals('Joe', $list->last()->Name);
728
	}
729
730
	/**
731
	 * $list->filter(array('Name'=>array('aziz','bob'), 'Age'=>array(21, 43)));
732
	 */
733
	public function testFilterArrayInArray() {
734
		$list = DataObjectTest_TeamComment::get();
735
		$list = $list->filter(array(
736
			'Name'=>array('Bob','Phil'),
737
			'TeamID'=>array($this->idFromFixture('DataObjectTest_Team', 'team1'))));
738
		$this->assertEquals(1, $list->count(), 'There should be one comment');
739
		$this->assertEquals('Bob', $list->first()->Name, 'Only comment should be from Bob');
740
	}
741
742
	public function testFilterWithModifiers() {
743
		$list = DataObjectTest_TeamComment::get();
744
		$nocaseList = $list->filter('Name:nocase', 'bob');
745
		$this->assertEquals(1, $nocaseList->count(), 'There should be one comment');
746
		$caseList = $list->filter('Name:case', 'bob');
747
		$this->assertEquals(0, $caseList->count(), 'There should be no comments');
748
		$gtList = $list->filter('TeamID:GreaterThan:not',
749
			$this->idFromFixture('DataObjectTest_Team', 'team1'));
750
		$this->assertEquals(2, $gtList->count());
751
	}
752
753
	public function testFilterAny() {
754
		$list = DataObjectTest_TeamComment::get();
755
		$list = $list->filterAny('Name', 'Bob');
756
		$this->assertEquals(1, $list->count());
757
	}
758
759
	public function testFilterAnyMultipleArray() {
760
		$list = DataObjectTest_TeamComment::get();
761
		$list = $list->filterAny(array('Name'=>'Bob', 'Comment'=>'This is a team comment by Bob'));
762
		$this->assertEquals(1, $list->count());
763
		$this->assertEquals('Bob', $list->first()->Name, 'Only comment should be from Bob');
764
	}
765
766
	public function testFilterAnyOnFilter() {
767
		$list = DataObjectTest_TeamComment::get();
768
		$list = $list->filter(array(
769
			'TeamID'=>$this->idFromFixture('DataObjectTest_Team', 'team1')
770
		));
771
		$list = $list->filterAny(array(
772
			'Name'=>array('Phil', 'Joe'),
773
			'Comment'=>'This is a team comment by Bob'
774
		));
775
		$list = $list->sort('Name');
776
		$this->assertEquals(2, $list->count());
777
		$this->assertEquals(
778
			'Bob',
779
			$list->offsetGet(0)->Name,
780
			'Results should include comments from Bob, matched by comment and team'
781
		);
782
		$this->assertEquals(
783
			'Joe',
784
			$list->offsetGet(1)->Name,
785
			'Results should include comments by Joe, matched by name and team (not by comment)'
786
		);
787
788
		$list = DataObjectTest_TeamComment::get();
789
		$list = $list->filter(array(
790
			'TeamID'=>$this->idFromFixture('DataObjectTest_Team', 'team1')
791
		));
792
		$list = $list->filterAny(array(
793
			'Name'=>array('Phil', 'Joe'),
794
			'Comment'=>'This is a team comment by Bob'
795
		));
796
		$list = $list->sort('Name');
797
		$list = $list->filter(array('Name' => 'Bob'));
798
		$this->assertEquals(1, $list->count());
799
		$this->assertEquals(
800
			'Bob',
801
			$list->offsetGet(0)->Name,
802
			'Results should include comments from Bob, matched by name and team'
803
		);
804
	}
805
806
	public function testFilterAnyMultipleWithArrayFilter() {
807
		$list = DataObjectTest_TeamComment::get();
808
		$list = $list->filterAny(array('Name'=>array('Bob','Phil')));
809
		$this->assertEquals(2, $list->count(), 'There should be two comments');
810
		$this->assertEquals('Bob', $list->first()->Name, 'First comment should be from Bob');
811
		$this->assertEquals('Phil', $list->last()->Name, 'Last comment should be from Phil');
812
	}
813
814
	public function testFilterAnyArrayInArray() {
815
		$list = DataObjectTest_TeamComment::get();
816
		$list = $list->filterAny(array(
817
			'Name'=>array('Bob','Phil'),
818
			'TeamID'=>array($this->idFromFixture('DataObjectTest_Team', 'team1'))))
819
			->sort('Name');
820
		$this->assertEquals(3, $list->count());
821
		$this->assertEquals(
822
			'Bob',
823
			$list->offsetGet(0)->Name,
824
			'Results should include comments from Bob, matched by name and team'
825
		);
826
		$this->assertEquals(
827
			'Joe',
828
			$list->offsetGet(1)->Name,
829
			'Results should include comments by Joe, matched by team (not by name)'
830
		);
831
		$this->assertEquals(
832
			'Phil',
833
			$list->offsetGet(2)->Name,
834
			'Results should include comments from Phil, matched by name (even if he\'s not in Team1)'
835
		);
836
	}
837
838
	public function testFilterOnJoin() {
839
		$list = DataObjectTest_TeamComment::get()
840
			->leftJoin('DataObjectTest_Team',
841
				'"DataObjectTest_Team"."ID" = "DataObjectTest_TeamComment"."TeamID"'
842
			)->filter(array(
843
				'Title' => 'Team 1'
844
			));
845
846
		$this->assertEquals(2, $list->count());
847
		$values = $list->column('Name');
848
		$this->assertEquals(array_intersect($values, array('Joe', 'Bob')), $values);
849
	}
850
851
	public function testFilterOnImplicitJoin() {
852
		// Many to many
853
		$list = DataObjectTest_Team::get()
854
			->filter('Players.FirstName', array('Captain', 'Captain 2'));
855
856
		$this->assertEquals(2, $list->count());
857
858
		// Has many
859
		$list = DataObjectTest_Team::get()
860
			->filter('Comments.Name', array('Joe', 'Phil'));
861
862
		$this->assertEquals(2, $list->count());
863
864
		// Has one
865
		$list = DataObjectTest_Player::get()
866
			->filter('FavouriteTeam.Title', 'Team 1');
867
868
		$this->assertEquals(1, $list->count());
869
		$this->assertEquals('007', $list->first()->ShirtNumber);
870
	}
871
872
	public function testFilterAndExcludeById() {
873
		$id = $this->idFromFixture('DataObjectTest_SubTeam', 'subteam1');
874
		$list = DataObjectTest_SubTeam::get()->filter('ID', $id);
875
		$this->assertEquals($id, $list->first()->ID);
876
877
		$list = DataObjectTest_SubTeam::get();
878
		$this->assertEquals(3, count($list));
879
		$this->assertEquals(2, count($list->exclude('ID', $id)));
880
881
		// Check that classes with namespaces work.
882
		$obj = new DataObjectTest\NamespacedClass();
883
		$obj->Name = "Test";
0 ignored issues
show
Documentation introduced by
The property Name does not exist on object<DataObjectTest\NamespacedClass>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
884
		$obj->write();
885
886
		$list = DataObjectTest\NamespacedClass::get()->filter('ID', $obj->ID);
887
		$this->assertEquals('Test', $list->First()->Name);
888
		$this->assertEquals(0, $list->exclude('ID', $obj->ID)->count());
889
	}
890
891
	/**
892
	 * $list = $list->filterByCallback(function($item, $list) { return $item->Age == 21; })
893
	 */
894
	public function testFilterByCallback() {
895
		$team1ID = $this->idFromFixture('DataObjectTest_Team', 'team1');
896
		$list = DataObjectTest_TeamComment::get();
897
		$list = $list->filterByCallback(function ($item, $list) use ($team1ID) {
0 ignored issues
show
Unused Code introduced by
The parameter $list is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
898
			return $item->TeamID == $team1ID;
899
		});
900
901
		$result = $list->column('Name');
902
		$expected = array_intersect($result, array('Joe', 'Bob'));
903
904
		$this->assertEquals(2, $list->count());
905
		$this->assertEquals($expected, $result, 'List should only contain comments from Team 1 (Joe and Bob)');
906
		$this->assertTrue($list instanceof SS_Filterable, 'The List should be of type SS_Filterable');
907
	}
908
909
	/**
910
	 * $list->exclude('Name', 'bob'); // exclude bob from list
911
	 */
912
	public function testSimpleExclude() {
913
		$list = DataObjectTest_TeamComment::get();
914
		$list = $list->exclude('Name', 'Bob');
915
		$list = $list->sort('Name');
916
		$this->assertEquals(2, $list->count());
917
		$this->assertEquals('Joe', $list->first()->Name, 'First comment should be from Joe');
918
		$this->assertEquals('Phil', $list->last()->Name, 'Last comment should be from Phil');
919
	}
920
//
921
	/**
922
	 * $list->exclude('Name', array('aziz', 'bob'); // exclude aziz and bob from list
923
	 */
924
	public function testSimpleExcludeWithMultiple() {
925
		$list = DataObjectTest_TeamComment::get();
926
		$list = $list->exclude('Name', array('Joe','Phil'));
927
		$this->assertEquals(1, $list->count());
928
		$this->assertEquals('Bob', $list->first()->Name, 'First comment should be from Bob');
929
	}
930
931
	/**
932
	 * $list->exclude(array('Name'=>'bob, 'Age'=>21)); // negative version
933
	 */
934
	public function testMultipleExcludeWithMiss() {
935
		$list = DataObjectTest_TeamComment::get();
936
		$list = $list->exclude(array('Name'=>'Bob', 'Comment'=>'Does not match any comments'));
937
		$this->assertEquals(3, $list->count());
938
	}
939
940
	/**
941
	 * $list->exclude(array('Name'=>'bob, 'Age'=>21)); // exclude bob that has Age 21
942
	 */
943
	public function testMultipleExclude() {
944
		$list = DataObjectTest_TeamComment::get();
945
		$list = $list->exclude(array('Name'=>'Bob', 'Comment'=>'This is a team comment by Bob'));
946
		$this->assertEquals(2, $list->count());
947
	}
948
949
	/**
950
	 * Test that if an exclude() is applied to a filter(), the filter() is still preserved.
951
	 */
952
	public function testExcludeOnFilter() {
953
		$list = DataObjectTest_TeamComment::get();
954
		$list = $list->filter('Comment', 'Phil is a unique guy, and comments on team2');
955
		$list = $list->exclude('Name', 'Bob');
956
957
		$sql = $list->sql($parameters);
958
		$this->assertSQLContains(
959
			'WHERE ("DataObjectTest_TeamComment"."Comment" = ?) AND (("DataObjectTest_TeamComment"."Name" != ?))',
960
			$sql);
961
		$this->assertEquals(array('Phil is a unique guy, and comments on team2', 'Bob'), $parameters);
962
	}
963
964
	public function testExcludeWithSearchFilter() {
965
		$list = DataObjectTest_TeamComment::get();
966
		$list = $list->exclude('Name:LessThan', 'Bob');
967
968
		$sql = $list->sql($parameters);
969
		$this->assertSQLContains('WHERE (("DataObjectTest_TeamComment"."Name" >= ?))', $sql);
970
		$this->assertEquals(array('Bob'), $parameters);
971
	}
972
973
	/**
974
	 * Test exact match filter with empty array items
975
	 */
976
	public function testEmptyFilter() {
977
		$list = DataObjectTest_TeamComment::get();
978
		$list = $list->exclude('Name', array());
979
980
		$sql = $list->sql($parameters);
981
		$this->assertSQLContains('WHERE (("DataObjectTest_TeamComment"."Name" NOT IN (?)))', $sql);
982
		$this->assertEquals(array(''), $parameters);
983
984
985
		$list = DataObjectTest_TeamComment::get();
986
		$list = $list->filter('Name', array());
987
988
		$sql = $list->sql($parameters);
989
		$this->assertSQLContains('WHERE ("DataObjectTest_TeamComment"."Name" IN (?))', $sql);
990
		$this->assertEquals(array(''), $parameters);
991
	}
992
993
	/**
994
	 * $list->exclude(array('Name'=>'bob, 'Age'=>array(21, 43))); // exclude bob with Age 21 or 43
995
	 */
996
	public function testMultipleExcludeWithMultipleThatCheersEitherTeam() {
997
		$list = DataObjectTest_TeamComment::get();
998
		$list = $list->exclude(array('Name'=>'Bob', 'TeamID'=>array(
999
			$this->idFromFixture('DataObjectTest_Team', 'team1'),
1000
			$this->idFromFixture('DataObjectTest_Team', 'team2')
1001
		)));
1002
		$list = $list->sort('Name');
1003
		$this->assertEquals(2, $list->count());
1004
		$this->assertEquals('Joe', $list->first()->Name, 'First comment should be from Phil');
1005
		$this->assertEquals('Phil', $list->last()->Name, 'First comment should be from Phil');
1006
	}
1007
1008
	/**
1009
	 * $list->exclude(array('Name'=>'bob, 'Age'=>array(21, 43))); // negative version
1010
	 */
1011
	public function testMultipleExcludeWithMultipleThatCheersOnNonExistingTeam() {
1012
		$list = DataObjectTest_TeamComment::get();
1013
		$list = $list->exclude(array('Name'=>'Bob', 'TeamID'=>array(3)));
1014
		$this->assertEquals(3, $list->count());
1015
	}
1016
1017
	/**
1018
	 * $list->exclude(array('Name'=>array('bob','phil'), 'Age'=>array(21, 43))); //negative version
1019
	 */
1020
	public function testMultipleExcludeWithNoExclusion() {
1021
		$list = DataObjectTest_TeamComment::get();
1022
		$list = $list->exclude(array(
1023
			'Name'=>array('Bob','Joe'),
1024
			'Comment' => 'Phil is a unique guy, and comments on team2'));
1025
		$this->assertEquals(3, $list->count());
1026
	}
1027
1028
	/**
1029
	 *  $list->exclude(array('Name'=>array('bob','phil'), 'Age'=>array(21, 43)));
1030
	 */
1031
	public function testMultipleExcludeWithTwoArray() {
1032
		$list = DataObjectTest_TeamComment::get();
1033
		$list = $list->exclude(array('Name' => array('Bob','Joe'), 'TeamID' => array(
1034
			$this->idFromFixture('DataObjectTest_Team', 'team1'),
1035
			$this->idFromFixture('DataObjectTest_Team', 'team2')
1036
		)));
1037
		$this->assertEquals(1, $list->count());
1038
		$this->assertEquals('Phil', $list->last()->Name, 'Only comment should be from Phil');
1039
	}
1040
1041
	/**
1042
	 *  $list->exclude(array('Name'=>array('bob','phil'), 'Age'=>array(21, 43)));
1043
	 */
1044
	public function testMultipleExcludeWithTwoArrayOneTeam() {
1045
		$list = DataObjectTest_TeamComment::get();
1046
		$list = $list->exclude(array(
1047
			'Name' => array('Bob', 'Phil'),
1048
			'TeamID' => array($this->idFromFixture('DataObjectTest_Team', 'team1'))));
1049
		$list = $list->sort('Name');
1050
		$this->assertEquals(2, $list->count());
1051
		$this->assertEquals('Joe', $list->first()->Name, 'First comment should be from Joe');
1052
		$this->assertEquals('Phil', $list->last()->Name, 'Last comment should be from Phil');
1053
	}
1054
1055
	/**
1056
	 *
1057
	 */
1058
	public function testSortByRelation() {
1059
		$list = DataObjectTest_TeamComment::get();
1060
		$list = $list->sort(array('Team.Title' => 'DESC'));
1061
		$this->assertEquals(3, $list->count());
1062
		$this->assertEquals($this->idFromFixture('DataObjectTest_Team', 'team2'), $list->first()->TeamID,
1063
			'First comment should be for Team 2');
1064
		$this->assertEquals($this->idFromFixture('DataObjectTest_Team', 'team1'), $list->last()->TeamID,
1065
			'Last comment should be for Team 1');
1066
	}
1067
1068
	public function testReverse() {
1069
		$list = DataObjectTest_TeamComment::get();
1070
		$list = $list->sort('Name');
1071
		$list = $list->reverse();
1072
1073
		$this->assertEquals('Bob', $list->last()->Name, 'Last comment should be from Bob');
1074
		$this->assertEquals('Phil', $list->first()->Name, 'First comment should be from Phil');
1075
	}
1076
1077
	public function testSortByComplexExpression() {
1078
		// Test an expression with both spaces and commas. This test also tests that column() can be called
1079
		// with a complex sort expression, so keep using column() below
1080
		$list = DataObjectTest_Team::get()->sort(
1081
			'CASE WHEN "DataObjectTest_Team"."ClassName" = \'DataObjectTest_SubTeam\' THEN 0 ELSE 1 END, "Title" DESC'
1082
		);
1083
		$this->assertEquals(array(
1084
			'Subteam 3',
1085
			'Subteam 2',
1086
			'Subteam 1',
1087
			'Team 3',
1088
			'Team 2',
1089
			'Team 1',
1090
		), $list->column("Title"));
1091
	}
1092
}
1093