| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 
 | // Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/enhanced_bookmarks/image_store.h"
#import <UIKit/UIKit.h>
#include "base/files/scoped_temp_dir.h"
#include "base/mac/scoped_cftyperef.h"
#include "components/enhanced_bookmarks/image_store_util.h"
#include "components/enhanced_bookmarks/persistent_image_store.h"
#include "components/enhanced_bookmarks/test_image_store.h"
#include "testing/platform_test.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/image/image.h"
#include "url/gurl.h"
namespace {
// Generates a gfx::Image with a random UIImage representation. Uses off-center
// circle gradient to make all pixels slightly different in order to detect
// small image alterations.
gfx::Image GenerateRandomUIImage(gfx::Size& size, float scale) {
  UIGraphicsBeginImageContextWithOptions(CGSizeMake(size.width(),
                                                    size.height()),
                                         YES,  // opaque.
                                         scale);
  // Create the gradient's colors.
  CGFloat locations[] = { 0.0, 1.0 };
  CGFloat components[] = { rand()/CGFloat(RAND_MAX),  // Start color r
                           rand()/CGFloat(RAND_MAX),  // g
                           rand()/CGFloat(RAND_MAX),  // b
                           1.0,                       // Alpha
                           rand()/CGFloat(RAND_MAX),  // End color r
                           rand()/CGFloat(RAND_MAX),  // g
                           rand()/CGFloat(RAND_MAX),  // b
                           1.0 };                     // Alpha
  CGPoint center = CGPointMake(size.width() / 3, size.height() / 3);
  CGFloat radius = MAX(size.width(), size.height());
  base::ScopedCFTypeRef<CGColorSpaceRef>
      colorspace(CGColorSpaceCreateDeviceRGB());
  base::ScopedCFTypeRef<CGGradientRef>
      gradient(CGGradientCreateWithColorComponents(colorspace,
                                                   components,
                                                   locations,
                                                   arraysize(locations)));
  CGContextDrawRadialGradient(UIGraphicsGetCurrentContext(),
                              gradient,
                              center,
                              0,
                              center,
                              radius,
                              kCGGradientDrawsAfterEndLocation);
  UIImage* image = UIGraphicsGetImageFromCurrentImageContext();
  UIGraphicsEndImageContext();
  return gfx::Image([image retain]);
}
// Returns true if the two images are identical.
bool CompareImages(const gfx::Image& image_1, const gfx::Image& image_2) {
  if (image_1.IsEmpty() && image_2.IsEmpty())
    return true;
  if (image_1.IsEmpty() || image_2.IsEmpty())
    return false;
  scoped_refptr<base::RefCountedMemory> image_1_bytes =
      enhanced_bookmarks::BytesForImage(image_1);
  scoped_refptr<base::RefCountedMemory> image_2_bytes =
      enhanced_bookmarks::BytesForImage(image_2);
  if (image_1_bytes->size() != image_2_bytes->size())
    return false;
  return !memcmp(image_1_bytes->front(),
                 image_2_bytes->front(),
                 image_1_bytes->size());
}
// Factory functions for creating instances of the implementations.
template <class T>
ImageStore* CreateStore(base::ScopedTempDir& folder);
template <>
ImageStore* CreateStore<TestImageStore>(
    base::ScopedTempDir& folder) {
  return new TestImageStore();
}
template <>
ImageStore* CreateStore<PersistentImageStore>(
    base::ScopedTempDir& folder) {
  return new PersistentImageStore(folder.path());
}
// Methods to check if persistence is on or not.
template <class T> bool ShouldPersist();
template <> bool ShouldPersist<TestImageStore>() { return false; }
template <> bool ShouldPersist<PersistentImageStore>() { return true; }
// Test fixture class template for the abstract API.
template <class T>
class ImageStoreUnitTestIOS : public PlatformTest {
 protected:
  ImageStoreUnitTestIOS() {}
  virtual ~ImageStoreUnitTestIOS() {}
  virtual void SetUp() override {
    bool success = temp_dir_.CreateUniqueTempDir();
    ASSERT_TRUE(success);
    store_.reset(CreateStore<T>(temp_dir_));
  }
  virtual void TearDown() override {
    if (store_ && use_persistent_store())
      store_->ClearAll();
  }
  bool use_persistent_store() const { return ShouldPersist<T>(); }
  void ResetStore() { store_.reset(CreateStore<T>(temp_dir_)); }
  // The directory the database is saved into.
  base::ScopedTempDir temp_dir_;
  // The object the fixture is testing, via its base interface.
  scoped_ptr<ImageStore> store_;
 private:
  DISALLOW_COPY_AND_ASSIGN(ImageStoreUnitTestIOS);
};
// The list of implementations of the abstract API that are going to be tested.
typedef testing::Types<TestImageStore,
                       PersistentImageStore> Implementations;
TYPED_TEST_CASE(ImageStoreUnitTestIOS, Implementations);
TYPED_TEST(ImageStoreUnitTestIOS, StoringImagesPreservesScale) {
  CGFloat scales[] = { 0.0, 1.0, 2.0 };
  gfx::Size image_size(42, 24);
  for (unsigned long i = 0; i < arraysize(scales); i++) {
    gfx::Image src_image(GenerateRandomUIImage(image_size, scales[i]));
    const GURL url("foo://bar");
    const GURL image_url("a.jpg");
    this->store_->Insert(url, image_url, src_image);
    std::pair<gfx::Image, GURL> image_info = this->store_->Get(url);
    EXPECT_EQ(image_url, image_info.second);
    EXPECT_TRUE(CompareImages(src_image, image_info.first));
  }
}
}  // namespace
 |