Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 149 lines (123 sloc) 4.624 kB
5bf56cf @macrotis Use plblockimp to provide imp_implementationWithBlock() for OS X 10.6…
macrotis authored
1 /*
2 * Author: Landon Fuller <landonf@plausible.coop>
3 *
4 * Copyright 2010-2011 Plausible Labs Cooperative, Inc.
5 * All rights reserved.
6 *
7 * Permission is hereby granted, free of charge,
8 * to any person obtaining a copy of this software and associated documentation
9 * files (the "Software"), to deal in the Software without restriction,
10 * including without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sublicense, and/or sell copies of the Software, and to permit
12 * persons to whom the Software is furnished to do so, subject to the following
13 * conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 * SOFTWARE.
25 */
26
27 #import "GTMSenTestCase.h"
28 #import "blockimp.h"
29
30 @interface BlockIMPTests : SenTestCase @end
31
32 /**
33 * BlockIMP Tests
34 */
35 @implementation BlockIMPTests
36
37 /**
38 * Test basic IMP allocation and execution.
39 */
40 - (void) testAllocateIMP {
41 /* A test block */
42 __block BOOL didRun = NO;
43 void (^Block)(id self) = ^(id blockself) {
44 didRun = YES;
45
46 STAssertEqualObjects(blockself, self, @"Incorrect 'self' pointer");
47 };
48
49 /* Create the IMP */
50 IMP imp = pl_imp_implementationWithBlock(Block);
51 STAssertTrue(imp != NULL, @"Returned NULL IMP");
52
53 /* Verify the IMP is valid. */
54 void (*ptr)(id self, SEL _cmd) = (void *) imp;
55 ptr(self, @selector(testAllocateIMP));
56 STAssertTrue(didRun, @"Block was not run");
57
58 /* Clean up */
59 pl_imp_removeBlock(imp);
60 }
61
62 /**
63 * Test basic stret IMP allocation and execution.
64 */
65 - (void) testAllocateStretIMP {
66 /* A test block */
67 __block BOOL didRun = NO;
68 NSRange (^Block)(id self) = ^NSRange (id blockself) {
69 didRun = YES;
70
71 STAssertEqualObjects(blockself, self, @"Incorrect 'self' pointer");
72 return NSMakeRange(42, 1);
73 };
74
75 /* Create the IMP */
76 IMP imp = pl_imp_implementationWithBlock(Block);
77 STAssertTrue(imp != NULL, @"Returned NULL IMP");
78
79 /* Verify the IMP is valid. */
80 NSRange (*ptr)(id self, SEL _cmd) = (void *) imp;
81 NSRange result = ptr(self, @selector(testAllocateStretIMP));
82
83 STAssertTrue(didRun, @"Block was not run");
84 STAssertEquals(result.location, (NSUInteger)42, @"Incorrect location");
85 STAssertEquals(result.length, (NSUInteger)1, @"Incorrect length");
86
87 /* Clean up */
88 pl_imp_removeBlock(imp);
89 }
90
91 /**
92 * Test fetching of the Block ptr from the IMP pointer.
93 */
94 - (void) testGetBlock {
95 /* A test block */
96 void (^Block)(id self) = [[^(id blockself) {
97 STAssertEqualObjects(blockself, self, @"Incorrect 'self' pointer");
98 } copy] autorelease];
99
100 /* Create the IMP */
101 IMP imp = pl_imp_implementationWithBlock(Block);
102 STAssertTrue(imp != NULL, @"Returned NULL IMP");
103
104 /* Try to fetch the underlying block */
105 void *b = pl_imp_getBlock(imp);
106 STAssertEquals(b, (void *) Block, @"Did not fetch block");
107
108 /* Clean up */
109 pl_imp_removeBlock(imp);
110 }
111
112 /**
113 * Exercise block allocation
114 */
115 - (void) testAllocationExcercise {
116 /* A test block */
117 __block int callCount = 0;
118 void (^Block)(id self) = [[^(id blockself) {
119 callCount++;
120 STAssertEqualObjects(blockself, self, @"Incorrect 'self' pointer");
121 } copy] autorelease];
122
123 /* Use a count larger than what a single page (on any architecture) can likely hold */
124 int count=PAGE_SIZE*2;
125
126 /* Generate the IMPs */
127 IMP *imps = malloc(sizeof(IMP) * count);
128 for (int i = 0; i < count; i++) {
129 imps[i] = pl_imp_implementationWithBlock(Block);
130 }
131
132 /* Call the IMPs */
133 for (int i = 0; i < count; i++) {
134 void (*ptr)(id self, SEL _cmd) = (void *) imps[i];
135 ptr(self, @selector(testAllocationExcercise));
136 }
137
138 /* Clean up the IMPs. We do this in reverse to exercise table reordering. */
139 for (int i = count-1; i+1 >= 1; i--) {
140 pl_imp_removeBlock(imps[i]);
141 }
142 free(imps);
143
144 /* Verify the result */
145 STAssertEquals(callCount, count, @"Call count does not match expected count; not all IMPs were called");
146 }
147
148 @end
Something went wrong with that request. Please try again.