cms/drupal/modules/simpletest/tests/image.test
changeset 541 e756a8c72c3d
equal deleted inserted replaced
540:07239de796bb 541:e756a8c72c3d
       
     1 <?php
       
     2 
       
     3 /**
       
     4  * @file
       
     5  * Tests for core image handling API.
       
     6  */
       
     7 
       
     8 /**
       
     9  * Base class for image manipulation testing.
       
    10  */
       
    11 class ImageToolkitTestCase extends DrupalWebTestCase {
       
    12   protected $toolkit;
       
    13   protected $file;
       
    14   protected $image;
       
    15 
       
    16   function setUp() {
       
    17     $modules = func_get_args();
       
    18     if (isset($modules[0]) && is_array($modules[0])) {
       
    19       $modules = $modules[0];
       
    20     }
       
    21     $modules[] = 'image_test';
       
    22 
       
    23     parent::setUp($modules);
       
    24 
       
    25     // Use the image_test.module's test toolkit.
       
    26     $this->toolkit = 'test';
       
    27 
       
    28     // Pick a file for testing.
       
    29     $file = current($this->drupalGetTestFiles('image'));
       
    30     $this->file = $file->uri;
       
    31 
       
    32     // Setup a dummy image to work with, this replicate image_load() so we
       
    33     // can avoid calling it.
       
    34     $this->image = new stdClass();
       
    35     $this->image->source = $this->file;
       
    36     $this->image->info = image_get_info($this->file);
       
    37     $this->image->toolkit = $this->toolkit;
       
    38 
       
    39     // Clear out any hook calls.
       
    40     image_test_reset();
       
    41   }
       
    42 
       
    43   /**
       
    44    * Assert that all of the specified image toolkit operations were called
       
    45    * exactly once once, other values result in failure.
       
    46    *
       
    47    * @param $expected
       
    48    *   Array with string containing with the operation name, e.g. 'load',
       
    49    *   'save', 'crop', etc.
       
    50    */
       
    51   function assertToolkitOperationsCalled(array $expected) {
       
    52     // Determine which operations were called.
       
    53     $actual = array_keys(array_filter(image_test_get_all_calls()));
       
    54 
       
    55     // Determine if there were any expected that were not called.
       
    56     $uncalled = array_diff($expected, $actual);
       
    57     if (count($uncalled)) {
       
    58       $this->assertTrue(FALSE, format_string('Expected operations %expected to be called but %uncalled was not called.', array('%expected' => implode(', ', $expected), '%uncalled' => implode(', ', $uncalled))));
       
    59     }
       
    60     else {
       
    61       $this->assertTrue(TRUE, format_string('All the expected operations were called: %expected', array('%expected' => implode(', ', $expected))));
       
    62     }
       
    63 
       
    64     // Determine if there were any unexpected calls.
       
    65     $unexpected = array_diff($actual, $expected);
       
    66     if (count($unexpected)) {
       
    67       $this->assertTrue(FALSE, format_string('Unexpected operations were called: %unexpected.', array('%unexpected' => implode(', ', $unexpected))));
       
    68     }
       
    69     else {
       
    70       $this->assertTrue(TRUE, 'No unexpected operations were called.');
       
    71     }
       
    72   }
       
    73 }
       
    74 
       
    75 /**
       
    76  * Test that the functions in image.inc correctly pass data to the toolkit.
       
    77  */
       
    78 class ImageToolkitUnitTest extends ImageToolkitTestCase {
       
    79   public static function getInfo() {
       
    80     return array(
       
    81       'name' => 'Image toolkit tests',
       
    82       'description' => 'Check image toolkit functions.',
       
    83       'group' => 'Image',
       
    84     );
       
    85   }
       
    86 
       
    87   /**
       
    88    * Check that hook_image_toolkits() is called and only available toolkits are
       
    89    * returned.
       
    90    */
       
    91   function testGetAvailableToolkits() {
       
    92     $toolkits = image_get_available_toolkits();
       
    93     $this->assertTrue(isset($toolkits['test']), 'The working toolkit was returned.');
       
    94     $this->assertFalse(isset($toolkits['broken']), 'The toolkit marked unavailable was not returned');
       
    95     $this->assertToolkitOperationsCalled(array());
       
    96   }
       
    97 
       
    98   /**
       
    99    * Test the image_load() function.
       
   100    */
       
   101   function testLoad() {
       
   102     $image = image_load($this->file, $this->toolkit);
       
   103     $this->assertTrue(is_object($image), 'Returned an object.');
       
   104     $this->assertEqual($this->toolkit, $image->toolkit, 'Image had toolkit set.');
       
   105     $this->assertToolkitOperationsCalled(array('load', 'get_info'));
       
   106   }
       
   107 
       
   108   /**
       
   109    * Test the image_save() function.
       
   110    */
       
   111   function testSave() {
       
   112     $this->assertFalse(image_save($this->image), 'Function returned the expected value.');
       
   113     $this->assertToolkitOperationsCalled(array('save'));
       
   114   }
       
   115 
       
   116   /**
       
   117    * Test the image_resize() function.
       
   118    */
       
   119   function testResize() {
       
   120     $this->assertTrue(image_resize($this->image, 1, 2), 'Function returned the expected value.');
       
   121     $this->assertToolkitOperationsCalled(array('resize'));
       
   122 
       
   123     // Check the parameters.
       
   124     $calls = image_test_get_all_calls();
       
   125     $this->assertEqual($calls['resize'][0][1], 1, 'Width was passed correctly');
       
   126     $this->assertEqual($calls['resize'][0][2], 2, 'Height was passed correctly');
       
   127   }
       
   128 
       
   129   /**
       
   130    * Test the image_scale() function.
       
   131    */
       
   132   function testScale() {
       
   133 // TODO: need to test upscaling
       
   134     $this->assertTrue(image_scale($this->image, 10, 10), 'Function returned the expected value.');
       
   135     $this->assertToolkitOperationsCalled(array('resize'));
       
   136 
       
   137     // Check the parameters.
       
   138     $calls = image_test_get_all_calls();
       
   139     $this->assertEqual($calls['resize'][0][1], 10, 'Width was passed correctly');
       
   140     $this->assertEqual($calls['resize'][0][2], 5, 'Height was based off aspect ratio and passed correctly');
       
   141   }
       
   142 
       
   143   /**
       
   144    * Test the image_scale_and_crop() function.
       
   145    */
       
   146   function testScaleAndCrop() {
       
   147     $this->assertTrue(image_scale_and_crop($this->image, 5, 10), 'Function returned the expected value.');
       
   148     $this->assertToolkitOperationsCalled(array('resize', 'crop'));
       
   149 
       
   150     // Check the parameters.
       
   151     $calls = image_test_get_all_calls();
       
   152 
       
   153     $this->assertEqual($calls['crop'][0][1], 7.5, 'X was computed and passed correctly');
       
   154     $this->assertEqual($calls['crop'][0][2], 0, 'Y was computed and passed correctly');
       
   155     $this->assertEqual($calls['crop'][0][3], 5, 'Width was computed and passed correctly');
       
   156     $this->assertEqual($calls['crop'][0][4], 10, 'Height was computed and passed correctly');
       
   157   }
       
   158 
       
   159   /**
       
   160    * Test the image_rotate() function.
       
   161    */
       
   162   function testRotate() {
       
   163     $this->assertTrue(image_rotate($this->image, 90, 1), 'Function returned the expected value.');
       
   164     $this->assertToolkitOperationsCalled(array('rotate'));
       
   165 
       
   166     // Check the parameters.
       
   167     $calls = image_test_get_all_calls();
       
   168     $this->assertEqual($calls['rotate'][0][1], 90, 'Degrees were passed correctly');
       
   169     $this->assertEqual($calls['rotate'][0][2], 1, 'Background color was passed correctly');
       
   170   }
       
   171 
       
   172   /**
       
   173    * Test the image_crop() function.
       
   174    */
       
   175   function testCrop() {
       
   176     $this->assertTrue(image_crop($this->image, 1, 2, 3, 4), 'Function returned the expected value.');
       
   177     $this->assertToolkitOperationsCalled(array('crop'));
       
   178 
       
   179     // Check the parameters.
       
   180     $calls = image_test_get_all_calls();
       
   181     $this->assertEqual($calls['crop'][0][1], 1, 'X was passed correctly');
       
   182     $this->assertEqual($calls['crop'][0][2], 2, 'Y was passed correctly');
       
   183     $this->assertEqual($calls['crop'][0][3], 3, 'Width was passed correctly');
       
   184     $this->assertEqual($calls['crop'][0][4], 4, 'Height was passed correctly');
       
   185   }
       
   186 
       
   187   /**
       
   188    * Test the image_desaturate() function.
       
   189    */
       
   190   function testDesaturate() {
       
   191     $this->assertTrue(image_desaturate($this->image), 'Function returned the expected value.');
       
   192     $this->assertToolkitOperationsCalled(array('desaturate'));
       
   193 
       
   194     // Check the parameters.
       
   195     $calls = image_test_get_all_calls();
       
   196     $this->assertEqual(count($calls['desaturate'][0]), 1, 'Only the image was passed.');
       
   197   }
       
   198 }
       
   199 
       
   200 /**
       
   201  * Test the core GD image manipulation functions.
       
   202  */
       
   203 class ImageToolkitGdTestCase extends DrupalWebTestCase {
       
   204   // Colors that are used in testing.
       
   205   protected $black       = array(0, 0, 0, 0);
       
   206   protected $red         = array(255, 0, 0, 0);
       
   207   protected $green       = array(0, 255, 0, 0);
       
   208   protected $blue        = array(0, 0, 255, 0);
       
   209   protected $yellow      = array(255, 255, 0, 0);
       
   210   protected $white       = array(255, 255, 255, 0);
       
   211   protected $transparent = array(0, 0, 0, 127);
       
   212   // Used as rotate background colors.
       
   213   protected $fuchsia            = array(255, 0, 255, 0);
       
   214   protected $rotate_transparent = array(255, 255, 255, 127);
       
   215 
       
   216   protected $width = 40;
       
   217   protected $height = 20;
       
   218 
       
   219   public static function getInfo() {
       
   220     return array(
       
   221       'name' => 'Image GD manipulation tests',
       
   222       'description' => 'Check that core image manipulations work properly: scale, resize, rotate, crop, scale and crop, and desaturate.',
       
   223       'group' => 'Image',
       
   224     );
       
   225   }
       
   226 
       
   227   /**
       
   228    * Function to compare two colors by RGBa.
       
   229    */
       
   230   function colorsAreEqual($color_a, $color_b) {
       
   231     // Fully transparent pixels are equal, regardless of RGB.
       
   232     if ($color_a[3] == 127 && $color_b[3] == 127) {
       
   233       return TRUE;
       
   234     }
       
   235 
       
   236     foreach ($color_a as $key => $value) {
       
   237       if ($color_b[$key] != $value) {
       
   238         return FALSE;
       
   239       }
       
   240     }
       
   241 
       
   242     return TRUE;
       
   243   }
       
   244 
       
   245   /**
       
   246    * Function for finding a pixel's RGBa values.
       
   247    */
       
   248   function getPixelColor($image, $x, $y) {
       
   249     $color_index = imagecolorat($image->resource, $x, $y);
       
   250 
       
   251     $transparent_index = imagecolortransparent($image->resource);
       
   252     if ($color_index == $transparent_index) {
       
   253       return array(0, 0, 0, 127);
       
   254     }
       
   255 
       
   256     return array_values(imagecolorsforindex($image->resource, $color_index));
       
   257   }
       
   258 
       
   259   /**
       
   260    * Since PHP can't visually check that our images have been manipulated
       
   261    * properly, build a list of expected color values for each of the corners and
       
   262    * the expected height and widths for the final images.
       
   263    */
       
   264   function testManipulations() {
       
   265     // If GD isn't available don't bother testing this.
       
   266     module_load_include('inc', 'system', 'image.gd');
       
   267     if (!function_exists('image_gd_check_settings') || !image_gd_check_settings()) {
       
   268       $this->pass(t('Image manipulations for the GD toolkit were skipped because the GD toolkit is not available.'));
       
   269       return;
       
   270     }
       
   271 
       
   272     // Typically the corner colors will be unchanged. These colors are in the
       
   273     // order of top-left, top-right, bottom-right, bottom-left.
       
   274     $default_corners = array($this->red, $this->green, $this->blue, $this->transparent);
       
   275 
       
   276     // A list of files that will be tested.
       
   277     $files = array(
       
   278       'image-test.png',
       
   279       'image-test.gif',
       
   280       'image-test-no-transparency.gif',
       
   281       'image-test.jpg',
       
   282     );
       
   283 
       
   284     // Setup a list of tests to perform on each type.
       
   285     $operations = array(
       
   286       'resize' => array(
       
   287         'function' => 'resize',
       
   288         'arguments' => array(20, 10),
       
   289         'width' => 20,
       
   290         'height' => 10,
       
   291         'corners' => $default_corners,
       
   292       ),
       
   293       'scale_x' => array(
       
   294         'function' => 'scale',
       
   295         'arguments' => array(20, NULL),
       
   296         'width' => 20,
       
   297         'height' => 10,
       
   298         'corners' => $default_corners,
       
   299       ),
       
   300       'scale_y' => array(
       
   301         'function' => 'scale',
       
   302         'arguments' => array(NULL, 10),
       
   303         'width' => 20,
       
   304         'height' => 10,
       
   305         'corners' => $default_corners,
       
   306       ),
       
   307       'upscale_x' => array(
       
   308         'function' => 'scale',
       
   309         'arguments' => array(80, NULL, TRUE),
       
   310         'width' => 80,
       
   311         'height' => 40,
       
   312         'corners' => $default_corners,
       
   313       ),
       
   314       'upscale_y' => array(
       
   315         'function' => 'scale',
       
   316         'arguments' => array(NULL, 40, TRUE),
       
   317         'width' => 80,
       
   318         'height' => 40,
       
   319         'corners' => $default_corners,
       
   320       ),
       
   321       'crop' => array(
       
   322         'function' => 'crop',
       
   323         'arguments' => array(12, 4, 16, 12),
       
   324         'width' => 16,
       
   325         'height' => 12,
       
   326         'corners' => array_fill(0, 4, $this->white),
       
   327       ),
       
   328       'scale_and_crop' => array(
       
   329         'function' => 'scale_and_crop',
       
   330         'arguments' => array(10, 8),
       
   331         'width' => 10,
       
   332         'height' => 8,
       
   333         'corners' => array_fill(0, 4, $this->black),
       
   334       ),
       
   335     );
       
   336 
       
   337     // Systems using non-bundled GD2 don't have imagerotate. Test if available.
       
   338     if (function_exists('imagerotate')) {
       
   339       $operations += array(
       
   340         'rotate_90' => array(
       
   341           'function' => 'rotate',
       
   342           'arguments' => array(90, 0xFF00FF), // Fuchsia background.
       
   343           'width' => 20,
       
   344           'height' => 40,
       
   345           'corners' => array($this->fuchsia, $this->red, $this->green, $this->blue),
       
   346         ),
       
   347         'rotate_transparent_90' => array(
       
   348           'function' => 'rotate',
       
   349           'arguments' => array(90),
       
   350           'width' => 20,
       
   351           'height' => 40,
       
   352           'corners' => array($this->transparent, $this->red, $this->green, $this->blue),
       
   353         ),
       
   354       );
       
   355       // As of PHP version 5.5, GD uses a different algorithm to rotate images
       
   356       // than version 5.4 and below, resulting in different dimensions.
       
   357       // See https://bugs.php.net/bug.php?id=65148.
       
   358       // For the 40x20 test images, the dimensions resulting from rotation will
       
   359       // be 1 pixel smaller in both width and height in PHP 5.5 and above.
       
   360       // @todo: If and when the PHP bug gets solved, add an upper limit
       
   361       //   version check.
       
   362       if (version_compare(PHP_VERSION, '5.5', '>=')) {
       
   363         $operations += array(
       
   364           'rotate_5' => array(
       
   365             'function' => 'rotate',
       
   366             'arguments' => array(5, 0xFF00FF), // Fuchsia background.
       
   367             'width' => 41,
       
   368             'height' => 23,
       
   369             'corners' => array_fill(0, 4, $this->fuchsia),
       
   370           ),
       
   371           'rotate_transparent_5' => array(
       
   372             'function' => 'rotate',
       
   373             'arguments' => array(5),
       
   374             'width' => 41,
       
   375             'height' => 23,
       
   376             'corners' => array_fill(0, 4, $this->rotate_transparent),
       
   377           ),
       
   378         );
       
   379       }
       
   380       else {
       
   381         $operations += array(
       
   382           'rotate_5' => array(
       
   383             'function' => 'rotate',
       
   384             'arguments' => array(5, 0xFF00FF), // Fuchsia background.
       
   385             'width' => 42,
       
   386             'height' => 24,
       
   387             'corners' => array_fill(0, 4, $this->fuchsia),
       
   388           ),
       
   389           'rotate_transparent_5' => array(
       
   390             'function' => 'rotate',
       
   391             'arguments' => array(5),
       
   392             'width' => 42,
       
   393             'height' => 24,
       
   394             'corners' => array_fill(0, 4, $this->rotate_transparent),
       
   395           ),
       
   396         );
       
   397       }
       
   398     }
       
   399 
       
   400     // Systems using non-bundled GD2 don't have imagefilter. Test if available.
       
   401     if (function_exists('imagefilter')) {
       
   402       $operations += array(
       
   403         'desaturate' => array(
       
   404           'function' => 'desaturate',
       
   405           'arguments' => array(),
       
   406           'height' => 20,
       
   407           'width' => 40,
       
   408           // Grayscale corners are a bit funky. Each of the corners are a shade of
       
   409           // gray. The values of these were determined simply by looking at the
       
   410           // final image to see what desaturated colors end up being.
       
   411           'corners' => array(
       
   412             array_fill(0, 3, 76) + array(3 => 0),
       
   413             array_fill(0, 3, 149) + array(3 => 0),
       
   414             array_fill(0, 3, 29) + array(3 => 0),
       
   415             array_fill(0, 3, 225) + array(3 => 127)
       
   416           ),
       
   417         ),
       
   418       );
       
   419     }
       
   420 
       
   421     foreach ($files as $file) {
       
   422       foreach ($operations as $op => $values) {
       
   423         // Load up a fresh image.
       
   424         $image = image_load(drupal_get_path('module', 'simpletest') . '/files/' . $file, 'gd');
       
   425         if (!$image) {
       
   426           $this->fail(t('Could not load image %file.', array('%file' => $file)));
       
   427           continue 2;
       
   428         }
       
   429 
       
   430         // All images should be converted to truecolor when loaded.
       
   431         $image_truecolor = imageistruecolor($image->resource);
       
   432         $this->assertTrue($image_truecolor, format_string('Image %file after load is a truecolor image.', array('%file' => $file)));
       
   433 
       
   434         if ($image->info['extension'] == 'gif') {
       
   435           if ($op == 'desaturate') {
       
   436             // Transparent GIFs and the imagefilter function don't work together.
       
   437             $values['corners'][3][3] = 0;
       
   438           }
       
   439         }
       
   440 
       
   441         // Perform our operation.
       
   442         $function = 'image_' . $values['function'];
       
   443         $arguments = array();
       
   444         $arguments[] = &$image;
       
   445         $arguments = array_merge($arguments, $values['arguments']);
       
   446         call_user_func_array($function, $arguments);
       
   447 
       
   448         // To keep from flooding the test with assert values, make a general
       
   449         // value for whether each group of values fail.
       
   450         $correct_dimensions_real = TRUE;
       
   451         $correct_dimensions_object = TRUE;
       
   452         $correct_colors = TRUE;
       
   453 
       
   454         // Check the real dimensions of the image first.
       
   455         if (imagesy($image->resource) != $values['height'] || imagesx($image->resource) != $values['width']) {
       
   456           $correct_dimensions_real = FALSE;
       
   457         }
       
   458 
       
   459         // Check that the image object has an accurate record of the dimensions.
       
   460         if ($image->info['width'] != $values['width'] || $image->info['height'] != $values['height']) {
       
   461           $correct_dimensions_object = FALSE;
       
   462         }
       
   463         // Now check each of the corners to ensure color correctness.
       
   464         foreach ($values['corners'] as $key => $corner) {
       
   465           // The test gif that does not have transparency has yellow where the
       
   466           // others have transparent.
       
   467           if ($file === 'image-test-no-transparency.gif' && $corner === $this->transparent) {
       
   468             $corner = $this->yellow;
       
   469           }
       
   470           // Get the location of the corner.
       
   471           switch ($key) {
       
   472             case 0:
       
   473               $x = 0;
       
   474               $y = 0;
       
   475               break;
       
   476             case 1:
       
   477               $x = $values['width'] - 1;
       
   478               $y = 0;
       
   479               break;
       
   480             case 2:
       
   481               $x = $values['width'] - 1;
       
   482               $y = $values['height'] - 1;
       
   483               break;
       
   484             case 3:
       
   485               $x = 0;
       
   486               $y = $values['height'] - 1;
       
   487               break;
       
   488           }
       
   489           $color = $this->getPixelColor($image, $x, $y);
       
   490           $correct_colors = $this->colorsAreEqual($color, $corner);
       
   491         }
       
   492 
       
   493         $directory = file_default_scheme() . '://imagetests';
       
   494         file_prepare_directory($directory, FILE_CREATE_DIRECTORY);
       
   495         $file_path = $directory . '/' . $op . '.' . $image->info['extension'];
       
   496         image_save($image, $file_path);
       
   497 
       
   498         $this->assertTrue($correct_dimensions_real, format_string('Image %file after %action action has proper dimensions.', array('%file' => $file, '%action' => $op)));
       
   499         $this->assertTrue($correct_dimensions_object, format_string('Image %file object after %action action is reporting the proper height and width values.', array('%file' => $file, '%action' => $op)));
       
   500         // JPEG colors will always be messed up due to compression.
       
   501         if ($image->info['extension'] != 'jpg') {
       
   502           $this->assertTrue($correct_colors, format_string('Image %file object after %action action has the correct color placement.', array('%file' => $file, '%action' => $op)));
       
   503         }
       
   504       }
       
   505 
       
   506       // Check that saved image reloads without raising PHP errors.
       
   507       $image_reloaded = image_load($file_path);
       
   508     }
       
   509   }
       
   510 
       
   511   /**
       
   512    * Tests loading an image whose transparent color index is out of range.
       
   513    */
       
   514   function testTransparentColorOutOfRange() {
       
   515     // This image was generated by taking an initial image with a palette size
       
   516     // of 6 colors, and setting the transparent color index to 6 (one higher
       
   517     // than the largest allowed index), as follows:
       
   518     // @code
       
   519     // $image = imagecreatefromgif('modules/simpletest/files/image-test.gif');
       
   520     // imagecolortransparent($image, 6);
       
   521     // imagegif($image, 'modules/simpletest/files/image-test-transparent-out-of-range.gif');
       
   522     // @endcode
       
   523     // This allows us to test that an image with an out-of-range color index
       
   524     // can be loaded correctly.
       
   525     $file = 'image-test-transparent-out-of-range.gif';
       
   526     $image = image_load(drupal_get_path('module', 'simpletest') . '/files/' . $file);
       
   527 
       
   528     if (!$image) {
       
   529       $this->fail(format_string('Could not load image %file.', array('%file' => $file)));
       
   530     }
       
   531     else {
       
   532       // All images should be converted to truecolor when loaded.
       
   533       $image_truecolor = imageistruecolor($image->resource);
       
   534       $this->assertTrue($image_truecolor, format_string('Image %file after load is a truecolor image.', array('%file' => $file)));
       
   535     }
       
   536   }
       
   537 }
       
   538 
       
   539 /**
       
   540  * Tests the file move function for managed files.
       
   541  */
       
   542 class ImageFileMoveTest extends ImageToolkitTestCase {
       
   543   public static function getInfo() {
       
   544     return array(
       
   545       'name' => 'Image moving',
       
   546       'description' => 'Tests the file move function for managed files.',
       
   547       'group' => 'Image',
       
   548     );
       
   549   }
       
   550 
       
   551   /**
       
   552    * Tests moving a randomly generated image.
       
   553    */
       
   554   function testNormal() {
       
   555     // Pick a file for testing.
       
   556     $file = current($this->drupalGetTestFiles('image'));
       
   557 
       
   558     // Create derivative image.
       
   559     $style = image_style_load(key(image_styles()));
       
   560     $derivative_uri = image_style_path($style['name'], $file->uri);
       
   561     image_style_create_derivative($style, $file->uri, $derivative_uri);
       
   562 
       
   563     // Check if derivative image exists.
       
   564     $this->assertTrue(file_exists($derivative_uri), 'Make sure derivative image is generated successfully.');
       
   565 
       
   566     // Clone the object so we don't have to worry about the function changing
       
   567     // our reference copy.
       
   568     $desired_filepath = 'public://' . $this->randomName();
       
   569     $result = file_move(clone $file, $desired_filepath, FILE_EXISTS_ERROR);
       
   570 
       
   571     // Check if image has been moved.
       
   572     $this->assertTrue(file_exists($result->uri), 'Make sure image is moved successfully.');
       
   573 
       
   574     // Check if derivative image has been flushed.
       
   575     $this->assertFalse(file_exists($derivative_uri), 'Make sure derivative image has been flushed.');
       
   576   }
       
   577 }
       
   578