mirror of
https://github.com/nicklockwood/SwiftFormat.git
synced 2026-05-17 10:30:35 +00:00
357efe0348
Co-authored-by: calda <1811727+calda@users.noreply.github.com>
818 lines
20 KiB
Swift
818 lines
20 KiB
Swift
// Created by Cal Stephens on 10/16/25.
|
|
// Copyright © 2025 Nick Lockwood. All rights reserved.
|
|
|
|
import XCTest
|
|
@testable import SwiftFormat
|
|
|
|
final class TestSuiteAccessControlTests: XCTestCase {
|
|
// MARK: XCTest
|
|
|
|
func testXCTestMethodsAreInternal() {
|
|
let input = """
|
|
import XCTest
|
|
|
|
final class MyTests: XCTestCase {
|
|
public func testExample() {
|
|
XCTAssertTrue(true)
|
|
}
|
|
|
|
private func testHelper() {
|
|
XCTAssertTrue(true)
|
|
}
|
|
}
|
|
"""
|
|
|
|
let output = """
|
|
import XCTest
|
|
|
|
final class MyTests: XCTestCase {
|
|
func testExample() {
|
|
XCTAssertTrue(true)
|
|
}
|
|
|
|
private func testHelper() {
|
|
XCTAssertTrue(true)
|
|
}
|
|
}
|
|
"""
|
|
|
|
testFormatting(for: input, output, rule: .testSuiteAccessControl, exclude: [.unusedArguments, .validateTestCases])
|
|
}
|
|
|
|
func testXCTestHelperMethodsArePrivate() {
|
|
let input = """
|
|
import XCTest
|
|
|
|
final class MyTests: XCTestCase {
|
|
func testExample() {
|
|
helperMethod(arg: 0)
|
|
}
|
|
|
|
func helperMethod(arg: Int) {
|
|
// helper code
|
|
}
|
|
|
|
public func publicHelper(arg: Int) {
|
|
// helper code
|
|
}
|
|
}
|
|
"""
|
|
|
|
let output = """
|
|
import XCTest
|
|
|
|
final class MyTests: XCTestCase {
|
|
func testExample() {
|
|
helperMethod(arg: 0)
|
|
}
|
|
|
|
private func helperMethod(arg: Int) {
|
|
// helper code
|
|
}
|
|
|
|
private func publicHelper(arg: Int) {
|
|
// helper code
|
|
}
|
|
}
|
|
"""
|
|
|
|
testFormatting(for: input, output, rule: .testSuiteAccessControl, exclude: [.unusedArguments, .validateTestCases])
|
|
}
|
|
|
|
func testXCTestPropertiesArePrivate() {
|
|
let input = """
|
|
import XCTest
|
|
|
|
final class MyTests: XCTestCase {
|
|
var someProperty: String = ""
|
|
public var anotherProperty: Int = 0
|
|
|
|
func testExample() {
|
|
XCTAssertEqual(someProperty, "")
|
|
}
|
|
}
|
|
"""
|
|
|
|
let output = """
|
|
import XCTest
|
|
|
|
final class MyTests: XCTestCase {
|
|
private var someProperty: String = ""
|
|
private var anotherProperty: Int = 0
|
|
|
|
func testExample() {
|
|
XCTAssertEqual(someProperty, "")
|
|
}
|
|
}
|
|
"""
|
|
|
|
testFormatting(for: input, output, rule: .testSuiteAccessControl, exclude: [.unusedArguments, .validateTestCases])
|
|
}
|
|
|
|
func testXCTestClassIsInternal() {
|
|
let input = """
|
|
import XCTest
|
|
|
|
public final class MyTests: XCTestCase {
|
|
func testExample() {
|
|
XCTAssertTrue(true)
|
|
}
|
|
}
|
|
"""
|
|
|
|
let output = """
|
|
import XCTest
|
|
|
|
final class MyTests: XCTestCase {
|
|
func testExample() {
|
|
XCTAssertTrue(true)
|
|
}
|
|
}
|
|
"""
|
|
|
|
testFormatting(for: input, output, rule: .testSuiteAccessControl, exclude: [.unusedArguments, .validateTestCases])
|
|
}
|
|
|
|
func testXCTestWithParameterlessInitializerIsProcessed() {
|
|
let input = """
|
|
import XCTest
|
|
|
|
final class MyTests: XCTestCase {
|
|
private let dependency: Dependency = Dependency()
|
|
|
|
public init() {
|
|
// Custom initialization
|
|
}
|
|
|
|
func testExample() {
|
|
XCTAssertTrue(true)
|
|
}
|
|
}
|
|
"""
|
|
|
|
let output = """
|
|
import XCTest
|
|
|
|
final class MyTests: XCTestCase {
|
|
private let dependency: Dependency = Dependency()
|
|
|
|
init() {
|
|
// Custom initialization
|
|
}
|
|
|
|
func testExample() {
|
|
XCTAssertTrue(true)
|
|
}
|
|
}
|
|
"""
|
|
|
|
testFormatting(for: input, output, rule: .testSuiteAccessControl, exclude: [.unusedArguments, .validateTestCases, .redundantType])
|
|
}
|
|
|
|
func testXCTestPreservesOpenTestClass() {
|
|
let input = """
|
|
import XCTest
|
|
|
|
open class MyTests: XCTestCase {
|
|
func testExample() {
|
|
XCTAssertTrue(true)
|
|
}
|
|
}
|
|
"""
|
|
|
|
testFormatting(for: input, rule: .testSuiteAccessControl, exclude: [.unusedArguments, .validateTestCases])
|
|
}
|
|
|
|
func testXCTestPreservesStaticFunctions() {
|
|
let input = """
|
|
import XCTest
|
|
|
|
final class MyTests: XCTestCase {
|
|
func testExample() {
|
|
XCTAssertTrue(true)
|
|
}
|
|
|
|
static func helperMethod() {
|
|
// helper code
|
|
}
|
|
}
|
|
"""
|
|
|
|
testFormatting(for: input, rule: .testSuiteAccessControl, exclude: [.unusedArguments, .validateTestCases])
|
|
}
|
|
|
|
func testXCTestPreservesStaticProperties() {
|
|
let input = """
|
|
import XCTest
|
|
|
|
final class MyTests: XCTestCase {
|
|
static var sharedState: String = ""
|
|
|
|
func testExample() {
|
|
XCTAssertEqual(Self.sharedState, "")
|
|
}
|
|
}
|
|
"""
|
|
|
|
testFormatting(for: input, rule: .testSuiteAccessControl, exclude: [.unusedArguments, .validateTestCases])
|
|
}
|
|
|
|
func testXCTestPreservesOverrideMethods() {
|
|
let input = """
|
|
import XCTest
|
|
|
|
class BaseTestCase: XCTestCase {
|
|
func setUp() {
|
|
// setup code
|
|
}
|
|
}
|
|
|
|
class MyTests: BaseTestCase {
|
|
override func setUp() {
|
|
super.setUp()
|
|
}
|
|
|
|
func testExample() {
|
|
XCTAssertTrue(true)
|
|
}
|
|
}
|
|
"""
|
|
|
|
testFormatting(for: input, rule: .testSuiteAccessControl, exclude: [.unusedArguments, .validateTestCases])
|
|
}
|
|
|
|
func testXCTestPreservesObjcMethods() {
|
|
let input = """
|
|
import XCTest
|
|
|
|
final class MyTests: XCTestCase {
|
|
@objc func helperMethod() {
|
|
// helper code
|
|
}
|
|
|
|
func testExample() {
|
|
XCTAssertTrue(true)
|
|
}
|
|
}
|
|
"""
|
|
|
|
testFormatting(for: input, rule: .testSuiteAccessControl, exclude: [.unusedArguments, .validateTestCases])
|
|
}
|
|
|
|
func testXCTestHelperMethodWithTestPrefixAndParameters() {
|
|
let input = """
|
|
import XCTest
|
|
|
|
final class MyTests: XCTestCase {
|
|
func testExample() {
|
|
testHelper(value: 5)
|
|
}
|
|
|
|
func testHelper(value: Int) {
|
|
XCTAssertEqual(value, 5)
|
|
}
|
|
|
|
func testFormatter(string: String) -> String {
|
|
return string.uppercased()
|
|
}
|
|
}
|
|
"""
|
|
|
|
let output = """
|
|
import XCTest
|
|
|
|
final class MyTests: XCTestCase {
|
|
func testExample() {
|
|
testHelper(value: 5)
|
|
}
|
|
|
|
private func testHelper(value: Int) {
|
|
XCTAssertEqual(value, 5)
|
|
}
|
|
|
|
private func testFormatter(string: String) -> String {
|
|
return string.uppercased()
|
|
}
|
|
}
|
|
"""
|
|
|
|
testFormatting(for: input, output, rule: .testSuiteAccessControl, exclude: [.unusedArguments, .validateTestCases])
|
|
}
|
|
|
|
// MARK: Swift Testing
|
|
|
|
func testSwiftTestingPropertiesArePrivate() {
|
|
let input = """
|
|
import Testing
|
|
|
|
struct MyFeatureTests {
|
|
var someProperty: String = ""
|
|
public var anotherProperty: Int = 0
|
|
|
|
@Test func featureWorks() {
|
|
#expect(someProperty == "")
|
|
}
|
|
}
|
|
"""
|
|
|
|
let output = """
|
|
import Testing
|
|
|
|
struct MyFeatureTests {
|
|
private var someProperty: String = ""
|
|
private var anotherProperty: Int = 0
|
|
|
|
@Test func featureWorks() {
|
|
#expect(someProperty == "")
|
|
}
|
|
}
|
|
"""
|
|
|
|
testFormatting(for: input, output, rule: .testSuiteAccessControl, exclude: [.unusedArguments, .validateTestCases])
|
|
}
|
|
|
|
func testSwiftTestingHelperMethodsArePrivate() {
|
|
let input = """
|
|
import Testing
|
|
|
|
struct MyFeatureTests {
|
|
@Test func featureWorks() {
|
|
helperMethod()
|
|
}
|
|
|
|
func helperMethod() {
|
|
// helper code
|
|
}
|
|
|
|
public func publicHelper() {
|
|
// helper code
|
|
}
|
|
}
|
|
"""
|
|
|
|
let output = """
|
|
import Testing
|
|
|
|
struct MyFeatureTests {
|
|
@Test func featureWorks() {
|
|
helperMethod()
|
|
}
|
|
|
|
private func helperMethod() {
|
|
// helper code
|
|
}
|
|
|
|
private func publicHelper() {
|
|
// helper code
|
|
}
|
|
}
|
|
"""
|
|
|
|
testFormatting(for: input, output, rule: .testSuiteAccessControl, exclude: [.unusedArguments, .validateTestCases])
|
|
}
|
|
|
|
func testSwiftTestingClassIsInternal() {
|
|
let input = """
|
|
import Testing
|
|
|
|
public struct MyFeatureTests {
|
|
@Test func featureWorks() {
|
|
#expect(true)
|
|
}
|
|
}
|
|
"""
|
|
|
|
let output = """
|
|
import Testing
|
|
|
|
struct MyFeatureTests {
|
|
@Test func featureWorks() {
|
|
#expect(true)
|
|
}
|
|
}
|
|
"""
|
|
|
|
testFormatting(for: input, output, rule: .testSuiteAccessControl, exclude: [.unusedArguments, .validateTestCases])
|
|
}
|
|
|
|
func testSwiftTestingPrivateTestFunctionsAreMadeInternal() {
|
|
let input = """
|
|
import Testing
|
|
|
|
struct MyFeatureTests {
|
|
@Test private func featureWorks() {
|
|
#expect(true)
|
|
}
|
|
|
|
@Test fileprivate func anotherFeature() {
|
|
#expect(true)
|
|
}
|
|
}
|
|
"""
|
|
|
|
let output = """
|
|
import Testing
|
|
|
|
struct MyFeatureTests {
|
|
@Test func featureWorks() {
|
|
#expect(true)
|
|
}
|
|
|
|
@Test func anotherFeature() {
|
|
#expect(true)
|
|
}
|
|
}
|
|
"""
|
|
|
|
testFormatting(for: input, output, rule: .testSuiteAccessControl, exclude: [.unusedArguments, .validateTestCases])
|
|
}
|
|
|
|
// MARK: Base Classes
|
|
|
|
func testDoesNotApplyToBaseTestClasses() {
|
|
let input = """
|
|
import XCTest
|
|
|
|
public class MyFeatureTestsBase: XCTestCase {
|
|
public func helperMethod() {
|
|
// helper code
|
|
}
|
|
|
|
public var someProperty: String = ""
|
|
}
|
|
"""
|
|
|
|
testFormatting(for: input, rule: .testSuiteAccessControl, exclude: [.unusedArguments, .validateTestCases])
|
|
}
|
|
|
|
func testDoesNotApplyToSwiftTestingBaseClasses() {
|
|
let input = """
|
|
import Testing
|
|
|
|
public class MyFeatureTestsBase {
|
|
public func helperMethod() {
|
|
// helper code
|
|
}
|
|
|
|
public var someProperty: String = ""
|
|
}
|
|
"""
|
|
|
|
testFormatting(for: input, rule: .testSuiteAccessControl, exclude: [.unusedArguments, .validateTestCases])
|
|
}
|
|
|
|
func testDoesNotApplyToTestClassWithBaseInDocComment() {
|
|
let input = """
|
|
import XCTest
|
|
|
|
/// Base class for feature tests.
|
|
public class MyFeatureTests: XCTestCase {
|
|
public func helperMethod() {
|
|
// helper code
|
|
}
|
|
|
|
public var someProperty: String = ""
|
|
}
|
|
"""
|
|
|
|
testFormatting(for: input, rule: .testSuiteAccessControl, exclude: [.unusedArguments, .validateTestCases])
|
|
}
|
|
|
|
func testDoesNotApplyToTestClassWithSubclassInDocComment() {
|
|
let input = """
|
|
import XCTest
|
|
|
|
/// Intended to be subclassed for specific feature tests.
|
|
public class MyFeatureTests: XCTestCase {
|
|
public func helperMethod() {
|
|
// helper code
|
|
}
|
|
|
|
public var someProperty: String = ""
|
|
}
|
|
"""
|
|
|
|
testFormatting(for: input, rule: .testSuiteAccessControl, exclude: [.unusedArguments, .validateTestCases])
|
|
}
|
|
|
|
func testDoesNotApplyToSwiftTestingClassWithBaseInDocComment() {
|
|
let input = """
|
|
import Testing
|
|
|
|
/// Base struct for testing features.
|
|
public struct MyFeatureTests {
|
|
public func helperMethod() {
|
|
// helper code
|
|
}
|
|
}
|
|
"""
|
|
|
|
testFormatting(for: input, rule: .testSuiteAccessControl, exclude: [.unusedArguments, .validateTestCases])
|
|
}
|
|
|
|
// MARK: Disabled Tests
|
|
|
|
func testXCTestPreservesDisabledTestMethods() {
|
|
let input = """
|
|
import XCTest
|
|
|
|
final class MyTests: XCTestCase {
|
|
func disable_testExample() {
|
|
XCTAssertTrue(true)
|
|
}
|
|
|
|
func skip_testFeature() {
|
|
XCTAssertTrue(false)
|
|
}
|
|
}
|
|
"""
|
|
|
|
testFormatting(for: input, rule: .testSuiteAccessControl, exclude: [.unusedArguments, .validateTestCases])
|
|
}
|
|
|
|
func testSwiftTestingPreservesDisabledTestMethods() {
|
|
let input = """
|
|
import Testing
|
|
|
|
struct MyFeatureTests {
|
|
func disable_featureWorks() {
|
|
#expect(true)
|
|
}
|
|
|
|
func x_edgeCaseHandling() {
|
|
#expect(false)
|
|
}
|
|
}
|
|
"""
|
|
|
|
testFormatting(for: input, rule: .testSuiteAccessControl, exclude: [.unusedArguments, .validateTestCases])
|
|
}
|
|
|
|
func testXCTestPreservesCapitalizedDisabledTestMethods() {
|
|
let input = """
|
|
import XCTest
|
|
|
|
final class MyTests: XCTestCase {
|
|
func X_testExample() {
|
|
XCTAssertTrue(true)
|
|
}
|
|
|
|
func DISABLE_testFeature() {
|
|
XCTAssertTrue(false)
|
|
}
|
|
}
|
|
"""
|
|
|
|
testFormatting(for: input, rule: .testSuiteAccessControl, exclude: [.unusedArguments, .validateTestCases])
|
|
}
|
|
|
|
func testSwiftTestingPreservesCapitalizedDisabledTestMethods() {
|
|
let input = """
|
|
import Testing
|
|
|
|
struct MyFeatureTests {
|
|
func SKIP_featureWorks() {
|
|
#expect(true)
|
|
}
|
|
|
|
func DISABLED_edgeCaseHandling() {
|
|
#expect(false)
|
|
}
|
|
}
|
|
"""
|
|
|
|
testFormatting(for: input, rule: .testSuiteAccessControl, exclude: [.unusedArguments, .validateTestCases])
|
|
}
|
|
|
|
// MARK: Mixed Frameworks
|
|
|
|
func testDoesNotApplyWhenBothTestingFrameworksAreImported() {
|
|
let input = """
|
|
import XCTest
|
|
import Testing
|
|
|
|
final class MyTests: XCTestCase {
|
|
func testExample() {
|
|
XCTAssertTrue(true)
|
|
}
|
|
|
|
func helperMethod() {
|
|
// helper code
|
|
}
|
|
|
|
var someProperty: String = ""
|
|
}
|
|
"""
|
|
|
|
testFormatting(for: input, rule: .testSuiteAccessControl, exclude: [.unusedArguments, .validateTestCases, .sortImports])
|
|
}
|
|
|
|
func testXCTestIgnoresTypesWithParameterizedInit() {
|
|
let input = """
|
|
import XCTest
|
|
|
|
final class MyHelperClass: XCTestCase {
|
|
let dependency: String
|
|
|
|
init(dependency: String) {
|
|
self.dependency = dependency
|
|
}
|
|
|
|
func example() {
|
|
XCTAssertTrue(true)
|
|
}
|
|
}
|
|
"""
|
|
|
|
// No changes should be made - types with parameterized init are not test suites
|
|
testFormatting(for: input, rule: .testSuiteAccessControl, exclude: [.unusedArguments, .validateTestCases])
|
|
}
|
|
|
|
func testSwiftTestingIgnoresTypesWithParameterizedInit() {
|
|
let input = """
|
|
import Testing
|
|
|
|
struct MyHelperStruct {
|
|
let dependency: String
|
|
|
|
init(dependency: String) {
|
|
self.dependency = dependency
|
|
}
|
|
|
|
func example() {
|
|
#expect(true)
|
|
}
|
|
}
|
|
"""
|
|
|
|
// No changes should be made - types with parameterized init are not test suites
|
|
testFormatting(for: input, rule: .testSuiteAccessControl, exclude: [.unusedArguments, .validateTestCases, .redundantMemberwiseInit])
|
|
}
|
|
|
|
func testSwiftTestingPrivateVisibilityOption() {
|
|
let input = """
|
|
import Testing
|
|
|
|
struct MyFeatureTests {
|
|
@Test func featureWorks() {
|
|
#expect(true)
|
|
}
|
|
|
|
func helperMethod() {
|
|
// helper code
|
|
}
|
|
}
|
|
"""
|
|
|
|
let output = """
|
|
import Testing
|
|
|
|
private struct MyFeatureTests {
|
|
@Test private func featureWorks() {
|
|
#expect(true)
|
|
}
|
|
|
|
private func helperMethod() {
|
|
// helper code
|
|
}
|
|
}
|
|
"""
|
|
|
|
let options = FormatOptions(testCaseAccessControl: .private)
|
|
testFormatting(for: input, output, rule: .testSuiteAccessControl, options: options, exclude: [.unusedArguments])
|
|
}
|
|
|
|
func testSwiftTestingPublicVisibilityOption() {
|
|
let input = """
|
|
import Testing
|
|
|
|
struct MyFeatureTests {
|
|
@Test func featureWorks() {
|
|
#expect(true)
|
|
}
|
|
|
|
func helperMethod() {
|
|
// helper code
|
|
}
|
|
}
|
|
"""
|
|
|
|
let output = """
|
|
import Testing
|
|
|
|
public struct MyFeatureTests {
|
|
@Test public func featureWorks() {
|
|
#expect(true)
|
|
}
|
|
|
|
private func helperMethod() {
|
|
// helper code
|
|
}
|
|
}
|
|
"""
|
|
|
|
let options = FormatOptions(testCaseAccessControl: .public)
|
|
testFormatting(for: input, output, rule: .testSuiteAccessControl, options: options, exclude: [.unusedArguments])
|
|
}
|
|
|
|
func testXCTestPrivateVisibilityFallsBackToInternal() {
|
|
let input = """
|
|
import XCTest
|
|
|
|
final class MyTests: XCTestCase {
|
|
public func testExample() {
|
|
XCTAssertTrue(true)
|
|
}
|
|
|
|
func helperMethod() {
|
|
// helper code
|
|
}
|
|
}
|
|
"""
|
|
|
|
let output = """
|
|
import XCTest
|
|
|
|
final class MyTests: XCTestCase {
|
|
func testExample() {
|
|
XCTAssertTrue(true)
|
|
}
|
|
|
|
private func helperMethod() {
|
|
// helper code
|
|
}
|
|
}
|
|
"""
|
|
|
|
// XCTest doesn't support private tests, so private/fileprivate falls back to internal
|
|
let options = FormatOptions(testCaseAccessControl: .private)
|
|
testFormatting(for: input, output, rule: .testSuiteAccessControl, options: options, exclude: [.unusedArguments])
|
|
}
|
|
|
|
func testXCTestFileprivateVisibilityFallsBackToInternal() {
|
|
let input = """
|
|
import XCTest
|
|
|
|
final class MyTests: XCTestCase {
|
|
public func testExample() {
|
|
XCTAssertTrue(true)
|
|
}
|
|
}
|
|
"""
|
|
|
|
let output = """
|
|
import XCTest
|
|
|
|
final class MyTests: XCTestCase {
|
|
func testExample() {
|
|
XCTAssertTrue(true)
|
|
}
|
|
}
|
|
"""
|
|
|
|
// XCTest doesn't support fileprivate tests, so fileprivate falls back to internal
|
|
let options = FormatOptions(testCaseAccessControl: .fileprivate)
|
|
testFormatting(for: input, output, rule: .testSuiteAccessControl, options: options, exclude: [.unusedArguments])
|
|
}
|
|
|
|
func testSwiftTestingFileprivateVisibilityOption() {
|
|
let input = """
|
|
import Testing
|
|
|
|
struct MyFeatureTests {
|
|
@Test func featureWorks() {
|
|
#expect(true)
|
|
}
|
|
}
|
|
"""
|
|
|
|
let output = """
|
|
import Testing
|
|
|
|
fileprivate struct MyFeatureTests {
|
|
@Test fileprivate func featureWorks() {
|
|
#expect(true)
|
|
}
|
|
}
|
|
"""
|
|
|
|
let options = FormatOptions(testCaseAccessControl: .fileprivate)
|
|
testFormatting(for: input, output, rule: .testSuiteAccessControl, options: options, exclude: [.unusedArguments])
|
|
}
|
|
|
|
func testSwiftTestingPrivateVisibilityPreservesExistingPrivate() {
|
|
let input = """
|
|
import Testing
|
|
|
|
private struct MyFeatureTests {
|
|
@Test private func featureWorks() {
|
|
#expect(true)
|
|
}
|
|
}
|
|
"""
|
|
|
|
let options = FormatOptions(testCaseAccessControl: .private)
|
|
testFormatting(for: input, rule: .testSuiteAccessControl, options: options, exclude: [.unusedArguments])
|
|
}
|
|
}
|