Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like ImageTest often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use ImageTest, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
7 | class ImageTest extends SapphireTest { |
||
8 | |||
9 | protected static $fixture_file = 'ImageTest.yml'; |
||
10 | |||
11 | protected $origBackend; |
||
12 | |||
13 | public function setUp() { |
||
14 | if(get_class($this) == "ImageTest") $this->skipTest = true; |
||
15 | |||
16 | parent::setUp(); |
||
17 | |||
18 | $this->origBackend = Image::get_backend(); |
||
19 | |||
20 | if($this->skipTest) |
||
21 | return; |
||
22 | |||
23 | if(!file_exists(ASSETS_PATH)) mkdir(ASSETS_PATH); |
||
24 | |||
25 | // Create a test folders for each of the fixture references |
||
26 | $folderIDs = $this->allFixtureIDs('Folder'); |
||
27 | |||
28 | View Code Duplication | foreach($folderIDs as $folderID) { |
|
29 | $folder = DataObject::get_by_id('Folder', $folderID); |
||
30 | |||
31 | if(!file_exists(BASE_PATH."/$folder->Filename")) mkdir(BASE_PATH."/$folder->Filename"); |
||
32 | } |
||
33 | |||
34 | // Copy test images for each of the fixture references |
||
35 | $imageIDs = $this->allFixtureIDs('Image'); |
||
36 | foreach($imageIDs as $imageID) { |
||
37 | $image = DataObject::get_by_id('Image', $imageID); |
||
38 | $filePath = BASE_PATH."/$image->Filename"; |
||
39 | $sourcePath = str_replace('assets/ImageTest/', 'framework/tests/model/testimages/', $filePath); |
||
40 | if(!file_exists($filePath)) { |
||
41 | if (!copy($sourcePath, $filePath)) user_error('Failed to copy test images', E_USER_ERROR); |
||
42 | } |
||
43 | } |
||
44 | } |
||
45 | |||
46 | public function tearDown() { |
||
47 | if($this->origBackend) Image::set_backend($this->origBackend); |
||
48 | |||
49 | // Remove the test files that we've created |
||
50 | $fileIDs = $this->allFixtureIDs('Image'); |
||
51 | View Code Duplication | foreach($fileIDs as $fileID) { |
|
52 | $file = DataObject::get_by_id('Image', $fileID); |
||
53 | if($file && file_exists(BASE_PATH."/$file->Filename")) unlink(BASE_PATH."/$file->Filename"); |
||
54 | } |
||
55 | |||
56 | // Remove the test folders that we've created |
||
57 | $folderIDs = $this->allFixtureIDs('Folder'); |
||
58 | foreach($folderIDs as $folderID) { |
||
59 | $folder = DataObject::get_by_id('Folder', $folderID); |
||
60 | if($folder && file_exists(BASE_PATH."/$folder->Filename")) { |
||
61 | Filesystem::removeFolder(BASE_PATH."/$folder->Filename"); |
||
62 | } |
||
63 | if($folder && file_exists(BASE_PATH."/".$folder->Filename."_resampled")) { |
||
64 | Filesystem::removeFolder(BASE_PATH."/".$folder->Filename."_resampled"); |
||
65 | } |
||
66 | } |
||
67 | |||
68 | parent::tearDown(); |
||
69 | } |
||
70 | |||
71 | View Code Duplication | public function testGetTagWithTitle() { |
|
72 | $image = $this->objFromFixture('Image', 'imageWithTitle'); |
||
73 | $expected = '<img src="' . Director::baseUrl() |
||
74 | . 'assets/ImageTest/test_image.png" alt="This is a image Title" />'; |
||
75 | $actual = $image->getTag(); |
||
76 | |||
77 | $this->assertEquals($expected, $actual); |
||
78 | } |
||
79 | |||
80 | View Code Duplication | public function testGetTagWithoutTitle() { |
|
81 | $image = $this->objFromFixture('Image', 'imageWithoutTitle'); |
||
82 | $expected = '<img src="' . Director::baseUrl() . 'assets/ImageTest/test_image.png" alt="test_image" />'; |
||
83 | $actual = $image->getTag(); |
||
84 | |||
85 | $this->assertEquals($expected, $actual); |
||
86 | } |
||
87 | |||
88 | View Code Duplication | public function testGetTagWithoutTitleContainingDots() { |
|
89 | $image = $this->objFromFixture('Image', 'imageWithoutTitleContainingDots'); |
||
90 | $expected = '<img src="' . Director::baseUrl() |
||
91 | . 'assets/ImageTest/test.image.with.dots.png" alt="test.image.with.dots" />'; |
||
92 | $actual = $image->getTag(); |
||
93 | |||
94 | $this->assertEquals($expected, $actual); |
||
95 | } |
||
96 | |||
97 | /** |
||
98 | * Tests that multiple image manipulations may be performed on a single Image |
||
99 | */ |
||
100 | public function testMultipleGenerateManipulationCalls() { |
||
101 | $image = $this->objFromFixture('Image', 'imageWithoutTitle'); |
||
102 | |||
103 | $imageFirst = $image->ScaleWidth(200); |
||
104 | $this->assertNotNull($imageFirst); |
||
105 | $expected = 200; |
||
106 | $actual = $imageFirst->getWidth(); |
||
107 | |||
108 | $this->assertEquals($expected, $actual); |
||
109 | |||
110 | $imageSecond = $imageFirst->setHeight(100); |
||
111 | $this->assertNotNull($imageSecond); |
||
112 | $expected = 100; |
||
113 | $actual = $imageSecond->getHeight(); |
||
114 | $this->assertEquals($expected, $actual); |
||
115 | } |
||
116 | |||
117 | /** |
||
118 | * Tests that image manipulations that do not affect the resulting dimensions |
||
119 | * of the output image do not resample the file. |
||
120 | */ |
||
121 | public function testReluctanceToResampling() { |
||
122 | $image = $this->objFromFixture('Image', 'imageWithoutTitle'); |
||
123 | $this->assertTrue($image->isSize(300, 300)); |
||
124 | |||
125 | // Set width to 300 pixels |
||
126 | $imageScaleWidth = $image->ScaleWidth(300); |
||
127 | $this->assertEquals($imageScaleWidth->getWidth(), 300); |
||
128 | $this->assertEquals($image->Filename, $imageScaleWidth->Filename); |
||
129 | |||
130 | // Set height to 300 pixels |
||
131 | $imageScaleHeight = $image->ScaleHeight(300); |
||
132 | $this->assertEquals($imageScaleHeight->getHeight(), 300); |
||
133 | $this->assertEquals($image->Filename, $imageScaleHeight->Filename); |
||
134 | |||
135 | // Crop image to 300 x 300 |
||
136 | $imageCropped = $image->Fill(300, 300); |
||
137 | $this->assertTrue($imageCropped->isSize(300, 300)); |
||
138 | $this->assertEquals($image->Filename, $imageCropped->Filename); |
||
139 | |||
140 | // Resize (padded) to 300 x 300 |
||
141 | $imageSized = $image->Pad(300, 300); |
||
142 | $this->assertTrue($imageSized->isSize(300, 300)); |
||
143 | $this->assertEquals($image->Filename, $imageSized->Filename); |
||
144 | |||
145 | // Padded image 300 x 300 (same as above) |
||
146 | $imagePadded = $image->Pad(300, 300); |
||
147 | $this->assertTrue($imagePadded->isSize(300, 300)); |
||
148 | $this->assertEquals($image->Filename, $imagePadded->Filename); |
||
149 | |||
150 | // Resized (stretched) to 300 x 300 |
||
151 | $imageStretched = $image->ResizedImage(300, 300); |
||
152 | $this->assertTrue($imageStretched->isSize(300, 300)); |
||
153 | $this->assertEquals($image->Filename, $imageStretched->Filename); |
||
154 | |||
155 | // Fit (various options) |
||
156 | $imageFit = $image->Fit(300, 600); |
||
157 | $this->assertTrue($imageFit->isSize(300, 300)); |
||
158 | $this->assertEquals($image->Filename, $imageFit->Filename); |
||
159 | $imageFit = $image->Fit(600, 300); |
||
160 | $this->assertTrue($imageFit->isSize(300, 300)); |
||
161 | $this->assertEquals($image->Filename, $imageFit->Filename); |
||
162 | $imageFit = $image->Fit(300, 300); |
||
163 | $this->assertTrue($imageFit->isSize(300, 300)); |
||
164 | $this->assertEquals($image->Filename, $imageFit->Filename); |
||
165 | } |
||
166 | |||
167 | /** |
||
168 | * Tests that image manipulations that do not affect the resulting dimensions |
||
169 | * of the output image resample the file when force_resample is set to true. |
||
170 | */ |
||
171 | public function testForceResample() { |
||
172 | $image = $this->objFromFixture('Image', 'imageWithoutTitle'); |
||
173 | $this->assertTrue($image->isSize(300, 300)); |
||
174 | |||
175 | $origForceResample = Config::inst()->get('Image', 'force_resample'); |
||
176 | Config::inst()->update('Image', 'force_resample', true); |
||
177 | |||
178 | // Set width to 300 pixels |
||
179 | $imageScaleWidth = $image->ScaleWidth(300); |
||
180 | $this->assertEquals($imageScaleWidth->getWidth(), 300); |
||
181 | $this->assertNotEquals($image->Filename, $imageScaleWidth->Filename); |
||
182 | |||
183 | // Set height to 300 pixels |
||
184 | $imageScaleHeight = $image->ScaleHeight(300); |
||
185 | $this->assertEquals($imageScaleHeight->getHeight(), 300); |
||
186 | $this->assertNotEquals($image->Filename, $imageScaleHeight->Filename); |
||
187 | |||
188 | // Crop image to 300 x 300 |
||
189 | $imageCropped = $image->Fill(300, 300); |
||
190 | $this->assertTrue($imageCropped->isSize(300, 300)); |
||
191 | $this->assertNotEquals($image->Filename, $imageCropped->Filename); |
||
192 | |||
193 | // Resize (padded) to 300 x 300 |
||
194 | $imageSized = $image->Pad(300, 300); |
||
195 | $this->assertTrue($imageSized->isSize(300, 300)); |
||
196 | $this->assertNotEquals($image->Filename, $imageSized->Filename); |
||
197 | |||
198 | // Padded image 300 x 300 (same as above) |
||
199 | $imagePadded = $image->Pad(300, 300); |
||
200 | $this->assertTrue($imagePadded->isSize(300, 300)); |
||
201 | $this->assertNotEquals($image->Filename, $imagePadded->Filename); |
||
202 | |||
203 | // Resized (stretched) to 300 x 300 |
||
204 | $imageStretched = $image->ResizedImage(300, 300); |
||
205 | $this->assertTrue($imageStretched->isSize(300, 300)); |
||
206 | $this->assertNotEquals($image->Filename, $imageStretched->Filename); |
||
207 | |||
208 | // Fit (various options) |
||
209 | $imageFit = $image->Fit(300, 600); |
||
210 | $this->assertTrue($imageFit->isSize(300, 300)); |
||
211 | $this->assertNotEquals($image->Filename, $imageFit->Filename); |
||
212 | $imageFit = $image->Fit(600, 300); |
||
213 | $this->assertTrue($imageFit->isSize(300, 300)); |
||
214 | $this->assertNotEquals($image->Filename, $imageFit->Filename); |
||
215 | $imageFit = $image->Fit(300, 300); |
||
216 | $this->assertTrue($imageFit->isSize(300, 300)); |
||
217 | $this->assertNotEquals($image->Filename, $imageFit->Filename); |
||
218 | Config::inst()->update('Image', 'force_resample', $origForceResample); |
||
219 | } |
||
220 | |||
221 | public function testImageResize() { |
||
222 | $image = $this->objFromFixture('Image', 'imageWithoutTitle'); |
||
223 | $this->assertTrue($image->isSize(300, 300)); |
||
224 | |||
225 | // Test normal resize |
||
226 | $resized = $image->Pad(150, 100); |
||
227 | $this->assertTrue($resized->isSize(150, 100)); |
||
228 | |||
229 | // Test cropped resize |
||
230 | $cropped = $image->Fill(100, 200); |
||
231 | $this->assertTrue($cropped->isSize(100, 200)); |
||
232 | |||
233 | // Test padded resize |
||
234 | $padded = $image->Pad(200, 100); |
||
235 | $this->assertTrue($padded->isSize(200, 100)); |
||
236 | |||
237 | // Test Fit |
||
238 | $ratio = $image->Fit(80, 160); |
||
239 | $this->assertTrue($ratio->isSize(80, 80)); |
||
240 | |||
241 | // Test FitMax |
||
242 | $fitMaxDn = $image->FitMax(200, 100); |
||
243 | $this->assertTrue($fitMaxDn->isSize(100, 100)); |
||
244 | $fitMaxUp = $image->FitMax(500, 400); |
||
245 | $this->assertTrue($fitMaxUp->isSize(300, 300)); |
||
246 | |||
247 | //Test ScaleMax |
||
248 | $scaleMaxWDn = $image->ScaleMaxWidth(200); |
||
249 | $this->assertTrue($scaleMaxWDn->isSize(200, 200)); |
||
250 | $scaleMaxWUp = $image->ScaleMaxWidth(400); |
||
251 | $this->assertTrue($scaleMaxWUp->isSize(300, 300)); |
||
252 | $scaleMaxHDn = $image->ScaleMaxHeight(200); |
||
253 | $this->assertTrue($scaleMaxHDn->isSize(200, 200)); |
||
254 | $scaleMaxHUp = $image->ScaleMaxHeight(400); |
||
255 | $this->assertTrue($scaleMaxHUp->isSize(300, 300)); |
||
256 | |||
257 | // Test FillMax |
||
258 | $cropMaxDn = $image->FillMax(200, 100); |
||
259 | $this->assertTrue($cropMaxDn->isSize(200, 100)); |
||
260 | $cropMaxUp = $image->FillMax(400, 200); |
||
261 | $this->assertTrue($cropMaxUp->isSize(300, 150)); |
||
262 | |||
263 | // Test Clip |
||
264 | $clipWDn = $image->CropWidth(200); |
||
265 | $this->assertTrue($clipWDn->isSize(200, 300)); |
||
266 | $clipWUp = $image->CropWidth(400); |
||
267 | $this->assertTrue($clipWUp->isSize(300, 300)); |
||
268 | $clipHDn = $image->CropHeight(200); |
||
269 | $this->assertTrue($clipHDn->isSize(300, 200)); |
||
270 | $clipHUp = $image->CropHeight(400); |
||
271 | $this->assertTrue($clipHUp->isSize(300, 300)); |
||
272 | } |
||
273 | |||
274 | /** |
||
275 | * @expectedException InvalidArgumentException |
||
276 | */ |
||
277 | public function testGenerateImageWithInvalidParameters() { |
||
278 | $image = $this->objFromFixture('Image', 'imageWithoutTitle'); |
||
279 | $image->setHeight('String'); |
||
280 | $image->Pad(600,600,'XXXXXX'); |
||
281 | } |
||
282 | |||
283 | public function testCacheFilename() { |
||
284 | $image = $this->objFromFixture('Image', 'imageWithoutTitle'); |
||
285 | $imageFirst = $image->Pad(200,200,'CCCCCC'); |
||
286 | $imageFilename = $imageFirst->getFullPath(); |
||
287 | // Encoding of the arguments is duplicated from cacheFilename |
||
288 | $neededPart = 'Pad' . Convert::base64url_encode(array(200,200,'CCCCCC')); |
||
289 | $this->assertContains($neededPart, $imageFilename, 'Filename for cached image is correctly generated'); |
||
290 | } |
||
291 | |||
292 | public function testMultipleGenerateManipulationCalls_Regeneration() { |
||
293 | $image = $this->objFromFixture('Image', 'imageWithoutTitle'); |
||
294 | $folder = new SS_FileFinder(); |
||
295 | |||
296 | $imageFirst = $image->Pad(200,200); |
||
297 | $this->assertNotNull($imageFirst); |
||
298 | $expected = 200; |
||
299 | $actual = $imageFirst->getWidth(); |
||
300 | |||
301 | $this->assertEquals($expected, $actual); |
||
302 | |||
303 | $imageSecond = $imageFirst->setHeight(100); |
||
304 | $this->assertNotNull($imageSecond); |
||
305 | $expected = 100; |
||
306 | $actual = $imageSecond->getHeight(); |
||
307 | $this->assertEquals($expected, $actual); |
||
308 | |||
309 | $imageThird = $imageSecond->Pad(600,600,'0F0F0F'); |
||
310 | // Encoding of the arguments is duplicated from cacheFilename |
||
311 | $argumentString = Convert::base64url_encode(array(600,600,'0F0F0F')); |
||
312 | $this->assertNotNull($imageThird); |
||
313 | $this->assertContains($argumentString, $imageThird->getFullPath(), |
||
314 | 'Image contains background color for padded resizement'); |
||
315 | |||
316 | $resampledFolder = dirname($image->getFullPath()) . "/_resampled"; |
||
317 | $filesInFolder = $folder->find($resampledFolder); |
||
318 | $this->assertEquals(3, count($filesInFolder), |
||
319 | 'Image folder contains only the expected number of images before regeneration'); |
||
320 | |||
321 | $imageThirdPath = $imageThird->getFullPath(); |
||
322 | $stats = getimagesize($imageThirdPath); |
||
323 | $this->assertEquals(3, $image->regenerateFormattedImages(), |
||
324 | 'Cached images were regenerated in the right number'); |
||
325 | $this->assertEquals($stats, getimagesize($imageThirdPath), 'Regeneration of third image is correct'); |
||
326 | |||
327 | /* Check that no other images exist, to ensure that the regeneration did not create other images */ |
||
328 | $this->assertEquals($filesInFolder, $folder->find($resampledFolder), |
||
329 | 'Image folder contains only the expected image files after regeneration'); |
||
330 | } |
||
331 | |||
332 | public function testRegenerateImages() { |
||
333 | $image = $this->objFromFixture('Image', 'imageWithoutTitle'); |
||
334 | $image_generated = $image->ScaleWidth(200); |
||
335 | $p = $image_generated->getFullPath(); |
||
336 | $this->assertTrue(file_exists($p), 'Resized image exists after creation call'); |
||
337 | $this->assertEquals(1, $image->regenerateFormattedImages(), 'Cached images were regenerated correct'); |
||
338 | $this->assertEquals($image_generated->getWidth(), 200, |
||
339 | 'Resized image has correct width after regeneration call'); |
||
340 | $this->assertTrue(file_exists($p), 'Resized image exists after regeneration call'); |
||
341 | } |
||
342 | |||
343 | /** |
||
344 | * Test that propertes from the source Image are inherited by resampled images |
||
345 | */ |
||
346 | View Code Duplication | public function testPropertyInheritance() { |
|
347 | $testString = 'This is a test'; |
||
348 | $origImage = $this->objFromFixture('Image', 'imageWithTitle'); |
||
349 | $origImage->TestProperty = $testString; |
||
350 | $resampled = $origImage->ScaleWidth(10); |
||
351 | $this->assertEquals($resampled->TestProperty, $testString); |
||
352 | $resampled2 = $resampled->ScaleWidth(5); |
||
353 | $this->assertEquals($resampled2->TestProperty, $testString); |
||
354 | } |
||
355 | |||
356 | /** |
||
357 | * Tests that cached images are regenerated properly after a cached file is renamed with new arguments |
||
358 | * ToDo: This doesn't seem like something that is worth testing - what is the point of this? |
||
359 | */ |
||
360 | public function testRegenerateImagesWithRenaming() { |
||
382 | |||
383 | public function testGeneratedImageDeletion() { |
||
384 | $image = $this->objFromFixture('Image', 'imageWithoutTitle'); |
||
385 | $image_generated = $image->ScaleWidth(200); |
||
386 | $p = $image_generated->getFullPath(); |
||
387 | $this->assertTrue(file_exists($p), 'Resized image exists after creation call'); |
||
388 | $numDeleted = $image->deleteFormattedImages(); |
||
389 | $this->assertEquals(1, $numDeleted, 'Expected one image to be deleted, but deleted ' . $numDeleted . ' images'); |
||
390 | $this->assertFalse(file_exists($p), 'Resized image not existing after deletion call'); |
||
391 | } |
||
392 | |||
393 | /** |
||
394 | * Tests that generated images with multiple image manipulations are all deleted |
||
395 | */ |
||
396 | public function testMultipleGenerateManipulationCallsImageDeletion() { |
||
397 | $image = $this->objFromFixture('Image', 'imageWithoutTitle'); |
||
398 | |||
399 | $firstImage = $image->ScaleWidth(200); |
||
400 | $firstImagePath = $firstImage->getFullPath(); |
||
401 | $this->assertTrue(file_exists($firstImagePath)); |
||
402 | |||
403 | $secondImage = $firstImage->ScaleHeight(100); |
||
404 | $secondImagePath = $secondImage->getFullPath(); |
||
405 | $this->assertTrue(file_exists($secondImagePath)); |
||
406 | |||
407 | $image->deleteFormattedImages(); |
||
408 | $this->assertFalse(file_exists($firstImagePath)); |
||
409 | $this->assertFalse(file_exists($secondImagePath)); |
||
410 | } |
||
411 | |||
412 | /** |
||
413 | * Tests path properties of cached images with multiple image manipulations |
||
414 | */ |
||
415 | View Code Duplication | public function testPathPropertiesCachedImage() { |
|
416 | $image = $this->objFromFixture('Image', 'imageWithoutTitle'); |
||
417 | $firstImage = $image->ScaleWidth(200); |
||
418 | $firstImagePath = $firstImage->getRelativePath(); |
||
419 | $this->assertEquals($firstImagePath, $firstImage->Filename); |
||
420 | |||
421 | $secondImage = $firstImage->ScaleHeight(100); |
||
422 | $secondImagePath = $secondImage->getRelativePath(); |
||
423 | $this->assertEquals($secondImagePath, $secondImage->Filename); |
||
424 | } |
||
425 | |||
426 | /** |
||
427 | * Tests the static function Image::strip_resampled_prefix, to ensure that |
||
428 | * the original filename can be extracted from the path of transformed images, |
||
429 | * both in current and previous formats |
||
430 | */ |
||
431 | public function testStripResampledPrefix() { |
||
432 | $orig_image = $this->objFromFixture('Image', 'imageWithoutTitleContainingDots'); |
||
433 | |||
434 | // current format (3.3+). Example: |
||
435 | // assets/ImageTest/_resampled/ScaleHeightWzIwMF0=/ScaleWidthWzQwMF0=/test.image.with.dots.png; |
||
436 | $firstImage = $orig_image->ScaleWidth(200); |
||
437 | $secondImage = $firstImage->ScaleHeight(200); |
||
438 | $paths_1 = $firstImage->Filename; |
||
439 | $paths_2 = $secondImage->Filename; |
||
440 | |||
441 | // 3.2 format (did not work for multiple transformations) |
||
442 | $paths_3 = 'assets/ImageTest/_resampled/ScaleHeightWzIwMF0=-test.image.with.dots.png'; |
||
443 | |||
444 | // 3.1 (and earlier) format (did not work for multiple transformations) |
||
445 | $paths_4 = 'assets/ImageTest/_resampled/ScaleHeight200-test.image.with.dots.png'; |
||
446 | |||
447 | $this->assertEquals($orig_image->Filename, Image::strip_resampled_prefix($paths_1)); |
||
448 | $this->assertEquals($orig_image->Filename, Image::strip_resampled_prefix($paths_2)); |
||
449 | $this->assertEquals($orig_image->Filename, Image::strip_resampled_prefix($paths_3)); |
||
450 | $this->assertEquals($orig_image->Filename, Image::strip_resampled_prefix($paths_4)); |
||
451 | } |
||
452 | |||
453 | /** |
||
454 | * Test all generate methods |
||
455 | */ |
||
456 | public function testGenerateMethods() { |
||
457 | $image = $this->objFromFixture('Image', 'imageWithoutTitle'); |
||
458 | $generateMethods = $this->getGenerateMethods(); |
||
459 | |||
460 | // test each generate method |
||
461 | foreach ($generateMethods as $method) { |
||
462 | $generatedImage = $image->$method(333, 333, 'FFFFFF'); |
||
463 | $this->assertFileExists( |
||
464 | $generatedImage->getFullPath(), |
||
465 | 'Formatted ' . $method . ' image exists' |
||
466 | ); |
||
467 | } |
||
468 | } |
||
469 | |||
470 | /** |
||
471 | * Test deleteFormattedImages() against all generate methods |
||
472 | */ |
||
473 | public function testDeleteFormattedImages() { |
||
495 | |||
496 | /** |
||
497 | * @param bool $custom include methods added dynamically at runtime |
||
498 | * @return array |
||
499 | */ |
||
500 | protected function getGenerateMethods($custom = true) { |
||
513 | |||
514 | } |
||
515 |