forked from realm/realm-swift
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRLMTestCase.m
181 lines (152 loc) · 5.48 KB
/
RLMTestCase.m
1
2
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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
////////////////////////////////////////////////////////////////////////////
//
// Copyright 2014 Realm Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////
#import "RLMTestCase.h"
#import <Realm/RLMRealm_Private.h>
@interface RLMRealm ()
+ (instancetype)realmWithPath:(NSString *)path
key:(NSData *)key
readOnly:(BOOL)readonly
inMemory:(BOOL)inMemory
dynamic:(BOOL)dynamic
schema:(RLMSchema *)customSchema
error:(NSError **)outError;
+ (void)resetRealmState;
@end
// This ensures the shared schema is initialized outside of of a test case,
// so if an exception is thrown, it will kill the test process rather than
// allowing hundreds of test cases to fail in strange ways
__attribute((constructor))
static void initializeSharedSchema() {
[RLMSchema class];
}
NSString *RLMRealmPathForFile(NSString *fileName) {
#if TARGET_OS_IPHONE
NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
#else
NSString *path = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES)[0];
path = [path stringByAppendingPathComponent:[[[NSBundle mainBundle] executablePath] lastPathComponent]];
#endif
return [path stringByAppendingPathComponent:fileName];
}
NSString *RLMDefaultRealmPath() {
return RLMRealmPathForFile(@"default.realm");
}
NSString *RLMTestRealmPath() {
return RLMRealmPathForFile(@"test.realm");
}
static void deleteOrThrow(NSString *path) {
NSError *error;
if (![[NSFileManager defaultManager] removeItemAtPath:path error:&error]) {
if (error.code != NSFileNoSuchFileError) {
@throw [NSException exceptionWithName:@"RLMTestException"
reason:[@"Unable to delete realm: " stringByAppendingString:error.description]
userInfo:nil];
}
}
}
NSData *RLMGenerateKey() {
uint8_t buffer[64];
SecRandomCopyBytes(kSecRandomDefault, 64, buffer);
return [[NSData alloc] initWithBytes:buffer length:sizeof(buffer)];
}
static BOOL encryptTests() {
static BOOL encryptAll = NO;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
if (getenv("REALM_ENCRYPT_ALL")) {
encryptAll = YES;
}
});
return encryptAll;
}
@implementation RLMTestCase
#if DEBUG || !TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
+ (void)setUp {
[super setUp];
// Disable actually syncing anything to the disk to greatly speed up the
// tests, but only when not running on device because it can't be
// re-enabled and we need it enabled for performance tests
RLMDisableSyncToDisk();
}
#endif
- (void)setUp {
@autoreleasepool {
[super setUp];
[self deleteFiles];
if (encryptTests()) {
[RLMRealm setEncryptionKey:RLMGenerateKey() forRealmsAtPath:RLMDefaultRealmPath()];
[RLMRealm setEncryptionKey:RLMGenerateKey() forRealmsAtPath:RLMTestRealmPath()];
}
}
}
- (void)tearDown {
@autoreleasepool {
[super tearDown];
[self deleteFiles];
}
}
- (void)deleteFiles {
// Clear cache
[RLMRealm resetRealmState];
// Delete Realm files
[self deleteRealmFileAtPath:RLMDefaultRealmPath()];
[self deleteRealmFileAtPath:RLMTestRealmPath()];
}
- (void)deleteRealmFileAtPath:(NSString *)path
{
deleteOrThrow(path);
deleteOrThrow([path stringByAppendingString:@".lock"]);
deleteOrThrow([path stringByAppendingString:@".note"]);
}
- (void)invokeTest {
@autoreleasepool {
[super invokeTest];
}
}
- (RLMRealm *)realmWithTestPath
{
return [RLMRealm realmWithPath:RLMTestRealmPath() readOnly:NO error:nil];
}
- (RLMRealm *)realmWithTestPathAndSchema:(RLMSchema *)schema {
return [RLMRealm realmWithPath:RLMTestRealmPath() key:nil readOnly:NO inMemory:NO dynamic:YES schema:schema error:nil];
}
- (void)waitForNotification:(NSString *)expectedNote realm:(RLMRealm *)realm block:(dispatch_block_t)block {
XCTestExpectation *notificationFired = [self expectationWithDescription:@"notification fired"];
RLMNotificationToken *token = [realm addNotificationBlock:^(NSString *note, RLMRealm *realm) {
XCTAssertNotNil(note, @"Note should not be nil");
XCTAssertNotNil(realm, @"Realm should not be nil");
if (note == expectedNote) { // Check pointer equality to ensure we're using the interned string constant
[notificationFired fulfill];
}
}];
dispatch_queue_t queue = dispatch_queue_create("background", 0);
dispatch_async(queue, ^{
@autoreleasepool {
block();
}
});
[self waitForExpectationsWithTimeout:2.0 handler:nil];
// wait for queue to finish
dispatch_sync(queue, ^{});
[realm removeNotification:token];
}
- (id)nonLiteralNil
{
return nil;
}
@end