Chromium Code Reviews| Index: ios/chrome/common/block_unittest.mm |
| diff --git a/ios/chrome/common/block_unittest.mm b/ios/chrome/common/block_unittest.mm |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..7822bc3c8204d1b90ce9e35514332bc4f124e3d4 |
| --- /dev/null |
| +++ b/ios/chrome/common/block_unittest.mm |
| @@ -0,0 +1,100 @@ |
| +// Copyright (c) 2012 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. |
| + |
| +#import <Foundation/Foundation.h> |
| +#include <vector> |
| + |
| +#include "base/memory/ref_counted.h" |
| +#include "testing/platform_test.h" |
| + |
| +// This test verifies assumptions about the murky world of interaction between |
| +// C++ objects and blocks. Just to make sure. |
| + |
| +namespace { |
| + |
| +class RefCountedObject : public base::RefCounted<RefCountedObject> { |
| + public: |
| + RefCountedObject(){}; |
|
sdefresne
2016/11/07 13:54:57
Remove trailing semi-colon ...
rohitrao (ping after 24h)
2016/11/07 14:04:05
Done.
|
| + |
| + // Refcount is private in the superclass, fake it by counting how many times |
| + // release can be called until there is one count left, then retain the count |
| + // back. |
| + int refcount() { |
| + int count = 1; |
| + while (!HasOneRef()) { |
| + bool check = base::subtle::RefCountedBase::Release(); |
| + EXPECT_FALSE(check); |
| + ++count; |
| + } |
| + for (int ii = 1; ii < count; ii++) |
|
sdefresne
2016/11/07 13:54:57
nit: why "ii" and not "i"?
rohitrao (ping after 24h)
2016/11/07 14:04:05
I tend to use "ii" because it doesn't commonly occ
|
| + base::subtle::RefCountedBase::AddRef(); |
| + return count; |
| + } |
| + |
| + protected: |
| + friend base::RefCounted<RefCountedObject>; |
| + virtual ~RefCountedObject(){}; |
|
sdefresne
2016/11/07 13:54:57
Remove trailing semi-colon ...
rohitrao (ping after 24h)
2016/11/07 14:04:05
Done.
|
| +}; |
| + |
| +TEST_F(PlatformTest, BlockAndCPlusPlus) { |
| + RefCountedObject* object = new RefCountedObject(); |
| + object->AddRef(); |
| + EXPECT_TRUE(object->HasOneRef()); |
| + EXPECT_EQ(1, object->refcount()); |
| + |
| + { |
| + scoped_refptr<RefCountedObject> object_test_ptr(object); |
| + EXPECT_EQ(2, object->refcount()); |
| + } |
| + EXPECT_TRUE(object->HasOneRef()); |
| + |
| + void (^heap_block)(int) = 0; |
| + { |
| + scoped_refptr<RefCountedObject> object_ptr(object); |
| + EXPECT_EQ(2, object->refcount()); |
| + void* object_void_ptr = (void*)object; |
| + |
| + void (^stack_block)(int) = ^(int expected) { |
| + EXPECT_EQ(object_void_ptr, object_ptr.get()); |
| + EXPECT_EQ(expected, object_ptr.get()->refcount()); |
| + }; |
| + stack_block(3); |
| + heap_block = [stack_block copy]; |
| + stack_block(4); |
| + } |
| + heap_block(2); |
| + [heap_block release]; |
| + EXPECT_TRUE(object->HasOneRef()); |
| + { |
| + scoped_refptr<RefCountedObject> object_test2_ptr(object); |
| + EXPECT_EQ(2, object->refcount()); |
| + } |
| + EXPECT_TRUE(object->HasOneRef()); |
| + object->Release(); |
| +} |
| + |
| +TEST_F(PlatformTest, BlockAndVectors) { |
| + void (^heap_block)(void) = 0; |
| + { |
| + std::vector<int> vector; |
| + vector.push_back(0); |
| + vector.push_back(1); |
| + vector.push_back(2); |
| + |
| + void (^stack_block)(void) = ^{ |
| + EXPECT_EQ(3ul, vector.size()); |
| + EXPECT_EQ(2, vector[2]); |
| + }; |
| + stack_block(); |
| + vector[2] = 42; |
| + vector.push_back(22); |
| + stack_block(); |
| + heap_block = [stack_block copy]; |
| + stack_block(); |
| + } |
| + heap_block(); |
| + [heap_block release]; |
| +} |
| + |
| +} // namespace |