Skip to content

Commit 112d7b0

Browse files
authored
Merge pull request #504 from madsmtm/more-tests
Add more tests
2 parents 5e1054d + 7030050 commit 112d7b0

File tree

5 files changed

+141
-8
lines changed

5 files changed

+141
-8
lines changed

crates/icrate/tests/mutable_dictionary.rs

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,16 +67,47 @@ fn test_insert() {
6767
}
6868

6969
#[test]
70-
fn test_insert_retain_release() {
70+
fn test_insert_key_copies() {
7171
let mut dict = NSMutableDictionary::new();
72-
dict.insert(NSNumber::new_i32(1), __RcTestObject::new());
72+
let key1 = __RcTestObject::new();
7373
let mut expected = __ThreadTestData::current();
7474

75-
let old = dict.insert(NSNumber::new_i32(1), __RcTestObject::new());
75+
let _ = dict.insert(key1, NSNumber::new_i32(1));
76+
// Create copy
77+
expected.copy += 1;
7678
expected.alloc += 1;
7779
expected.init += 1;
78-
expected.retain += 2;
79-
expected.release += 2;
80+
81+
// Release passed-in key
82+
expected.release += 1;
83+
expected.dealloc += 1;
84+
expected.assert_current();
85+
86+
dict.removeAllObjects();
87+
// Release key
88+
expected.release += 1;
89+
expected.dealloc += 1;
90+
expected.assert_current();
91+
}
92+
93+
#[test]
94+
fn test_insert_value_retain_release() {
95+
let mut dict = NSMutableDictionary::new();
96+
dict.insert(NSNumber::new_i32(1), __RcTestObject::new());
97+
let to_insert = __RcTestObject::new();
98+
let mut expected = __ThreadTestData::current();
99+
100+
let old = dict.insert(NSNumber::new_i32(1), to_insert);
101+
// Grab old value
102+
expected.retain += 1;
103+
104+
// Dictionary takes new value and overwrites the old one
105+
expected.retain += 1;
106+
expected.release += 1;
107+
108+
// Release passed-in `Id`
109+
expected.release += 1;
110+
80111
expected.assert_current();
81112

82113
drop(old);

crates/icrate/tests/mutable_set.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#![cfg(feature = "Foundation_NSMutableSet")]
22
#![cfg(feature = "Foundation_NSString")]
33
use objc2::rc::{__RcTestObject, __ThreadTestData};
4+
use objc2::ClassType;
45

56
use icrate::Foundation::{self, ns_string, NSMutableSet, NSSet, NSString};
67

@@ -79,17 +80,30 @@ fn test_insert_retain_release() {
7980
let mut set = NSMutableSet::new();
8081
let obj1 = __RcTestObject::new();
8182
let obj2 = __RcTestObject::new();
83+
let obj2_copy = obj2.retain();
8284
let mut expected = __ThreadTestData::current();
8385

8486
set.insert(obj1);
87+
// Retain to store in set
8588
expected.retain += 1;
89+
// Release passed in object
8690
expected.release += 1;
8791
expected.assert_current();
8892
assert_eq!(set.len(), 1);
8993
assert_eq!(set.get_any(), set.get_any());
9094

9195
set.insert(obj2);
96+
// Retain to store in set
9297
expected.retain += 1;
98+
// Release passed in object
99+
expected.release += 1;
100+
expected.assert_current();
101+
assert_eq!(set.len(), 2);
102+
103+
set.insert(obj2_copy);
104+
// No retain, since the object is already in the set
105+
expected.retain += 0;
106+
// Release passed in object
93107
expected.release += 1;
94108
expected.assert_current();
95109
assert_eq!(set.len(), 2);

crates/objc2/src/declare/mod.rs

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -762,12 +762,15 @@ impl Drop for ProtocolBuilder {
762762

763763
#[cfg(test)]
764764
mod tests {
765+
use core::hash::Hasher;
766+
use std::collections::hash_map::DefaultHasher;
767+
use std::hash::Hash;
768+
765769
use super::*;
766770
use crate::mutability::Immutable;
767771
use crate::rc::Id;
768-
use crate::runtime::{NSObject, NSZone, __NSCopying as NSCopying};
769-
use crate::test_utils;
770-
use crate::{declare_class, msg_send, ClassType, ProtocolType};
772+
use crate::runtime::{NSObject, NSObjectProtocol, NSZone, __NSCopying as NSCopying};
773+
use crate::{declare_class, extern_methods, msg_send, test_utils, ClassType, ProtocolType};
771774

772775
#[test]
773776
fn test_alignment() {
@@ -1159,4 +1162,55 @@ mod tests {
11591162

11601163
let _ = GenericDeclareClass::<()>::class();
11611164
}
1165+
1166+
#[test]
1167+
fn test_inherited_nsobject_methods_work() {
1168+
declare_class!(
1169+
#[derive(Debug, PartialEq, Eq, Hash)]
1170+
struct Custom;
1171+
1172+
unsafe impl ClassType for Custom {
1173+
type Super = NSObject;
1174+
type Mutability = Immutable;
1175+
const NAME: &'static str = "TestInheritedNSObjectMethodsWork";
1176+
}
1177+
);
1178+
1179+
extern_methods!(
1180+
unsafe impl Custom {
1181+
#[method_id(new)]
1182+
fn new() -> Id<Self>;
1183+
}
1184+
);
1185+
1186+
let obj1 = Custom::new();
1187+
let obj2 = Custom::new();
1188+
1189+
// isEqual:
1190+
assert_eq!(obj1, obj1);
1191+
assert_ne!(obj1, obj2);
1192+
1193+
// description
1194+
let expected =
1195+
format!("Custom {{ __superclass: ManuallyDrop {{ value: <TestInheritedNSObjectMethodsWork: {obj1:p}> }} }}");
1196+
assert_eq!(format!("{obj1:?}"), expected);
1197+
1198+
// hash
1199+
let mut hashstate1 = DefaultHasher::new();
1200+
let mut hashstate2 = DefaultHasher::new();
1201+
1202+
obj1.hash(&mut hashstate1);
1203+
obj1.hash(&mut hashstate2);
1204+
1205+
assert_eq!(hashstate1.finish(), hashstate2.finish());
1206+
1207+
let mut hashstate2 = DefaultHasher::new();
1208+
obj2.hash(&mut hashstate2);
1209+
assert_ne!(hashstate1.finish(), hashstate2.finish());
1210+
1211+
// isKindOfClass:
1212+
assert!(obj1.is_kind_of::<NSObject>());
1213+
assert!(obj1.is_kind_of::<Custom>());
1214+
assert!(obj1.is_kind_of::<Custom>());
1215+
}
11621216
}

crates/objc2/src/exception.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,8 +298,10 @@ pub unsafe fn catch<R>(
298298
mod tests {
299299
use alloc::format;
300300
use alloc::string::ToString;
301+
use core::panic::AssertUnwindSafe;
301302

302303
use super::*;
304+
use crate::msg_send_id;
303305
use crate::runtime::NSObject;
304306

305307
#[test]
@@ -332,6 +334,27 @@ mod tests {
332334
assert!(result.unwrap_err().is_none());
333335
}
334336

337+
#[test]
338+
#[cfg_attr(
339+
feature = "catch-all",
340+
ignore = "Panics inside `catch` when catch-all is enabled"
341+
)]
342+
fn test_catch_unknown_selector() {
343+
let obj = AssertUnwindSafe(NSObject::new());
344+
let ptr = Id::as_ptr(&obj);
345+
let result = unsafe {
346+
catch(|| {
347+
let _: Id<NSObject> = msg_send_id![&*obj, copy];
348+
})
349+
};
350+
let err = result.unwrap_err().unwrap();
351+
352+
assert_eq!(
353+
format!("{err}"),
354+
format!("-[NSObject copyWithZone:]: unrecognized selector sent to instance {ptr:?}"),
355+
);
356+
}
357+
335358
#[test]
336359
fn test_throw_catch_object() {
337360
let obj = NSObject::new();

crates/objc2/src/runtime/nsobject.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,4 +357,15 @@ mod tests {
357357
assert!(obj.is_kind_of::<NSObject>());
358358
assert!(obj.is_kind_of::<__RcTestObject>());
359359
}
360+
361+
#[test]
362+
fn test_retain_same() {
363+
let obj1 = NSObject::new();
364+
let ptr1 = Id::as_ptr(&obj1);
365+
366+
let obj2 = obj1.clone();
367+
let ptr2 = Id::as_ptr(&obj2);
368+
369+
assert_eq!(ptr1, ptr2);
370+
}
360371
}

0 commit comments

Comments
 (0)