forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
BUG=None TBR=blundell@chromium.com Review URL: https://codereview.chromium.org/347513003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@278482 0039d316-1c4b-4281-b951-d872f2087c98
- Loading branch information
noyau@chromium.org
committed
Jun 19, 2014
1 parent
5f71a37
commit cad4d0d
Showing
5 changed files
with
224 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
153 changes: 153 additions & 0 deletions
153
components/enhanced_bookmarks/image_store_ios_unittest.mm
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
// 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_util.h" | ||
|
||
#import <UIKit/UIKit.h> | ||
|
||
#include "base/mac/scoped_cftyperef.h" | ||
#include "base/mac/scoped_nsobject.h" | ||
|
||
namespace { | ||
// An implementation of RefCountedMemory, where the bytes are stored in a | ||
// NSData. This class assumes the NSData is non mutable to avoid a copy. | ||
class RefCountedNSDataMemory : public base::RefCountedMemory { | ||
public: | ||
explicit RefCountedNSDataMemory(NSData* memory) : data_([memory retain]) {} | ||
|
||
virtual const unsigned char* front() const OVERRIDE { | ||
return reinterpret_cast<const unsigned char*>([data_ bytes]); | ||
} | ||
|
||
virtual size_t size() const OVERRIDE { | ||
return [data_ length]; | ||
} | ||
|
||
private: | ||
virtual ~RefCountedNSDataMemory() {} | ||
|
||
base::scoped_nsobject<NSData> data_; | ||
DISALLOW_COPY_AND_ASSIGN(RefCountedNSDataMemory); | ||
}; | ||
} // namespace | ||
|
||
namespace enhanced_bookmarks { | ||
|
||
// Encodes the UIImage representation of a gfx::Image. | ||
scoped_refptr<base::RefCountedMemory> BytesForImage(const gfx::Image& image) { | ||
DCHECK(image.HasRepresentation(gfx::Image::kImageRepCocoaTouch)); | ||
return scoped_refptr<RefCountedNSDataMemory>(new RefCountedNSDataMemory( | ||
[NSKeyedArchiver archivedDataWithRootObject:image.ToUIImage()])); | ||
} | ||
|
||
// Decodes the UIImage in the bytes and returns a gfx::Image. | ||
gfx::Image ImageForBytes(const scoped_refptr<base::RefCountedMemory>& data) { | ||
return gfx::Image([[NSKeyedUnarchiver unarchiveObjectWithData: | ||
[NSData dataWithBytes:data->front() length:data->size()]] retain]); | ||
} | ||
|
||
} // namespace enhanced_bookmarks |