ObjectInterfaceTests.m 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579
  1. ////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright 2014 Realm Inc.
  4. //
  5. // Licensed under the Apache License, Version 2.0 (the "License");
  6. // you may not use this file except in compliance with the License.
  7. // You may obtain a copy of the License at
  8. //
  9. // http://www.apache.org/licenses/LICENSE-2.0
  10. //
  11. // Unless required by applicable law or agreed to in writing, software
  12. // distributed under the License is distributed on an "AS IS" BASIS,
  13. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. // See the License for the specific language governing permissions and
  15. // limitations under the License.
  16. //
  17. ////////////////////////////////////////////////////////////////////////////
  18. #import "RLMTestCase.h"
  19. #pragma mark - Test Objects
  20. @interface PrimaryKeyWithLinkObject : RLMObject
  21. @property NSString *primaryKey;
  22. @property StringObject *string;
  23. @end
  24. @implementation PrimaryKeyWithLinkObject
  25. + (NSString *)primaryKey {
  26. return @"primaryKey";
  27. }
  28. @end
  29. #pragma mark - Tests
  30. @interface ObjectInterfaceTests : RLMTestCase
  31. @end
  32. @implementation ObjectInterfaceTests
  33. - (void)testCustomAccessorsObject {
  34. RLMRealm *realm = [RLMRealm defaultRealm];
  35. [realm beginWriteTransaction];
  36. CustomAccessorsObject *ca = [CustomAccessorsObject createInRealm:realm withValue:@[@"name", @2]];
  37. XCTAssertEqualObjects(ca.name, @"name");
  38. XCTAssertEqualObjects([ca getThatName], @"name");
  39. XCTAssertEqual(ca.age, 2);
  40. XCTAssertEqual([ca age], 2);
  41. [ca setTheInt:99];
  42. XCTAssertEqual(ca.age, 99);
  43. XCTAssertEqual([ca age], 99);
  44. [realm cancelWriteTransaction];
  45. }
  46. - (void)testClassExtension {
  47. RLMRealm *realm = [RLMRealm defaultRealm];
  48. [realm beginWriteTransaction];
  49. BaseClassStringObject *bObject = [[BaseClassStringObject alloc ] init];
  50. bObject.intCol = 1;
  51. bObject.stringCol = @"stringVal";
  52. [realm addObject:bObject];
  53. [realm commitWriteTransaction];
  54. BaseClassStringObject *objectFromRealm = [BaseClassStringObject allObjects][0];
  55. XCTAssertEqual(1, objectFromRealm.intCol, @"Should be 1");
  56. XCTAssertEqualObjects(@"stringVal", objectFromRealm.stringCol, @"Should be stringVal");
  57. }
  58. - (void)testNSNumberProperties {
  59. NumberObject *obj = [NumberObject new];
  60. obj.intObj = @20;
  61. obj.floatObj = @0.7f;
  62. obj.doubleObj = @33.3;
  63. obj.boolObj = @YES;
  64. XCTAssertEqualObjects(@20, obj.intObj);
  65. XCTAssertEqualObjects(@0.7f, obj.floatObj);
  66. XCTAssertEqualObjects(@33.3, obj.doubleObj);
  67. XCTAssertEqualObjects(@YES, obj.boolObj);
  68. RLMRealm *realm = [RLMRealm defaultRealm];
  69. [realm beginWriteTransaction];
  70. [realm addObject:obj];
  71. [realm commitWriteTransaction];
  72. XCTAssertEqualObjects(@20, obj.intObj);
  73. XCTAssertEqualObjects(@0.7f, obj.floatObj);
  74. XCTAssertEqualObjects(@33.3, obj.doubleObj);
  75. XCTAssertEqualObjects(@YES, obj.boolObj);
  76. }
  77. - (void)testOptionalStringProperties {
  78. RLMRealm *realm = [RLMRealm defaultRealm];
  79. StringObject *so = [[StringObject alloc] init];
  80. XCTAssertNil(so.stringCol);
  81. XCTAssertNil([so valueForKey:@"stringCol"]);
  82. XCTAssertNil(so[@"stringCol"]);
  83. so.stringCol = @"a";
  84. XCTAssertEqualObjects(so.stringCol, @"a");
  85. XCTAssertEqualObjects([so valueForKey:@"stringCol"], @"a");
  86. XCTAssertEqualObjects(so[@"stringCol"], @"a");
  87. [so setValue:nil forKey:@"stringCol"];
  88. XCTAssertNil(so.stringCol);
  89. XCTAssertNil([so valueForKey:@"stringCol"]);
  90. XCTAssertNil(so[@"stringCol"]);
  91. [realm transactionWithBlock:^{
  92. [realm addObject:so];
  93. XCTAssertNil(so.stringCol);
  94. XCTAssertNil([so valueForKey:@"stringCol"]);
  95. XCTAssertNil(so[@"stringCol"]);
  96. }];
  97. so = [StringObject allObjectsInRealm:realm].firstObject;
  98. XCTAssertNil(so.stringCol);
  99. XCTAssertNil([so valueForKey:@"stringCol"]);
  100. XCTAssertNil(so[@"stringCol"]);
  101. [realm transactionWithBlock:^{
  102. so.stringCol = @"b";
  103. }];
  104. XCTAssertEqualObjects(so.stringCol, @"b");
  105. XCTAssertEqualObjects([so valueForKey:@"stringCol"], @"b");
  106. XCTAssertEqualObjects(so[@"stringCol"], @"b");
  107. [realm transactionWithBlock:^{
  108. so.stringCol = @"";
  109. }];
  110. XCTAssertEqualObjects(so.stringCol, @"");
  111. XCTAssertEqualObjects([so valueForKey:@"stringCol"], @"");
  112. XCTAssertEqualObjects(so[@"stringCol"], @"");
  113. }
  114. - (void)testOptionalBinaryProperties {
  115. RLMRealm *realm = [RLMRealm defaultRealm];
  116. BinaryObject *bo = [[BinaryObject alloc] init];
  117. XCTAssertNil(bo.binaryCol);
  118. XCTAssertNil([bo valueForKey:@"binaryCol"]);
  119. XCTAssertNil(bo[@"binaryCol"]);
  120. NSData *aData = [@"a" dataUsingEncoding:NSUTF8StringEncoding];
  121. bo.binaryCol = aData;
  122. XCTAssertEqualObjects(bo.binaryCol, aData);
  123. XCTAssertEqualObjects([bo valueForKey:@"binaryCol"], aData);
  124. XCTAssertEqualObjects(bo[@"binaryCol"], aData);
  125. [bo setValue:nil forKey:@"binaryCol"];
  126. XCTAssertNil(bo.binaryCol);
  127. XCTAssertNil([bo valueForKey:@"binaryCol"]);
  128. XCTAssertNil(bo[@"binaryCol"]);
  129. [realm transactionWithBlock:^{
  130. [realm addObject:bo];
  131. XCTAssertNil(bo.binaryCol);
  132. XCTAssertNil([bo valueForKey:@"binaryCol"]);
  133. XCTAssertNil(bo[@"binaryCol"]);
  134. }];
  135. bo = [BinaryObject allObjectsInRealm:realm].firstObject;
  136. XCTAssertNil(bo.binaryCol);
  137. XCTAssertNil([bo valueForKey:@"binaryCol"]);
  138. XCTAssertNil(bo[@"binaryCol"]);
  139. NSData *bData = [@"b" dataUsingEncoding:NSUTF8StringEncoding];
  140. [realm transactionWithBlock:^{
  141. bo.binaryCol = bData;
  142. }];
  143. XCTAssertEqualObjects(bo.binaryCol, bData);
  144. XCTAssertEqualObjects([bo valueForKey:@"binaryCol"], bData);
  145. XCTAssertEqualObjects(bo[@"binaryCol"], bData);
  146. NSData *emptyData = [NSData data];
  147. [realm transactionWithBlock:^{
  148. bo.binaryCol = emptyData;
  149. }];
  150. XCTAssertEqualObjects(bo.binaryCol, emptyData);
  151. XCTAssertEqualObjects([bo valueForKey:@"binaryCol"], emptyData);
  152. XCTAssertEqualObjects(bo[@"binaryCol"], emptyData);
  153. }
  154. - (void)testOptionalNumberProperties {
  155. void (^assertNullProperties)(NumberObject *) = ^(NumberObject *no){
  156. XCTAssertNil(no.intObj);
  157. XCTAssertNil(no.doubleObj);
  158. XCTAssertNil(no.floatObj);
  159. XCTAssertNil(no.boolObj);
  160. XCTAssertNil([no valueForKey:@"intObj"]);
  161. XCTAssertNil([no valueForKey:@"doubleObj"]);
  162. XCTAssertNil([no valueForKey:@"floatObj"]);
  163. XCTAssertNil([no valueForKey:@"boolObj"]);
  164. XCTAssertNil(no[@"intObj"]);
  165. XCTAssertNil(no[@"doubleObj"]);
  166. XCTAssertNil(no[@"floatObj"]);
  167. XCTAssertNil(no[@"boolObj"]);
  168. };
  169. void (^assertNonNullProperties)(NumberObject *) = ^(NumberObject *no){
  170. XCTAssertEqualObjects(no.intObj, @1);
  171. XCTAssertEqualObjects(no.doubleObj, @1.1);
  172. XCTAssertEqualObjects(no.floatObj, @2.2f);
  173. XCTAssertEqualObjects(no.boolObj, @YES);
  174. XCTAssertEqualObjects([no valueForKey:@"intObj"], @1);
  175. XCTAssertEqualObjects([no valueForKey:@"doubleObj"], @1.1);
  176. XCTAssertEqualObjects([no valueForKey:@"floatObj"], @2.2f);
  177. XCTAssertEqualObjects([no valueForKey:@"boolObj"], @YES);
  178. XCTAssertEqualObjects(no[@"intObj"], @1);
  179. XCTAssertEqualObjects(no[@"doubleObj"], @1.1);
  180. XCTAssertEqualObjects(no[@"floatObj"], @2.2f);
  181. XCTAssertEqualObjects(no[@"boolObj"], @YES);
  182. };
  183. RLMRealm *realm = [RLMRealm defaultRealm];
  184. NumberObject *no = [[NumberObject alloc] init];
  185. assertNullProperties(no);
  186. no.intObj = @1;
  187. no.doubleObj = @1.1;
  188. no.floatObj = @2.2f;
  189. no.boolObj = @YES;
  190. assertNonNullProperties(no);
  191. no.intObj = nil;
  192. no.doubleObj = nil;
  193. no.floatObj = nil;
  194. no.boolObj = nil;
  195. assertNullProperties(no);
  196. no[@"intObj"] = @1;
  197. no[@"doubleObj"] = @1.1;
  198. no[@"floatObj"] = @2.2f;
  199. no[@"boolObj"] = @YES;
  200. assertNonNullProperties(no);
  201. no.intObj = nil;
  202. no.doubleObj = nil;
  203. no.floatObj = nil;
  204. no.boolObj = nil;
  205. [realm transactionWithBlock:^{
  206. [realm addObject:no];
  207. assertNullProperties(no);
  208. }];
  209. no = [NumberObject allObjectsInRealm:realm].firstObject;
  210. assertNullProperties(no);
  211. [realm transactionWithBlock:^{
  212. no.intObj = @1;
  213. no.doubleObj = @1.1;
  214. no.floatObj = @2.2f;
  215. no.boolObj = @YES;
  216. }];
  217. assertNonNullProperties(no);
  218. }
  219. - (void)testRequiredNumberProperties {
  220. RLMRealm *realm = [RLMRealm defaultRealm];
  221. [realm beginWriteTransaction];
  222. RequiredNumberObject *obj = [RequiredNumberObject createInRealm:realm withValue:@[@0, @0, @0, @0]];
  223. RLMAssertThrowsWithReason(obj.intObj = nil, @"insert null into non-nullable");
  224. RLMAssertThrowsWithReason(obj.floatObj = nil, @"insert null into non-nullable");
  225. RLMAssertThrowsWithReason(obj.doubleObj = nil, @"insert null into non-nullable");
  226. RLMAssertThrowsWithReason(obj.boolObj = nil, @"insert null into non-nullable");
  227. obj.intObj = @1;
  228. XCTAssertEqualObjects(obj.intObj, @1);
  229. obj.floatObj = @2.2f;
  230. XCTAssertEqualObjects(obj.floatObj, @2.2f);
  231. obj.doubleObj = @3.3;
  232. XCTAssertEqualObjects(obj.doubleObj, @3.3);
  233. obj.boolObj = @YES;
  234. XCTAssertEqualObjects(obj.boolObj, @YES);
  235. [realm cancelWriteTransaction];
  236. }
  237. - (void)testSettingNonOptionalPropertiesToNil {
  238. RequiredPropertiesObject *ro = [[RequiredPropertiesObject alloc] init];
  239. ro.stringCol = nil;
  240. ro.binaryCol = nil;
  241. XCTAssertNil(ro.stringCol);
  242. XCTAssertNil(ro.binaryCol);
  243. ro.stringCol = @"a";
  244. ro.binaryCol = [@"a" dataUsingEncoding:NSUTF8StringEncoding];
  245. RLMRealm *realm = [RLMRealm defaultRealm];
  246. [realm beginWriteTransaction];
  247. [realm addObject:ro];
  248. RLMAssertThrowsWithReasonMatching(ro.stringCol = nil, @"null into non-nullable column");
  249. RLMAssertThrowsWithReasonMatching(ro.binaryCol = nil, @"null into non-nullable column");
  250. [realm cancelWriteTransaction];
  251. }
  252. - (void)testIntSizes {
  253. RLMRealm *realm = [self realmWithTestPath];
  254. int16_t v16 = 1 << 12;
  255. int32_t v32 = 1 << 30;
  256. int64_t v64 = 1LL << 40;
  257. AllIntSizesObject *obj = [AllIntSizesObject new];
  258. // Test unmanaged
  259. obj[@"int16"] = @(v16);
  260. XCTAssertEqual([obj[@"int16"] shortValue], v16);
  261. obj[@"int16"] = @(v32);
  262. XCTAssertNotEqual([obj[@"int16"] intValue], v32, @"should truncate");
  263. obj.int16 = 0;
  264. obj.int16 = v16;
  265. XCTAssertEqual(obj.int16, v16);
  266. obj[@"int32"] = @(v32);
  267. XCTAssertEqual([obj[@"int32"] intValue], v32);
  268. obj[@"int32"] = @(v64);
  269. XCTAssertNotEqual([obj[@"int32"] longLongValue], v64, @"should truncate");
  270. obj.int32 = 0;
  271. obj.int32 = v32;
  272. XCTAssertEqual(obj.int32, v32);
  273. obj[@"int64"] = @(v64);
  274. XCTAssertEqual([obj[@"int64"] longLongValue], v64);
  275. obj.int64 = 0;
  276. obj.int64 = v64;
  277. XCTAssertEqual(obj.int64, v64);
  278. // Test in realm
  279. [realm beginWriteTransaction];
  280. [realm addObject:obj];
  281. XCTAssertEqual(obj.int16, v16);
  282. XCTAssertEqual(obj.int32, v32);
  283. XCTAssertEqual(obj.int64, v64);
  284. obj.int16 = 0;
  285. obj.int32 = 0;
  286. obj.int64 = 0;
  287. obj[@"int16"] = @(v16);
  288. XCTAssertEqual([obj[@"int16"] shortValue], v16);
  289. obj.int16 = 0;
  290. obj.int16 = v16;
  291. XCTAssertEqual(obj.int16, v16);
  292. obj[@"int32"] = @(v32);
  293. XCTAssertEqual([obj[@"int32"] intValue], v32);
  294. obj.int32 = 0;
  295. obj.int32 = v32;
  296. XCTAssertEqual(obj.int32, v32);
  297. obj[@"int64"] = @(v64);
  298. XCTAssertEqual([obj[@"int64"] longLongValue], v64);
  299. obj.int64 = 0;
  300. obj.int64 = v64;
  301. XCTAssertEqual(obj.int64, v64);
  302. [realm commitWriteTransaction];
  303. }
  304. - (void)testRenamedProperties {
  305. RenamedProperties1 *obj1 = [[RenamedProperties1 alloc] initWithValue:@{@"propA": @5, @"propB": @"a"}];
  306. XCTAssertEqual(obj1.propA, 5);
  307. XCTAssertEqualObjects(obj1.propB, @"a");
  308. XCTAssertEqualObjects(obj1[@"propA"], @5);
  309. XCTAssertEqualObjects(obj1[@"propB"], @"a");
  310. XCTAssertEqualObjects([obj1 valueForKey:@"propA"], @5);
  311. XCTAssertEqualObjects([obj1 valueForKey:@"propB"], @"a");
  312. RLMRealm *realm = [RLMRealm defaultRealm];
  313. [realm beginWriteTransaction];
  314. [realm addObject:obj1];
  315. XCTAssertEqual(obj1.propA, 5);
  316. XCTAssertEqualObjects(obj1.propB, @"a");
  317. XCTAssertEqualObjects(obj1[@"propA"], @5);
  318. XCTAssertEqualObjects(obj1[@"propB"], @"a");
  319. XCTAssertEqualObjects([obj1 valueForKey:@"propA"], @5);
  320. XCTAssertEqualObjects([obj1 valueForKey:@"propB"], @"a");
  321. RenamedProperties2 *obj2 = [RenamedProperties2 createInRealm:realm withValue:@{@"propC": @6, @"propD": @"b"}];
  322. XCTAssertEqual(obj2.propC, 6);
  323. XCTAssertEqualObjects(obj2.propD, @"b");
  324. XCTAssertEqualObjects(obj2[@"propC"], @6);
  325. XCTAssertEqualObjects(obj2[@"propD"], @"b");
  326. XCTAssertEqualObjects([obj2 valueForKey:@"propC"], @6);
  327. XCTAssertEqualObjects([obj2 valueForKey:@"propD"], @"b");
  328. RLMResults<RenamedProperties1 *> *results1 = [RenamedProperties1 allObjectsInRealm:realm];
  329. RLMResults<RenamedProperties2 *> *results2 = [RenamedProperties2 allObjectsInRealm:realm];
  330. XCTAssertTrue([results1[0] isEqualToObject:results2[0]]);
  331. XCTAssertTrue([results1[1] isEqualToObject:results2[1]]);
  332. LinkToRenamedProperties1 *link1 = [LinkToRenamedProperties1 createInRealm:realm withValue:@[obj1, obj2, @[obj1, results1[1]]]];
  333. LinkToRenamedProperties2 *link2 = [LinkToRenamedProperties2 createInRealm:realm withValue:@[obj2, obj1, @[obj2, results2[0]]]];
  334. XCTAssertTrue([link1.linkA isKindOfClass:[RenamedProperties1 class]]);
  335. XCTAssertTrue([link1.linkB isKindOfClass:[RenamedProperties2 class]]);
  336. XCTAssertTrue([link1.array[0] isKindOfClass:[RenamedProperties1 class]]);
  337. XCTAssertTrue([link1.array[1] isKindOfClass:[RenamedProperties1 class]]);
  338. XCTAssertTrue([link2.linkC isKindOfClass:[RenamedProperties2 class]]);
  339. XCTAssertTrue([link2.linkD isKindOfClass:[RenamedProperties1 class]]);
  340. XCTAssertTrue([link2.array[0] isKindOfClass:[RenamedProperties2 class]]);
  341. XCTAssertTrue([link2.array[1] isKindOfClass:[RenamedProperties2 class]]);
  342. XCTAssertTrue([link1.linkA isEqualToObject:results1[0]]);
  343. XCTAssertTrue([link1.linkB isEqualToObject:results1[1]]);
  344. XCTAssertTrue([link1.linkA isEqualToObject:results2[0]]);
  345. XCTAssertTrue([link1.linkB isEqualToObject:results2[1]]);
  346. XCTAssertTrue([link2.linkC isEqualToObject:results1[1]]);
  347. XCTAssertTrue([link2.linkD isEqualToObject:results1[0]]);
  348. XCTAssertTrue([link2.linkC isEqualToObject:results2[1]]);
  349. XCTAssertTrue([link2.linkD isEqualToObject:results2[0]]);
  350. XCTAssertEqualObjects([link1.array valueForKey:@"propB"], (@[@"a", @"b"]));
  351. XCTAssertEqualObjects([link2.array valueForKey:@"propD"], (@[@"b", @"a"]));
  352. XCTAssertTrue([obj1.linking1[0] isEqualToObject:link1]);
  353. XCTAssertTrue([obj1.linking2[0] isEqualToObject:link2]);
  354. XCTAssertTrue([obj2.linking1[0] isEqualToObject:link2]);
  355. XCTAssertTrue([obj2.linking2[0] isEqualToObject:link1]);
  356. [realm cancelWriteTransaction];
  357. }
  358. - (void)testAllMethodsCheckThread {
  359. RLMRealm *realm = [RLMRealm defaultRealm];
  360. __block AllTypesObject *obj;
  361. __block StringObject *stringObj;
  362. NSDictionary *values = @{@"boolCol": @NO,
  363. @"intCol": @0,
  364. @"floatCol": @0,
  365. @"doubleCol": @0,
  366. @"stringCol": @"",
  367. @"binaryCol": NSData.data,
  368. @"dateCol": NSDate.date,
  369. @"cBoolCol": @NO,
  370. @"longCol": @0,
  371. @"objectCol": NSNull.null};
  372. [realm transactionWithBlock:^{
  373. obj = [AllTypesObject createInRealm:realm withValue:values];
  374. stringObj = [StringObject createInRealm:realm withValue:@[@""]];
  375. }];
  376. [realm beginWriteTransaction];
  377. NSArray<NSString *> *propertyNames = [obj.objectSchema.properties valueForKey:@"name"];
  378. [self dispatchAsyncAndWait:^{
  379. // Getters
  380. for (NSString *prop in propertyNames) {
  381. RLMAssertThrowsWithReasonMatching(obj[prop], @"thread");
  382. RLMAssertThrowsWithReasonMatching([obj valueForKey:prop], @"thread");
  383. }
  384. RLMAssertThrowsWithReasonMatching(obj.boolCol, @"thread");
  385. RLMAssertThrowsWithReasonMatching(obj.intCol, @"thread");
  386. RLMAssertThrowsWithReasonMatching(obj.floatCol, @"thread");
  387. RLMAssertThrowsWithReasonMatching(obj.doubleCol, @"thread");
  388. RLMAssertThrowsWithReasonMatching(obj.stringCol, @"thread");
  389. RLMAssertThrowsWithReasonMatching(obj.binaryCol, @"thread");
  390. RLMAssertThrowsWithReasonMatching(obj.dateCol, @"thread");
  391. RLMAssertThrowsWithReasonMatching(obj.cBoolCol, @"thread");
  392. RLMAssertThrowsWithReasonMatching(obj.longCol, @"thread");
  393. RLMAssertThrowsWithReasonMatching(obj.objectCol, @"thread");
  394. RLMAssertThrowsWithReasonMatching(obj.linkingObjectsCol, @"thread");
  395. // Setters
  396. for (NSString *prop in propertyNames) {
  397. RLMAssertThrowsWithReasonMatching(obj[prop] = values[prop], @"thread");
  398. RLMAssertThrowsWithReasonMatching([obj setValue:values[prop] forKey:prop], @"thread");
  399. }
  400. RLMAssertThrowsWithReasonMatching(obj.boolCol = 0, @"thread");
  401. RLMAssertThrowsWithReasonMatching(obj.intCol = 0, @"thread");
  402. RLMAssertThrowsWithReasonMatching(obj.floatCol = 0, @"thread");
  403. RLMAssertThrowsWithReasonMatching(obj.doubleCol = 0, @"thread");
  404. RLMAssertThrowsWithReasonMatching(obj.stringCol = nil, @"thread");
  405. RLMAssertThrowsWithReasonMatching(obj.binaryCol = nil, @"thread");
  406. RLMAssertThrowsWithReasonMatching(obj.dateCol = nil, @"thread");
  407. RLMAssertThrowsWithReasonMatching(obj.cBoolCol = 0, @"thread");
  408. RLMAssertThrowsWithReasonMatching(obj.longCol = 0, @"thread");
  409. RLMAssertThrowsWithReasonMatching(obj.objectCol = nil, @"thread");
  410. RLMAssertThrowsWithReasonMatching(obj.objectCol = [StringObject new], @"thread");
  411. RLMAssertThrowsWithReasonMatching(obj.objectCol = stringObj, @"thread");
  412. }];
  413. [realm cancelWriteTransaction];
  414. }
  415. - (void)testAllMethodsCheckForInvalidation {
  416. RLMRealm *realm = [RLMRealm defaultRealm];
  417. __block StringObject *stringObj;
  418. NSDictionary *values = @{@"boolCol": @NO,
  419. @"intCol": @0,
  420. @"floatCol": @0,
  421. @"doubleCol": @0,
  422. @"stringCol": @"",
  423. @"binaryCol": NSData.data,
  424. @"dateCol": NSDate.date,
  425. @"cBoolCol": @NO,
  426. @"longCol": @0,
  427. @"objectCol": NSNull.null};
  428. [realm transactionWithBlock:^{
  429. [AllTypesObject createInRealm:realm withValue:values];
  430. stringObj = [StringObject createInRealm:realm withValue:@[@""]];
  431. }];
  432. for (int i = 0; i < 2; ++i) {
  433. AllTypesObject *obj = [[AllTypesObject allObjectsInRealm:realm] firstObject];
  434. [realm beginWriteTransaction];
  435. // Deleting the object directly and indirectly leave the managed
  436. // accessor in different states, so test both
  437. if (i == 0) {
  438. [realm deleteObject:obj];
  439. }
  440. else {
  441. [realm deleteObjects:[AllTypesObject allObjectsInRealm:realm]];
  442. }
  443. NSArray<NSString *> *propertyNames = [obj.objectSchema.properties valueForKey:@"name"];
  444. // Getters
  445. for (NSString *prop in propertyNames) {
  446. RLMAssertThrowsWithReasonMatching(obj[prop], @"invalidated");
  447. RLMAssertThrowsWithReasonMatching([obj valueForKey:prop], @"invalidated");
  448. }
  449. RLMAssertThrowsWithReasonMatching(obj.boolCol, @"invalidated");
  450. RLMAssertThrowsWithReasonMatching(obj.intCol, @"invalidated");
  451. RLMAssertThrowsWithReasonMatching(obj.floatCol, @"invalidated");
  452. RLMAssertThrowsWithReasonMatching(obj.doubleCol, @"invalidated");
  453. RLMAssertThrowsWithReasonMatching(obj.stringCol, @"invalidated");
  454. RLMAssertThrowsWithReasonMatching(obj.binaryCol, @"invalidated");
  455. RLMAssertThrowsWithReasonMatching(obj.dateCol, @"invalidated");
  456. RLMAssertThrowsWithReasonMatching(obj.cBoolCol, @"invalidated");
  457. RLMAssertThrowsWithReasonMatching(obj.longCol, @"invalidated");
  458. RLMAssertThrowsWithReasonMatching(obj.objectCol, @"invalidated");
  459. RLMAssertThrowsWithReasonMatching(obj.linkingObjectsCol, @"invalidated");
  460. // Setters
  461. for (NSString *prop in propertyNames) {
  462. RLMAssertThrowsWithReasonMatching(obj[prop] = values[prop], @"invalidated");
  463. RLMAssertThrowsWithReasonMatching([obj setValue:values[prop] forKey:prop], @"invalidated");
  464. }
  465. RLMAssertThrowsWithReasonMatching(obj.boolCol = 0, @"invalidated");
  466. RLMAssertThrowsWithReasonMatching(obj.intCol = 0, @"invalidated");
  467. RLMAssertThrowsWithReasonMatching(obj.floatCol = 0, @"invalidated");
  468. RLMAssertThrowsWithReasonMatching(obj.doubleCol = 0, @"invalidated");
  469. RLMAssertThrowsWithReasonMatching(obj.stringCol = nil, @"invalidated");
  470. RLMAssertThrowsWithReasonMatching(obj.binaryCol = nil, @"invalidated");
  471. RLMAssertThrowsWithReasonMatching(obj.dateCol = nil, @"invalidated");
  472. RLMAssertThrowsWithReasonMatching(obj.cBoolCol = 0, @"invalidated");
  473. RLMAssertThrowsWithReasonMatching(obj.longCol = 0, @"invalidated");
  474. RLMAssertThrowsWithReasonMatching(obj.objectCol = nil, @"invalidated");
  475. RLMAssertThrowsWithReasonMatching(obj.objectCol = [StringObject new], @"invalidated");
  476. RLMAssertThrowsWithReasonMatching(obj.objectCol = stringObj, @"invalidated");
  477. [realm cancelWriteTransaction];
  478. }
  479. }
  480. @end