// RUN: %target-run-simple-swift(-swift-version 4) // RUN: %target-run-simple-swift(-swift-version 5) // REQUIRES: executable_test import StdlibUnittest var ProtocolInitTestSuite = TestSuite("ProtocolInitClass") func mustThrow(_ f: () throws -> T) { do { _ = try f() preconditionFailure("Didn't throw") } catch {} } func mustFail(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()