FBRetainCycleDetectorTests/FBBlockStrongLayoutTests.mm (71 lines of code) (raw):

/** * Copyright (c) 2016-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. */ #import <memory> #import <unordered_map> #import <vector> #import <XCTest/XCTest.h> #import <FBRetainCycleDetector/FBBlockStrongLayout.h> #import <FBRetainCycleDetector/FBRetainCycleUtils.h> @interface FBBlockStrongLayoutTests : XCTestCase @end @implementation FBBlockStrongLayoutTests - (void)testBlockDoesntRetainWeakReference { __attribute__((objc_precise_lifetime)) NSObject *object = [NSObject new]; __weak NSObject *weakObject = object; void (^block)() = ^{ __unused NSObject *someObject = weakObject; }; NSArray *retainedObjects = FBGetBlockStrongReferences((__bridge void *)(block)); XCTAssertEqual([retainedObjects count], 0); } - (void)testBlockRetainsStrongReference { NSObject *object = [NSObject new]; void (^block)() = ^{ __unused NSObject *someObject = object; }; NSArray *retainedObjects = FBGetBlockStrongReferences((__bridge void *)(block)); XCTAssertEqual([retainedObjects count], 1); XCTAssertEqualObjects(retainedObjects[0], object); } - (void)testThatBlockRetainingVectorOfObjectsDoNotCrash { NSObject *object = [NSObject new]; std::vector<id> vector = {object}; void (^block)() = ^{ __unused std::vector<id> someVector = vector; }; NSArray *retainedObjects = FBGetBlockStrongReferences((__bridge void *)(block)); XCTAssertEqual([retainedObjects count], 0); } - (void)testThatBlockRetainingVectorOfStructsDoNotCrash { struct HelperStruct {}; std::vector<HelperStruct> vector = {}; void (^block)() = ^{ __unused std::vector<HelperStruct> someVector = vector; }; NSArray *retainedObjects = FBGetBlockStrongReferences((__bridge void *)(block)); XCTAssertEqual([retainedObjects count], 0); } - (void)testThatBlockUsingCppButRetainingOnlyObjectsWillReturnTheObjectAndNotCrash { NSObject *object = [NSObject new]; void (^block)() = ^{ std::vector<id> vector; vector.push_back(object); }; NSArray *retainedObjects = FBGetBlockStrongReferences((__bridge void *)(block)); XCTAssertEqual([retainedObjects count], 1); XCTAssertEqualObjects(retainedObjects[0], object); } - (void)testThatBlockRetainingMapWillNotCrash { struct HelperStruct{}; std::unordered_map<int, HelperStruct> map; void (^block)() = ^{ __unused std::unordered_map<int, HelperStruct> someMap = map; }; NSArray *retainedObjects = FBGetBlockStrongReferences((__bridge void *)(block)); XCTAssertEqual([retainedObjects count], 0); } @end