blob: 9a841b7f6622499441ef1bed3db76d588e935f78 [file] [log] [blame]
// RUN: %empty-directory(%t)
// RUN: %target-build-swift -swift-version 5 %s -o %t/a.out
// RUN: %target-codesign %t/a.out
//
// RUN: %target-run %t/a.out
// REQUIRES: executable_test
import StdlibUnittest
var ProtocolInitTestSuite = TestSuite("ProtocolInitClass")
func mustThrow<T>(_ f: () throws -> T) {
do {
_ = try f()
preconditionFailure("Didn't throw")
} catch {}
}
func mustFail<T>(f: () -> T?) {
if f() != nil {
preconditionFailure("Didn't fail")
}
}
enum E : Error { case X }
// This is the same as the protocol_initializers.swift test,
// but class-bound
protocol TriviallyConstructible : class {
init(x: LifetimeTracked)
init(x: LifetimeTracked, throwsDuring: Bool) throws
init?(x: LifetimeTracked, failsDuring: Bool)
}
extension TriviallyConstructible {
init(x: LifetimeTracked, throwsBefore: Bool) throws {
if throwsBefore {
throw E.X
}
self.init(x: x)
}
init(x: LifetimeTracked, throwsAfter: Bool) throws {
self.init(x: x)
if throwsAfter {
throw E.X
}
}
init(x: LifetimeTracked, throwsBefore: Bool, throwsDuring: Bool) throws {
if throwsBefore {
throw E.X
}
try self.init(x: x, throwsDuring: throwsDuring)
}
init(x: LifetimeTracked, throwsBefore: Bool, throwsAfter: Bool) throws {
if throwsBefore {
throw E.X
}
self.init(x: x)
if throwsAfter {
throw E.X
}
}
init(x: LifetimeTracked, throwsDuring: Bool, throwsAfter: Bool) throws {
try self.init(x: x, throwsDuring: throwsDuring)
if throwsAfter {
throw E.X
}
}
init(x: LifetimeTracked, throwsBefore: Bool, throwsDuring: Bool, throwsAfter: Bool) throws {
if throwsBefore {
throw E.X
}
try self.init(x: x, throwsDuring: throwsDuring)
if throwsAfter {
throw E.X
}
}
init?(x: LifetimeTracked, failsBefore: Bool) {
if failsBefore {
return nil
}
self.init(x: x)
}
init?(x: LifetimeTracked, failsAfter: Bool) {
self.init(x: x)
if failsAfter {
return nil
}
}
init?(x: LifetimeTracked, failsBefore: Bool, failsDuring: Bool) {
if failsBefore {
return nil
}
self.init(x: x, failsDuring: failsDuring)
}
init?(x: LifetimeTracked, failsBefore: Bool, failsAfter: Bool) {
if failsBefore {
return nil
}
self.init(x: x)
if failsAfter {
return nil
}
}
init?(x: LifetimeTracked, failsDuring: Bool, failsAfter: Bool) {
self.init(x: x, failsDuring: failsDuring)
if failsAfter {
return nil
}
}
init?(x: LifetimeTracked, failsBefore: Bool, failsDuring: Bool, failsAfter: Bool) {
if failsBefore {
return nil
}
self.init(x: x, failsDuring: failsDuring)
if failsAfter {
return nil
}
}
}
class TrivialClass : TriviallyConstructible {
let tracker: LifetimeTracked
// Protocol requirements
required init(x: LifetimeTracked) {
self.tracker = x
}
required convenience init(x: LifetimeTracked, throwsDuring: Bool) throws {
self.init(x: x)
if throwsDuring {
throw E.X
}
}
required convenience init?(x: LifetimeTracked, failsDuring: Bool) {
self.init(x: x)
if failsDuring {
return nil
}
}
// Class initializers delegating to protocol initializers
convenience init(throwsBefore: Bool) throws {
if throwsBefore {
throw E.X
}
self.init(x: LifetimeTracked(0))
}
convenience init(throwsAfter: Bool) throws {
self.init(x: LifetimeTracked(0))
if throwsAfter {
throw E.X
}
}
convenience init(throwsBefore: Bool, throwsDuring: Bool) throws {
if throwsBefore {
throw E.X
}
try self.init(x: LifetimeTracked(0), throwsDuring: throwsDuring)
}
convenience init(throwsBefore: Bool, throwsAfter: Bool) throws {
if throwsBefore {
throw E.X
}
self.init(x: LifetimeTracked(0))
if throwsAfter {
throw E.X
}
}
convenience init(throwsDuring: Bool, throwsAfter: Bool) throws {
try self.init(x: LifetimeTracked(0), throwsDuring: throwsDuring)
if throwsAfter {
throw E.X
}
}
convenience init(throwsBefore: Bool, throwsDuring: Bool, throwsAfter: Bool) throws {
if throwsBefore {
throw E.X
}
try self.init(x: LifetimeTracked(0), throwsDuring: throwsDuring)
if throwsAfter {
throw E.X
}
}
convenience init?(failsBefore: Bool) {
if failsBefore {
return nil
}
self.init(x: LifetimeTracked(0))
}
convenience init?(failsAfter: Bool) {
self.init(x: LifetimeTracked(0))
if failsAfter {
return nil
}
}
convenience init?(failsBefore: Bool, failsDuring: Bool) {
if failsBefore {
return nil
}
self.init(x: LifetimeTracked(0), failsDuring: failsDuring)
}
convenience init?(failsBefore: Bool, failsAfter: Bool) {
if failsBefore {
return nil
}
self.init(x: LifetimeTracked(0))
if failsAfter {
return nil
}
}
convenience init?(failsDuring: Bool, failsAfter: Bool) {
self.init(x: LifetimeTracked(0), failsDuring: failsDuring)
if failsAfter {
return nil
}
}
convenience init?(failsBefore: Bool, failsDuring: Bool, failsAfter: Bool) {
if failsBefore {
return nil
}
self.init(x: LifetimeTracked(0), failsDuring: failsDuring)
if failsAfter {
return nil
}
}
}
ProtocolInitTestSuite.test("ExtensionInit_Success") {
_ = try! TrivialClass(x: LifetimeTracked(0), throwsBefore: false)
_ = try! TrivialClass(x: LifetimeTracked(0), throwsAfter: false)
_ = try! TrivialClass(x: LifetimeTracked(0), throwsBefore: false, throwsDuring: false)
_ = try! TrivialClass(x: LifetimeTracked(0), throwsDuring: false, throwsAfter: false)
_ = try! TrivialClass(x: LifetimeTracked(0), throwsBefore: false, throwsAfter: false)
_ = try! TrivialClass(x: LifetimeTracked(0), throwsBefore: false, throwsDuring: false, throwsAfter: false)
_ = TrivialClass(x: LifetimeTracked(0), failsBefore: false)!
_ = TrivialClass(x: LifetimeTracked(0), failsAfter: false)!
_ = TrivialClass(x: LifetimeTracked(0), failsBefore: false, failsDuring: false)!
_ = TrivialClass(x: LifetimeTracked(0), failsDuring: false, failsAfter: false)!
_ = TrivialClass(x: LifetimeTracked(0), failsBefore: false, failsAfter: false)!
_ = TrivialClass(x: LifetimeTracked(0), failsBefore: false, failsDuring: false, failsAfter: false)!
}
ProtocolInitTestSuite.test("ClassInit_Success") {
_ = try! TrivialClass(throwsBefore: false)
_ = try! TrivialClass(throwsAfter: false)
_ = try! TrivialClass(throwsBefore: false, throwsDuring: false)
_ = try! TrivialClass(throwsDuring: false, throwsAfter: false)
_ = try! TrivialClass(throwsBefore: false, throwsAfter: false)
_ = try! TrivialClass(throwsBefore: false, throwsDuring: false, throwsAfter: false)
_ = TrivialClass(failsBefore: false)!
_ = TrivialClass(failsAfter: false)!
_ = TrivialClass(failsBefore: false, failsDuring: false)!
_ = TrivialClass(failsDuring: false, failsAfter: false)!
_ = TrivialClass(failsBefore: false, failsAfter: false)!
_ = TrivialClass(failsBefore: false, failsDuring: false, failsAfter: false)!
}
ProtocolInitTestSuite.test("ExtensionInit_Failure") {
mustThrow { try TrivialClass(x: LifetimeTracked(0), throwsBefore: true) }
mustThrow { try TrivialClass(x: LifetimeTracked(0), throwsAfter: true) }
mustThrow { try TrivialClass(x: LifetimeTracked(0), throwsBefore: true, throwsDuring: false) }
mustThrow { try TrivialClass(x: LifetimeTracked(0), throwsBefore: false, throwsDuring: true) }
mustThrow { try TrivialClass(x: LifetimeTracked(0), throwsDuring: true, throwsAfter: false) }
mustThrow { try TrivialClass(x: LifetimeTracked(0), throwsDuring: false, throwsAfter: true) }
mustThrow { try TrivialClass(x: LifetimeTracked(0), throwsBefore: true, throwsAfter: false) }
mustThrow { try TrivialClass(x: LifetimeTracked(0), throwsBefore: false, throwsAfter: true) }
mustThrow { try TrivialClass(x: LifetimeTracked(0), throwsBefore: true, throwsDuring: false, throwsAfter: false) }
mustThrow { try TrivialClass(x: LifetimeTracked(0), throwsBefore: false, throwsDuring: true, throwsAfter: false) }
mustThrow { try TrivialClass(x: LifetimeTracked(0), throwsBefore: false, throwsDuring: false, throwsAfter: true) }
mustFail { TrivialClass(x: LifetimeTracked(0), failsBefore: true) }
mustFail { TrivialClass(x: LifetimeTracked(0), failsAfter: true) }
mustFail { TrivialClass(x: LifetimeTracked(0), failsBefore: true, failsDuring: false) }
mustFail { TrivialClass(x: LifetimeTracked(0), failsBefore: false, failsDuring: true) }
mustFail { TrivialClass(x: LifetimeTracked(0), failsDuring: true, failsAfter: false) }
mustFail { TrivialClass(x: LifetimeTracked(0), failsDuring: false, failsAfter: true) }
mustFail { TrivialClass(x: LifetimeTracked(0), failsBefore: true, failsAfter: false) }
mustFail { TrivialClass(x: LifetimeTracked(0), failsBefore: false, failsAfter: true) }
mustFail { TrivialClass(x: LifetimeTracked(0), failsBefore: true, failsDuring: false, failsAfter: false) }
mustFail { TrivialClass(x: LifetimeTracked(0), failsBefore: false, failsDuring: true, failsAfter: false) }
mustFail { TrivialClass(x: LifetimeTracked(0), failsBefore: false, failsDuring: false, failsAfter: true) }
}
ProtocolInitTestSuite.test("ClassInit_Failure") {
mustThrow { try TrivialClass(throwsBefore: true) }
mustThrow { try TrivialClass(throwsAfter: true) }
mustThrow { try TrivialClass(throwsBefore: true, throwsDuring: false) }
mustThrow { try TrivialClass(throwsBefore: false, throwsDuring: true) }
mustThrow { try TrivialClass(throwsDuring: true, throwsAfter: false) }
mustThrow { try TrivialClass(throwsDuring: false, throwsAfter: true) }
mustThrow { try TrivialClass(throwsBefore: true, throwsAfter: false) }
mustThrow { try TrivialClass(throwsBefore: false, throwsAfter: true) }
mustThrow { try TrivialClass(throwsBefore: true, throwsDuring: false, throwsAfter: false) }
mustThrow { try TrivialClass(throwsBefore: false, throwsDuring: true, throwsAfter: false) }
mustThrow { try TrivialClass(throwsBefore: false, throwsDuring: false, throwsAfter: true) }
mustFail { TrivialClass(failsBefore: true) }
mustFail { TrivialClass(failsAfter: true) }
mustFail { TrivialClass(failsBefore: true, failsDuring: false) }
mustFail { TrivialClass(failsBefore: false, failsDuring: true) }
mustFail { TrivialClass(failsDuring: true, failsAfter: false) }
mustFail { TrivialClass(failsDuring: false, failsAfter: true) }
mustFail { TrivialClass(failsBefore: true, failsAfter: false) }
mustFail { TrivialClass(failsBefore: false, failsAfter: true) }
mustFail { TrivialClass(failsBefore: true, failsDuring: false, failsAfter: false) }
mustFail { TrivialClass(failsBefore: false, failsDuring: true, failsAfter: false) }
mustFail { TrivialClass(failsBefore: false, failsDuring: false, failsAfter: true) }
}
runAllTests()