| // RUN: %empty-directory(%t) |
| |
| // RUN: %clang %target-cc-options -isysroot %sdk -fobjc-arc %S/Inputs/ObjCClasses/ObjCClasses.m -c -o %t/ObjCClasses.o |
| // RUN: %target-build-swift -I %S/Inputs/ObjCClasses/ %t/ObjCClasses.o %s -o %t/a.out |
| // RUN: %target-run %t/a.out |
| |
| // REQUIRES: executable_test |
| // REQUIRES: objc_interop |
| |
| import Foundation |
| import StdlibUnittest |
| import ObjCClasses |
| |
| class SwiftClass : ProtoWithClassProperty { |
| static var getCount = 0 |
| static var setCount = 0 |
| |
| private static var _value: CInt = 0 |
| |
| @objc class func reset() { |
| getCount = 0 |
| setCount = 0 |
| _value = 0 |
| } |
| |
| @objc class var value: CInt { |
| get { |
| getCount += 1 |
| return _value |
| } |
| set { |
| setCount += 1 |
| _value = newValue |
| } |
| } |
| |
| @objc class var optionalClassProp: Bool { |
| return true |
| } |
| } |
| |
| class Subclass : ClassWithClassProperty { |
| static var getCount = 0 |
| static var setCount = 0 |
| |
| override class func reset() { |
| getCount = 0 |
| setCount = 0 |
| super.reset() |
| } |
| |
| override class var value: CInt { |
| get { |
| getCount += 1 |
| return super.value |
| } |
| set { |
| setCount += 1 |
| super.value = newValue |
| } |
| } |
| |
| override class var optionalClassProp: Bool { |
| return true |
| } |
| } |
| |
| var ClassProperties = TestSuite("ClassProperties") |
| |
| ClassProperties.test("direct") { |
| ClassWithClassProperty.reset() |
| expectEqual(0, ClassWithClassProperty.value) |
| ClassWithClassProperty.value = 4 |
| expectEqual(4, ClassWithClassProperty.value) |
| |
| Subclass.reset() |
| expectEqual(0, Subclass.value) |
| Subclass.value = 4 |
| expectEqual(4, Subclass.value) |
| expectEqual(2, Subclass.getCount) |
| expectEqual(1, Subclass.setCount) |
| } |
| |
| func testExistential(_ e: ProtoWithClassProperty.Type) { |
| e.reset() |
| expectEqual(0, e.value) |
| e.value = 4 |
| expectEqual(4, e.value) |
| } |
| |
| ClassProperties.test("existentials") { |
| testExistential(ClassWithClassProperty.self) |
| testExistential(ObjCSubclassWithClassProperty.self) |
| |
| testExistential(SwiftClass.self) |
| expectEqual(2, SwiftClass.getCount) |
| expectEqual(1, SwiftClass.setCount) |
| |
| testExistential(Subclass.self) |
| expectEqual(2, Subclass.getCount) |
| expectEqual(1, Subclass.setCount) |
| } |
| |
| func testGeneric<T: ProtoWithClassProperty>(_ e: T.Type) { |
| e.reset() |
| expectEqual(0, e.value) |
| e.value = 4 |
| expectEqual(4, e.value) |
| } |
| |
| ClassProperties.test("generics") { |
| testGeneric(ClassWithClassProperty.self) |
| testGeneric(ObjCSubclassWithClassProperty.self) |
| |
| testGeneric(SwiftClass.self) |
| expectEqual(2, SwiftClass.getCount) |
| expectEqual(1, SwiftClass.setCount) |
| |
| testGeneric(Subclass.self) |
| expectEqual(2, Subclass.getCount) |
| expectEqual(1, Subclass.setCount) |
| } |
| |
| func testInheritance(_ e: ClassWithClassProperty.Type) { |
| e.reset() |
| expectEqual(0, e.value) |
| e.value = 4 |
| expectEqual(4, e.value) |
| } |
| |
| ClassProperties.test("inheritance") { |
| testInheritance(ClassWithClassProperty.self) |
| testInheritance(ObjCSubclassWithClassProperty.self) |
| |
| testInheritance(Subclass.self) |
| expectEqual(2, Subclass.getCount) |
| expectEqual(1, Subclass.setCount) |
| } |
| |
| func testInheritanceGeneric<T: ClassWithClassProperty>(_ e: T.Type) { |
| e.reset() |
| expectEqual(0, e.value) |
| e.value = 4 |
| expectEqual(4, e.value) |
| } |
| |
| ClassProperties.test("inheritance/generic") { |
| testInheritanceGeneric(ClassWithClassProperty.self) |
| testInheritanceGeneric(ObjCSubclassWithClassProperty.self) |
| |
| testInheritanceGeneric(Subclass.self) |
| expectEqual(2, Subclass.getCount) |
| expectEqual(1, Subclass.setCount) |
| } |
| |
| ClassProperties.test("optionalProp") { |
| let noProp: ProtoWithClassProperty.Type = ClassWithClassProperty.self |
| expectNil(noProp.optionalClassProp) |
| |
| let hasProp: ProtoWithClassProperty.Type = Subclass.self |
| expectNotNil(hasProp.optionalClassProp) |
| expectEqual(true, hasProp.optionalClassProp!) |
| |
| let hasOwnProp: ProtoWithClassProperty.Type = SwiftClass.self |
| expectNotNil(hasOwnProp.optionalClassProp) |
| expectEqual(true, hasOwnProp.optionalClassProp!) |
| |
| let hasPropObjC: ProtoWithClassProperty.Type = ObjCSubclassWithClassProperty.self |
| expectNotNil(hasPropObjC.optionalClassProp) |
| expectEqual(true, hasPropObjC.optionalClassProp!) |
| } |
| |
| class NamingConflictSubclass : PropertyNamingConflict { |
| override var prop: Any? { return nil } |
| override class var prop: Any? { return NamingConflictSubclass() } |
| } |
| |
| ClassProperties.test("namingConflict") { |
| let obj = PropertyNamingConflict() |
| expectTrue(obj === obj.prop.map { $0 as AnyObject }) |
| expectNil(type(of: obj).prop) |
| expectNil(PropertyNamingConflict.prop) |
| |
| let sub = NamingConflictSubclass() |
| expectNil(sub.prop) |
| expectNotNil(type(of: sub).prop) |
| expectNotNil(NamingConflictSubclass.prop) |
| } |
| |
| extension NamingConflictSubclass : PropertyNamingConflictProto { |
| var protoProp: Any? { |
| get { return self } |
| set {} |
| } |
| class var protoProp: Any? { |
| get { return nil } |
| set {} |
| } |
| } |
| |
| ClassProperties.test("namingConflict/protocol") { |
| let obj: PropertyNamingConflictProto = NamingConflictSubclass() |
| expectTrue(obj === obj.protoProp.map { $0 as AnyObject }) |
| expectNil(type(of: obj).protoProp) |
| |
| let type: PropertyNamingConflictProto.Type = NamingConflictSubclass.self |
| expectNil(type.protoProp) |
| } |
| |
| var global1: Int = 0 |
| |
| var global2: Int = 0 |
| |
| class Steak : NSObject { |
| @objc override var thickness: Int { |
| get { return global1 } set { global1 = newValue } |
| } |
| } |
| |
| extension NSObject : HasThickness { |
| @objc var thickness: Int { get { return global2 } set { global2 = newValue } } |
| } |
| |
| protocol HasThickness : class { |
| var thickness: Int { get set } |
| } |
| |
| ClassProperties.test("dynamicOverride") { |
| // Calls NSObject.thickness |
| NSObject().thickness += 1 |
| |
| // Calls Steak.thickness |
| (Steak() as NSObject).thickness += 1 |
| Steak().thickness += 1 |
| (Steak() as HasThickness).thickness += 1 |
| |
| expectEqual(3, global1) |
| expectEqual(1, global2) |
| } |
| |
| runAllTests() |
| |