@testable import SwiftLintBuiltInRules import TestHelpers final class TypeContentsOrderRuleTests: SwiftLintTestCase { // swiftlint:disable:next function_body_length func testTypeContentsOrderReversedOrder() { // Test with reversed `order` entries let nonTriggeringExamples = [ Example([ "class TestViewController: UIViewController {", TypeContentsOrderRuleExamples.defaultOrderParts.reversed().joined(separator: "\n\n"), "}", ].joined(separator: "\n")), ] let triggeringExamples = [ Example(""" class TestViewController: UIViewController { // Type Aliases ↓typealias CompletionHandler = ((TestEnum) -> Void) // Subtypes class TestClass { // 10 lines } } """), Example(""" class TestViewController: UIViewController { // Subtypes ↓class TestClass { // 10 lines } // Stored Type Properties static let cellIdentifier: String = "AmazingCell" } """), Example(""" class TestViewController: UIViewController { // Stored Type Properties ↓static let cellIdentifier: String = "AmazingCell" // Stored Instance Properties var shouldLayoutView1: Bool! } """), Example(""" class TestViewController: UIViewController { // Computed Instance Properties private ↓var hasAnyLayoutedView: Bool { return hasLayoutedView1 || hasLayoutedView2 } // IBOutlets @IBOutlet private var view1: UIView! } """), Example(""" class TestViewController: UIViewController { // IBOutlets @IBOutlet private ↓var view1: UIView! // Initializers override ↓init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) } // deinitializer deinit { log.debug("deinit") } } """), Example(""" class TestViewController: UIViewController { // Type Methods ↓static func makeViewController() -> TestViewController { // some code } // View Life-Cycle Methods override func viewDidLoad() { super.viewDidLoad() view1.setNeedsLayout() view1.layoutIfNeeded() hasLayoutedView1 = true } } """), Example(""" class TestViewController: UIViewController { // View Life-Cycle Methods override ↓func viewDidLoad() { super.viewDidLoad() view1.setNeedsLayout() view1.layoutIfNeeded() hasLayoutedView1 = true } // IBActions @IBAction func goNextButtonPressed() { goToNextVc() delegate?.didPressTrackedButton() } } """), Example(""" class TestViewController: UIViewController { // IBActions @IBAction ↓func goNextButtonPressed() { goToNextVc() delegate?.didPressTrackedButton() } // Other Methods func goToNextVc() { /* TODO */ } } """), Example(""" class TestViewController: UIViewController { // MARK: Other Methods ↓func goToNextVc() { /* TODO */ } // Subscripts subscript(_ someIndexThatIsNotEvenUsed: Int) -> String { get { return "This is just a test" } set { log.warning("Just a test", newValue) } } } """), ] let reversedOrderDescription = TypeContentsOrderRule.description .with(triggeringExamples: triggeringExamples) .with(nonTriggeringExamples: nonTriggeringExamples) verifyRule( reversedOrderDescription, ruleConfiguration: [ "order": [ "deinitializer", "subscript", "other_method", "ib_action", "view_life_cycle_method", "type_method", "initializer", "ib_outlet", "ib_inspectable", "instance_property", "type_property", "subtype", ["type_alias", "associated_type"], "case", ] as [Any], ] ) } // swiftlint:disable:next function_body_length func testTypeContentsOrderGroupedOrder() { // Test with grouped `order` entries let nonTriggeringExamples = [ Example(""" class TestViewController: UIViewController { // Type Alias typealias CompletionHandler = ((TestClass) -> Void) // Subtype class TestClass { // 10 lines } // Type Alias typealias CompletionHandler2 = ((TestStruct) -> Void) // Subtype struct TestStruct { // 3 lines } // Type Alias typealias CompletionHandler3 = ((TestEnum) -> Void) // Subtype enum TestEnum { // 5 lines } // Instance Property var shouldLayoutView1: Bool! // Type Property static let cellIdentifier: String = "AmazingCell" // Instance Property weak var delegate: TestViewControllerDelegate? // IBOutlet @IBOutlet private var view1: UIView! // Instance Property private var hasLayoutedView1: Bool = false // IBOutlet @IBOutlet private var view2: UIView! // Initializer override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) } // Type Method static func makeViewController() -> TestViewController { // some code } // Initializer required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } // deinitializer deinit { log.debug("deinit") } // View Life-Cycle Method override func viewDidLoad() { super.viewDidLoad() view1.setNeedsLayout() view1.layoutIfNeeded() hasLayoutedView1 = true } // Other Method func goToInfoVc() { /* TODO */ } // Other Method func initInfoVc () { /* TODO */ } // IBAction @IBAction func goNextButtonPressed() { goToNextVc() delegate?.didPressTrackedButton() } // Other Methods func goToNextVc() { /* TODO */ } // Subscript subscript(_ someIndexThatIsNotEvenUsed: Int) -> String { get { return "This is just a test" } set { log.warning("Just a test", newValue) } } // Other Method private func getRandomVc() -> UIViewController { return UIViewController() } /// View Life-Cycle Method override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() view2.setNeedsLayout() view2.layoutIfNeeded() hasLayoutedView2 = true } @IBSegueAction func prepareForNextVc(_ coder: NSCoder) -> UIViewController? { getRandomVc() } } """), ] let triggeringExamples = [ Example(""" class TestViewController: UIViewController { // Type Alias typealias CompletionHandler = ((TestClass) -> Void) // Instance Property ↓var shouldLayoutView1: Bool! // deinitializer ↓deinit { log.debug("deinit") } // Subtype class TestClass { // 10 lines } } """), Example(""" class TestViewController: UIViewController { // Instance Property var shouldLayoutView1: Bool! // Initializer override ↓init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) } // Type Property static let cellIdentifier: String = "AmazingCell" } """), Example(""" class TestViewController: UIViewController { // Initializer override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) } // Other Method private ↓func getRandomVc() -> UIViewController { return UIViewController() } // Type Method static func makeViewController() -> TestViewController { // some code } } """), Example(""" class C { func f() {} @IBSegueAction ↓func foo(_ coder: NSCoder) -> UIViewController? { nil } @IBAction func bar() {} } """), ] let groupedOrderDescription = TypeContentsOrderRule.description .with(triggeringExamples: triggeringExamples) .with(nonTriggeringExamples: nonTriggeringExamples) verifyRule( groupedOrderDescription, ruleConfiguration: [ "order": [ ["type_alias", "associated_type", "subtype"], ["type_property", "instance_property", "ib_inspectable", "ib_outlet"], ["initializer", "type_method", "deinitializer"], ["view_life_cycle_method", "ib_action", "other_method", "subscript"], ["ib_segue_action"], ], ] ) } }