Files
SwiftLint/Tests/BuiltInRulesTests/TypeContentsOrderRuleTests.swift
Danny Mösch 15b285527a Separate built-in rule tests from framework tests (#5924)
* Short names for test modules
* Lint plugins and `Package.swift` in integration tests
* Simplify and merge file groups in Bazel
* Move common functions to `TestHelpers`
2024-12-30 12:26:46 +01:00

369 lines
12 KiB
Swift

@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"],
],
]
)
}
}