1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
|
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
@_spi(Rules) import SwiftFormat
import _SwiftFormatTestSupport
final class OneCasePerLineTests: LintOrFormatRuleTestCase {
// The inconsistent leading whitespace in the expected text is intentional. This transform does
// not attempt to preserve leading indentation since the pretty printer will correct it when
// running the full formatter.
func testInvalidCasesOnLine() {
assertFormatting(
OneCasePerLine.self,
input: """
public enum Token {
case arrow
case comma, 1️⃣identifier(String), semicolon, 2️⃣stringSegment(String)
case period
case 3️⃣ifKeyword(String), 4️⃣forKeyword(String)
indirect case guardKeyword, elseKeyword, 5️⃣contextualKeyword(String)
var x: Bool
case leftParen, 6️⃣rightParen = ")", leftBrace, 7️⃣rightBrace = "}"
}
""",
expected: """
public enum Token {
case arrow
case comma
case identifier(String)
case semicolon
case stringSegment(String)
case period
case ifKeyword(String)
case forKeyword(String)
indirect case guardKeyword, elseKeyword
indirect case contextualKeyword(String)
var x: Bool
case leftParen
case rightParen = ")"
case leftBrace
case rightBrace = "}"
}
""",
findings: [
FindingSpec("1️⃣", message: "move 'identifier' to its own 'case' declaration"),
FindingSpec("2️⃣", message: "move 'stringSegment' to its own 'case' declaration"),
FindingSpec("3️⃣", message: "move 'ifKeyword' to its own 'case' declaration"),
FindingSpec("4️⃣", message: "move 'forKeyword' to its own 'case' declaration"),
FindingSpec("5️⃣", message: "move 'contextualKeyword' to its own 'case' declaration"),
FindingSpec("6️⃣", message: "move 'rightParen' to its own 'case' declaration"),
FindingSpec("7️⃣", message: "move 'rightBrace' to its own 'case' declaration"),
]
)
}
func testElementOrderIsPreserved() {
assertFormatting(
OneCasePerLine.self,
input: """
enum Foo: Int {
case 1️⃣a = 0, b, c, d
}
""",
expected: """
enum Foo: Int {
case a = 0
case b, c, d
}
""",
findings: [
FindingSpec("1️⃣", message: "move 'a' to its own 'case' declaration")
]
)
}
func testCommentsAreNotRepeated() {
assertFormatting(
OneCasePerLine.self,
input: """
enum Foo: Int {
/// This should only be above `a`.
case 1️⃣a = 0, b, c, d
// This should only be above `e`.
case e, 2️⃣f = 100
}
""",
expected: """
enum Foo: Int {
/// This should only be above `a`.
case a = 0
case b, c, d
// This should only be above `e`.
case e
case f = 100
}
""",
findings: [
FindingSpec("1️⃣", message: "move 'a' to its own 'case' declaration"),
FindingSpec("2️⃣", message: "move 'f' to its own 'case' declaration"),
]
)
}
func testAttributesArePropagated() {
assertFormatting(
OneCasePerLine.self,
input: """
enum Foo {
@someAttr case 1️⃣a(String), b, c, d
case e, 2️⃣f(Int)
@anotherAttr case g, 3️⃣h(Float)
}
""",
expected: """
enum Foo {
@someAttr case a(String)
@someAttr case b, c, d
case e
case f(Int)
@anotherAttr case g
@anotherAttr case h(Float)
}
""",
findings: [
FindingSpec("1️⃣", message: "move 'a' to its own 'case' declaration"),
FindingSpec("2️⃣", message: "move 'f' to its own 'case' declaration"),
FindingSpec("3️⃣", message: "move 'h' to its own 'case' declaration"),
]
)
}
}
|