Rework @Throws tests

This commit is contained in:
Svyatoslav Scherbina
2020-02-07 11:52:20 +03:00
committed by SvyatoslavScherbina
parent 537188fce8
commit 8bcee1e632
3 changed files with 294 additions and 56 deletions
@@ -265,25 +265,90 @@ __attribute__((swift_name("MyException")))
- (instancetype)initWithCause:(ValuesKotlinThrowable * _Nullable)cause __attribute__((swift_name("init(cause:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable));
@end;
__attribute__((swift_name("BridgeBase")))
@interface ValuesBridgeBase : ValuesBase
__attribute__((objc_subclassing_restricted))
__attribute__((swift_name("MyError")))
@interface ValuesMyError : ValuesKotlinError
- (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer));
+ (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead")));
- (id _Nullable)foo1AndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("foo1()")));
- (int32_t)foo2AndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("foo2()"))) __attribute__((swift_error(nonnull_error)));
- (BOOL)foo3AndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("foo3()")));
- (ValuesKotlinNothing * _Nullable)foo4AndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("foo4()"))) __attribute__((swift_error(nonnull_error)));
- (instancetype)initWithMessage:(NSString * _Nullable)message __attribute__((swift_name("init(message:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable));
- (instancetype)initWithMessage:(NSString * _Nullable)message cause:(ValuesKotlinThrowable * _Nullable)cause __attribute__((swift_name("init(message:cause:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable));
- (instancetype)initWithCause:(ValuesKotlinThrowable * _Nullable)cause __attribute__((swift_name("init(cause:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable));
@end;
__attribute__((swift_name("SwiftOverridableMethodsWithThrows")))
@protocol ValuesSwiftOverridableMethodsWithThrows
@required
- (BOOL)unitAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("unit()")));
- (BOOL)nothingAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("nothing()")));
- (id _Nullable)anyAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("any()")));
- (ValuesInt *(^ _Nullable)(void))blockAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("block()")));
@end;
__attribute__((swift_name("MethodsWithThrows")))
@protocol ValuesMethodsWithThrows <ValuesSwiftOverridableMethodsWithThrows>
@required
- (ValuesKotlinNothing * _Nullable)nothingNAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("nothingN()"))) __attribute__((swift_error(nonnull_error)));
- (id _Nullable)anyNAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("anyN()"))) __attribute__((swift_error(nonnull_error)));
- (ValuesInt *(^ _Nullable)(void))blockNAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("blockN()"))) __attribute__((swift_error(nonnull_error)));
- (void * _Nullable)pointerAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("pointer()")));
- (void * _Nullable)pointerNAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("pointerN()"))) __attribute__((swift_error(nonnull_error)));
- (int32_t)intAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("int()"))) __attribute__((swift_error(nonnull_error)));
- (ValuesLong * _Nullable)longNAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("longN()"))) __attribute__((swift_error(nonnull_error)));
- (double)doubleAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("double()"))) __attribute__((swift_error(nonnull_error)));
@end;
__attribute__((swift_name("MethodsWithThrowsUnitCaller")))
@protocol ValuesMethodsWithThrowsUnitCaller
@required
- (BOOL)callMethods:(id<ValuesMethodsWithThrows>)methods error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("call(methods:)")));
@end;
__attribute__((swift_name("Throwing")))
@interface ValuesThrowing : ValuesBase <ValuesMethodsWithThrows>
- (instancetype _Nullable)initWithDoThrow:(BOOL)doThrow error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("init(doThrow:)"))) __attribute__((objc_designated_initializer));
- (BOOL)unitAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("unit()")));
- (BOOL)nothingAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("nothing()")));
- (ValuesKotlinNothing * _Nullable)nothingNAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("nothingN()"))) __attribute__((swift_error(nonnull_error)));
- (id _Nullable)anyAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("any()")));
- (id _Nullable)anyNAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("anyN()"))) __attribute__((swift_error(nonnull_error)));
- (ValuesInt *(^ _Nullable)(void))blockAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("block()")));
- (ValuesInt *(^ _Nullable)(void))blockNAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("blockN()"))) __attribute__((swift_error(nonnull_error)));
- (void * _Nullable)pointerAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("pointer()")));
- (void * _Nullable)pointerNAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("pointerN()"))) __attribute__((swift_error(nonnull_error)));
- (int32_t)intAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("int()"))) __attribute__((swift_error(nonnull_error)));
- (ValuesLong * _Nullable)longNAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("longN()"))) __attribute__((swift_error(nonnull_error)));
- (double)doubleAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("double()"))) __attribute__((swift_error(nonnull_error)));
@end;
__attribute__((objc_subclassing_restricted))
__attribute__((swift_name("Bridge")))
@interface ValuesBridge : ValuesBridgeBase
__attribute__((swift_name("NotThrowing")))
@interface ValuesNotThrowing : ValuesBase <ValuesMethodsWithThrows>
- (instancetype _Nullable)initAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer));
- (BOOL)unitAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("unit()")));
- (BOOL)nothingAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("nothing()")));
- (ValuesKotlinNothing * _Nullable)nothingNAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("nothingN()"))) __attribute__((swift_error(nonnull_error)));
- (id _Nullable)anyAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("any()")));
- (id _Nullable)anyNAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("anyN()"))) __attribute__((swift_error(nonnull_error)));
- (ValuesInt *(^ _Nullable)(void))blockAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("block()")));
- (ValuesInt *(^ _Nullable)(void))blockNAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("blockN()"))) __attribute__((swift_error(nonnull_error)));
- (void * _Nullable)pointerAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("pointer()")));
- (void * _Nullable)pointerNAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("pointerN()"))) __attribute__((swift_error(nonnull_error)));
- (int32_t)intAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("int()"))) __attribute__((swift_error(nonnull_error)));
- (ValuesLong * _Nullable)longNAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("longN()"))) __attribute__((swift_error(nonnull_error)));
- (double)doubleAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("double()"))) __attribute__((swift_error(nonnull_error)));
@end;
__attribute__((swift_name("ThrowsWithBridgeBase")))
@protocol ValuesThrowsWithBridgeBase
@required
- (id _Nullable)plusOneX:(int32_t)x error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("plusOne(x:)")));
@end;
__attribute__((swift_name("ThrowsWithBridge")))
@interface ValuesThrowsWithBridge : ValuesBase <ValuesThrowsWithBridgeBase>
- (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer));
+ (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead")));
- (ValuesKotlinNothing * _Nullable)foo1AndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("foo1()")));
- (int32_t)foo2AndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("foo2()"))) __attribute__((swift_error(nonnull_error)));
- (BOOL)foo3AndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("foo3()")));
- (ValuesKotlinNothing *)foo4AndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("foo4()"))) __attribute__((swift_error(nonnull_error)));
- (ValuesInt * _Nullable)plusOneX:(int32_t)x error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("plusOne(x:)")));
@end;
__attribute__((objc_subclassing_restricted))
@@ -1102,7 +1167,13 @@ __attribute__((swift_name("ValuesKt")))
+ (BOOL)isFrozenObj:(id)obj __attribute__((swift_name("isFrozen(obj:)")));
+ (id)kotlinLambdaBlock:(id (^)(id))block __attribute__((swift_name("kotlinLambda(block:)")));
+ (int64_t)multiplyInt:(int32_t)int_ long:(int64_t)long_ __attribute__((swift_name("multiply(int:long:)")));
+ (id _Nullable)callFoo1Bridge:(ValuesBridgeBase *)bridge error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("callFoo1(bridge:)")));
+ (BOOL)throwExceptionError:(BOOL)error error:(NSError * _Nullable * _Nullable)error_ __attribute__((swift_name("throwException(error:)")));
+ (ValuesKotlinObjCErrorException * _Nullable)testSwiftThrowingMethods:(id<ValuesSwiftOverridableMethodsWithThrows>)methods error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("testSwiftThrowing(methods:)")));
+ (BOOL)testSwiftNotThrowingMethods:(id<ValuesSwiftOverridableMethodsWithThrows>)methods error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("testSwiftNotThrowing(methods:)")));
+ (BOOL)callUnitMethods:(id<ValuesSwiftOverridableMethodsWithThrows>)methods error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("callUnit(methods:)")));
+ (BOOL)callUnitCallerCaller:(id<ValuesMethodsWithThrowsUnitCaller>)caller methods:(id<ValuesMethodsWithThrows>)methods error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("callUnitCaller(caller:methods:)")));
+ (BOOL)testSwiftThrowingTest:(id<ValuesThrowsWithBridgeBase>)test flag:(BOOL)flag error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("testSwiftThrowing(test:flag:)")));
+ (BOOL)testSwiftNotThrowingTest:(id<ValuesThrowsWithBridgeBase>)test error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("testSwiftNotThrowing(test:)")));
+ (id)same:(id)receiver __attribute__((swift_name("same(_:)")));
+ (ValuesInt * _Nullable)callBase1:(id<ValuesBase1>)base1 value:(ValuesInt * _Nullable)value __attribute__((swift_name("call(base1:value:)")));
+ (ValuesInt * _Nullable)callExtendedBase1:(id<ValuesExtendedBase1>)extendedBase1 value:(ValuesInt * _Nullable)value __attribute__((swift_name("call(extendedBase1:value:)")));
+114 -16
View File
@@ -14,6 +14,7 @@ import kotlin.native.ref.WeakReference
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KClass
import kotlin.reflect.KProperty
import kotlin.test.*
import kotlinx.cinterop.*
// Ensure loaded function IR classes aren't ordered by arity:
@@ -253,27 +254,124 @@ fun kotlinLambda(block: (Any) -> Any): Any = block
fun multiply(int: Int, long: Long) = int * long
class MyException : Exception()
class MyError : Error()
open class BridgeBase {
@Throws(MyException::class)
open fun foo1(): Any = Any()
@Throws(MyException::class)
open fun foo2(): Int = 42
@Throws(MyException::class)
open fun foo3(): Unit = Unit
@Throws(MyException::class)
open fun foo4(): Nothing? = throw IllegalStateException()
@Throws(MyException::class, MyError::class)
fun throwException(error: Boolean): Unit {
throw if (error) MyError() else MyException()
}
class Bridge : BridgeBase() {
override fun foo1() = throw MyException()
override fun foo2() = throw MyException()
override fun foo3() = throw MyException()
override fun foo4() = throw MyException()
interface SwiftOverridableMethodsWithThrows {
@Throws(MyException::class) fun unit(): Unit
@Throws(MyException::class) fun nothing(): Nothing
@Throws(MyException::class) fun any(): Any
@Throws(MyException::class) fun block(): () -> Int
}
@Throws(NullPointerException::class)
fun callFoo1(bridge: BridgeBase) = bridge.foo1()
interface MethodsWithThrows : SwiftOverridableMethodsWithThrows {
@Throws(MyException::class) fun nothingN(): Nothing?
@Throws(MyException::class) fun anyN(): Any?
@Throws(MyException::class) fun blockN(): (() -> Int)?
@Throws(MyException::class) fun pointer(): CPointer<*>
@Throws(MyException::class) fun pointerN(): CPointer<*>?
@Throws(MyException::class) fun int(): Int
@Throws(MyException::class) fun longN(): Long?
@Throws(MyException::class) fun double(): Double
interface UnitCaller {
@Throws(MyException::class) fun call(methods: MethodsWithThrows): Unit
}
}
open class Throwing : MethodsWithThrows {
@Throws(MyException::class) constructor(doThrow: Boolean) {
if (doThrow) throw MyException()
}
override fun unit(): Unit = throw MyException()
override fun nothing(): Nothing = throw MyException()
override fun nothingN(): Nothing? = throw MyException()
override fun any(): Any = throw MyException()
override fun anyN(): Any? = throw MyException()
override fun block(): () -> Int = throw MyException()
override fun blockN(): (() -> Int)? = throw MyException()
override fun pointer(): CPointer<*> = throw MyException()
override fun pointerN(): CPointer<*>? = throw MyException()
override fun int(): Int = throw MyException()
override fun longN(): Long? = throw MyException()
override fun double(): Double = throw MyException()
}
class NotThrowing : MethodsWithThrows {
@Throws(MyException::class) constructor() {}
override fun unit(): Unit {}
override fun nothing(): Nothing = throw MyException()
override fun nothingN(): Nothing? = null
override fun any(): Any = Any()
override fun anyN(): Any? = Any()
override fun block(): () -> Int = { 42 }
override fun blockN(): (() -> Int)? = null
override fun pointer(): CPointer<*> = 1L.toCPointer<COpaque>()!!
override fun pointerN(): CPointer<*>? = null
override fun int(): Int = 42
override fun longN(): Long? = null
override fun double(): Double = 3.14
}
@Throws(Throwable::class)
fun testSwiftThrowing(methods: SwiftOverridableMethodsWithThrows) = with(methods) {
assertSwiftThrowing { unit() }
assertSwiftThrowing { nothing() }
assertSwiftThrowing { any() }
assertSwiftThrowing { block() }
}
private inline fun assertSwiftThrowing(block: () -> Unit) =
assertFailsWith<kotlin.native.internal.ObjCErrorException>(block = block)
@Throws(Throwable::class)
fun testSwiftNotThrowing(methods: SwiftOverridableMethodsWithThrows) = with(methods) {
unit()
assertEquals(42, any())
assertEquals(17, block()())
}
@Throws(MyError::class)
fun callUnit(methods: SwiftOverridableMethodsWithThrows) = methods.unit()
@Throws(Throwable::class)
fun callUnitCaller(caller: MethodsWithThrows.UnitCaller, methods: MethodsWithThrows) {
assertFailsWith<MyException> { caller.call(methods) }
}
interface ThrowsWithBridgeBase {
@Throws(MyException::class)
fun plusOne(x: Int): Any
}
abstract class ThrowsWithBridge : ThrowsWithBridgeBase {
abstract override fun plusOne(x: Int): Int
}
@Throws(Throwable::class)
fun testSwiftThrowing(test: ThrowsWithBridgeBase, flag: Boolean) {
assertFailsWith<kotlin.native.internal.ObjCErrorException> {
if (flag) {
test.plusOne(0)
} else {
val test1 = test as ThrowsWithBridge
val ignore: Int = test1.plusOne(1)
}
}
}
@Throws(Throwable::class)
fun testSwiftNotThrowing(test: ThrowsWithBridgeBase) {
assertEquals(3, test.plusOne(2))
val test1 = test as ThrowsWithBridge
assertEquals<Int>(4, test1.plusOne(3))
}
fun Any.same() = this
@@ -275,43 +275,112 @@ func testFunctions() throws {
try assertEquals(actual: ValuesKt.multiply(int: 3, long: 2), expected: 6)
}
class BridgeSwift : BridgeBase {
class Err : Error {}
class SwiftThrowing : SwiftOverridableMethodsWithThrows {
class E : Error {}
override func foo1() throws -> Any {
throw Err()
func unit() throws -> Void { throw E() }
func nothing() throws -> Void { throw E() }
func any() throws -> Any { throw E() }
func block() throws -> () -> KotlinInt { throw E() }
}
class TestThrowingConstructorRelease : Throwing {
static var deinitialized = false
deinit {
TestThrowingConstructorRelease.deinitialized = true
}
}
class SwiftNotThrowing : SwiftOverridableMethodsWithThrows {
func unit() throws -> Void { }
func nothing() throws -> Void { throw SwiftThrowing.E() }
func any() throws -> Any { return 42 as Int32 }
func block() throws -> () -> KotlinInt { return { 17 } }
}
class SwiftUnitCaller : MethodsWithThrowsUnitCaller {
func call(methods: MethodsWithThrows) throws -> Void {
try methods.unit()
}
}
class SwiftThrowingWithBridge : ThrowsWithBridge {
override func plusOne(x: Int32) throws -> KotlinInt {
throw SwiftThrowing.E()
}
}
class SwiftNotThrowingWithBridge : ThrowsWithBridge {
override func plusOne(x: Int32) throws -> KotlinInt {
return KotlinInt(value: x + 1)
}
}
func testExceptions() throws {
let bridge = Bridge()
func testThrowing(_ block: () throws -> Void) throws {
do {
try block()
} catch let error as NSError {
try assertTrue(error.kotlinException is MyException)
}
}
try testThrowing { try ValuesKt.throwException(error: false) }
do {
try bridge.foo1()
try ValuesKt.throwException(error: true)
} catch let error as NSError {
try assertTrue(error.kotlinException is MyException)
try assertTrue(error.kotlinException is MyError)
}
try assertFalse(TestThrowingConstructorRelease.deinitialized)
try testThrowing { try TestThrowingConstructorRelease(doThrow: true) }
ValuesKt.gc()
try assertTrue(TestThrowingConstructorRelease.deinitialized)
try testThrowing { try Throwing(doThrow: true) }
let throwing = try Throwing(doThrow: false)
try testThrowing { try throwing.unit() }
try testThrowing { try throwing.nothing() }
try testThrowing { try throwing.nothingN() }
try testThrowing { try throwing.any() }
try testThrowing { try throwing.anyN() }
try testThrowing { try throwing.block()() }
try testThrowing { try throwing.blockN() }
try testThrowing { try throwing.pointer() }
try testThrowing { try throwing.pointerN() }
try testThrowing { try throwing.int() }
try testThrowing { try throwing.longN() }
try testThrowing { try throwing.double() }
let notThrowing = try NotThrowing()
try notThrowing.unit()
try assertEquals(actual: notThrowing.nothingN(), expected: nil)
try assertTrue(notThrowing.any() is KotlinBase)
try assertTrue(notThrowing.anyN() is KotlinBase)
try assertEquals(actual: notThrowing.block()(), expected: 42)
try assertTrue(notThrowing.blockN() == nil)
try assertEquals(actual: Int(bitPattern: notThrowing.pointer()), expected: 1)
try assertEquals(actual: notThrowing.pointerN(), expected: nil)
try assertEquals(actual: notThrowing.int(), expected: 42)
try assertEquals(actual: notThrowing.longN(), expected: nil)
try assertEquals(actual: notThrowing.double(), expected: 3.14)
try ValuesKt.testSwiftThrowing(methods: SwiftThrowing())
try ValuesKt.testSwiftNotThrowing(methods: SwiftNotThrowing())
do {
try bridge.foo2()
} catch let error as NSError {
try assertTrue(error.kotlinException is MyException)
}
do {
try bridge.foo3()
} catch let error as NSError {
try assertTrue(error.kotlinException is MyException)
}
do {
try bridge.foo4()
} catch let error as NSError {
try assertTrue(error.kotlinException is MyException)
}
do {
try ValuesKt.callFoo1(bridge: BridgeSwift())
} catch let error as BridgeSwift.Err {
// Ok
} catch {
try assertTrue(false)
try ValuesKt.callUnit(methods: SwiftThrowing())
} catch let e as SwiftThrowing.E {
// Ok.
}
try ValuesKt.callUnitCaller(caller: SwiftUnitCaller(), methods: throwing)
try ValuesKt.testSwiftThrowing(test: SwiftThrowingWithBridge(), flag: false)
try ValuesKt.testSwiftThrowing(test: SwiftThrowingWithBridge(), flag: true)
try ValuesKt.testSwiftNotThrowing(test: SwiftNotThrowingWithBridge())
}
func testFuncType() throws {