mirror of
https://github.com/nicklockwood/SwiftFormat.git
synced 2026-06-16 10:34:34 +00:00
341 lines
9.4 KiB
Swift
341 lines
9.4 KiB
Swift
//
|
|
// WrapMultilineFunctionChainsTests.swift
|
|
// SwiftFormat
|
|
//
|
|
// Created by Eric Horacek on 2/20/25.
|
|
// Copyright © 2025 Nick Lockwood. All rights reserved.
|
|
//
|
|
|
|
import XCTest
|
|
@testable import SwiftFormat
|
|
|
|
final class WrapMultilineFunctionChainsTests: XCTestCase {
|
|
func testWrapIfExpressionAssignment() {
|
|
let input = """
|
|
let evenSquaresSum = [20, 17, 35, 4]
|
|
.filter { $0 % 2 == 0 }.map { $0 * $0 }
|
|
.reduce(0, +)
|
|
"""
|
|
|
|
let output = """
|
|
let evenSquaresSum = [20, 17, 35, 4]
|
|
.filter { $0 % 2 == 0 }
|
|
.map { $0 * $0 }
|
|
.reduce(0, +)
|
|
"""
|
|
|
|
testFormatting(for: input, [output], rules: [.wrapMultilineFunctionChains, .indent])
|
|
}
|
|
|
|
func testWrapMultipleFunctionCalls() {
|
|
let input = """
|
|
let result = array
|
|
.first?.map { $0 * 2 }.filter { $0 > 10 }
|
|
.reduce(0, +)
|
|
"""
|
|
|
|
let output = """
|
|
let result = array
|
|
.first?
|
|
.map { $0 * 2 }
|
|
.filter { $0 > 10 }
|
|
.reduce(0, +)
|
|
"""
|
|
|
|
testFormatting(for: input, [output], rules: [.wrapMultilineFunctionChains, .indent])
|
|
}
|
|
|
|
func testWrapSingleFunctionCall() {
|
|
let input = """
|
|
let result = array.map { $0 * 2 }
|
|
"""
|
|
|
|
testFormatting(for: input, [], rules: [.wrapMultilineFunctionChains, .indent])
|
|
}
|
|
|
|
func testWrapNestedFunctionCallsWithTrailingClosures() {
|
|
let input = """
|
|
let result = array
|
|
.map { $0.filter { $1 > 10 } }.flatMap { $0 }
|
|
"""
|
|
|
|
let output = """
|
|
let result = array
|
|
.map { $0.filter { $1 > 10 } }
|
|
.flatMap { $0 }
|
|
"""
|
|
|
|
testFormatting(for: input, [output], rules: [.wrapMultilineFunctionChains, .indent])
|
|
}
|
|
|
|
func testWrapNestedFunctionCallsWithClosureParameters() {
|
|
let input = """
|
|
let result = array
|
|
.map { $0.reduce(0, +) }.flatMap { $0 }
|
|
"""
|
|
|
|
let output = """
|
|
let result = array
|
|
.map { $0.reduce(0, +) }
|
|
.flatMap { $0 }
|
|
"""
|
|
|
|
testFormatting(for: input, [output], rules: [.wrapMultilineFunctionChains, .indent])
|
|
}
|
|
|
|
func testWrapFunctionCallsWithComments() {
|
|
let input = """
|
|
let result = array
|
|
.map { $0 * 2 } // multiply by 2
|
|
.filter { $0 > 10 } // filter greater than 10
|
|
.reduce(0, +) // sum up
|
|
"""
|
|
|
|
testFormatting(for: input, [], rules: [.wrapMultilineFunctionChains, .indent])
|
|
}
|
|
|
|
func testWrapFunctionCallsWithPropertyAccess() {
|
|
let input = """
|
|
let result = array
|
|
.first?.property.map { $0 * 2 }.filter { $0 > 10 }
|
|
.reduce(0, +)
|
|
"""
|
|
|
|
let output = """
|
|
let result = array
|
|
.first?
|
|
.property
|
|
.map { $0 * 2 }
|
|
.filter { $0 > 10 }
|
|
.reduce(0, +)
|
|
"""
|
|
|
|
testFormatting(for: input, [output], rules: [.wrapMultilineFunctionChains, .indent])
|
|
}
|
|
|
|
func testWrapFunctionCallsWithMultiplePropertyAccesses() {
|
|
let input = """
|
|
let result = array
|
|
.first?.property.anotherProperty.map { $0 * 2 }.filter { $0 > 10 }
|
|
.reduce(0, +)
|
|
"""
|
|
|
|
let output = """
|
|
let result = array
|
|
.first?
|
|
.property
|
|
.anotherProperty
|
|
.map { $0 * 2 }
|
|
.filter { $0 > 10 }
|
|
.reduce(0, +)
|
|
"""
|
|
|
|
testFormatting(for: input, [output], rules: [.wrapMultilineFunctionChains, .indent])
|
|
}
|
|
|
|
func testWrapFunctionCallsWithChainsOnEndOfClosures() {
|
|
let input = """
|
|
let result = array
|
|
.map { item in
|
|
item.property
|
|
}.filter { $0 > 10 }
|
|
.reduce(0, +)
|
|
"""
|
|
|
|
let output = """
|
|
let result = array
|
|
.map { item in
|
|
item.property
|
|
}
|
|
.filter { $0 > 10 }
|
|
.reduce(0, +)
|
|
"""
|
|
|
|
testFormatting(for: input, [output], rules: [.wrapMultilineFunctionChains, .indent])
|
|
}
|
|
|
|
func testWrapFunctionCallsWithChainsOnEndOfParameters() {
|
|
let input = """
|
|
let result = array
|
|
.function(
|
|
arg1: item.property,
|
|
arg2: item.property
|
|
).reduce(0, +)
|
|
"""
|
|
|
|
let output = """
|
|
let result = array
|
|
.function(
|
|
arg1: item.property,
|
|
arg2: item.property
|
|
)
|
|
.reduce(0, +)
|
|
"""
|
|
|
|
testFormatting(for: input, [output], rules: [.wrapMultilineFunctionChains, .indent])
|
|
}
|
|
|
|
func testMultilineOperatorStatementsNotWrapped() {
|
|
let input = """
|
|
formatter.currentIndentForLine(at: conditionBeginIndex)
|
|
.count < indent.count + formatter.options.indent.count
|
|
"""
|
|
|
|
testFormatting(for: input, rules: [.wrapMultilineFunctionChains, .indent])
|
|
}
|
|
|
|
func testNamespacedAccessNotWrapped() {
|
|
let input = """
|
|
Namespace.NestedNamespace.property
|
|
.map { $0 * 2 }
|
|
"""
|
|
|
|
testFormatting(for: input, rules: [.wrapMultilineFunctionChains, .indent])
|
|
}
|
|
|
|
func testNestedNamespacedAccessNotWrapped() {
|
|
let input = """
|
|
Namespace.NestedNamespace.DeeplyNestedNamespace.property
|
|
.function()
|
|
"""
|
|
|
|
testFormatting(for: input, rules: [.wrapMultilineFunctionChains, .indent])
|
|
}
|
|
|
|
func testMultilineTypesNotWrapped() {
|
|
let input = """
|
|
func tableCellSelection(for selection: Selection?) -> Selection
|
|
.TableSelection.CellSelection?
|
|
{
|
|
selection.tableCellSelection
|
|
}
|
|
"""
|
|
|
|
testFormatting(for: input, rules: [.wrapMultilineFunctionChains, .indent])
|
|
}
|
|
|
|
func testSingleFunctionChainNotWrapped() {
|
|
let input = """
|
|
let result = array.map { $0 * 2 }
|
|
"""
|
|
|
|
testFormatting(for: input, [], rules: [.wrapMultilineFunctionChains, .indent])
|
|
}
|
|
|
|
func testMultipleFunctionChainsOnOneLineNotWrapped() {
|
|
let input = """
|
|
let result = array.map { $0 * 2 }.filter { $0 > 10 }.reduce(0, +)
|
|
"""
|
|
|
|
testFormatting(for: input, [], rules: [.wrapMultilineFunctionChains, .indent])
|
|
}
|
|
|
|
func testFunctionChainWithOptionalChaining() {
|
|
let input = """
|
|
let result = array?
|
|
.map { $0 * 2 }
|
|
.filter { $0 > 10 }
|
|
.reduce(0, +)
|
|
"""
|
|
|
|
testFormatting(for: input, [], rules: [.wrapMultilineFunctionChains, .indent])
|
|
}
|
|
|
|
func testConsecutiveDeclarations() {
|
|
let input = """
|
|
let sequence = [42].async
|
|
let sequence = [43].async
|
|
"""
|
|
|
|
testFormatting(for: input, [], rules: [.wrapMultilineFunctionChains, .indent])
|
|
}
|
|
|
|
func testConsecutiveStatements() {
|
|
let input = """
|
|
let encoded = try JSONEncoder().encode(container)
|
|
let decoded = try JSONDecoder().decode(Container.self, from: encoded)
|
|
"""
|
|
|
|
testFormatting(for: input, [], rules: [.wrapMultilineFunctionChains, .indent])
|
|
}
|
|
|
|
func testAdjacentChainsChainsShouldNotWrap() {
|
|
let input = """
|
|
value.property.map { $0 * 2 }
|
|
value.property.map { $0 * 2 }
|
|
"""
|
|
|
|
testFormatting(for: input, [], rules: [.wrapMultilineFunctionChains, .indent])
|
|
}
|
|
|
|
func testAdjacentChainsInViewBuildersWithDifferentWraps() {
|
|
let input = """
|
|
Text("S")
|
|
.padding(10)
|
|
Color.blue.frame(maxWidth: 1, maxHeight: .infinity).fixedSize()
|
|
"""
|
|
|
|
testFormatting(for: input, [], rules: [.wrapMultilineFunctionChains, .indent])
|
|
}
|
|
|
|
func testNonFunctionChains() {
|
|
let input = """
|
|
let adjusted: CGPoint = .init(
|
|
x: rect.origin.x + insets.left,
|
|
y: rect.origin.y + insets.top
|
|
)
|
|
"""
|
|
|
|
testFormatting(for: input, [], rules: [.wrapMultilineFunctionChains, .indent])
|
|
}
|
|
|
|
func testAdjacentChainsInConditions() {
|
|
let input = """
|
|
let hexSanitized = hexString
|
|
.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
.replacingOccurrences(of: "#", with: "")
|
|
|
|
var hex: UInt64 = 0
|
|
guard Scanner(string: hexSanitized).scanHexInt64(&hex) else {
|
|
return nil
|
|
}
|
|
"""
|
|
testFormatting(for: input, [], rules: [.wrapMultilineFunctionChains, .indent])
|
|
}
|
|
|
|
func testAdjacentChainsInIfConditionWhereStatement() {
|
|
let input = """
|
|
let xcTestCaseInstanceMethods = Set(["expectation"])
|
|
.union(options.additionalXCTestSymbols)
|
|
|
|
for index in tokens.indices where tokens[index].isIdentifier {
|
|
let identifier = tokens[index].string
|
|
}
|
|
"""
|
|
|
|
testFormatting(for: input, [], rules: [.wrapMultilineFunctionChains, .indent])
|
|
}
|
|
|
|
func testTrailingClosureNotWrapped() {
|
|
let input = """
|
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { [weak self] in
|
|
self?.hideKeyboard.send()
|
|
}
|
|
"""
|
|
|
|
testFormatting(for: input, [], rules: [.wrapMultilineFunctionChains, .indent])
|
|
}
|
|
|
|
func testParenthesisInSingleLineDoNoWrap() {
|
|
let input = """
|
|
MainActor.assumeIsolated {
|
|
let value = try await someFunction()
|
|
}
|
|
|
|
(invoke() as Value).method()
|
|
"""
|
|
|
|
testFormatting(for: input, [], rules: [.wrapMultilineFunctionChains, .indent], exclude: [.hoistTry])
|
|
}
|
|
}
|