mirror of
https://github.com/nicklockwood/SwiftFormat.git
synced 2026-06-16 10:34:34 +00:00
3364 lines
101 KiB
Swift
3364 lines
101 KiB
Swift
//
|
|
// WrapArgumentsTests.swift
|
|
// SwiftFormatTests
|
|
//
|
|
// Created by Nick Lockwood on 11/23/16.
|
|
// Copyright © 2024 Nick Lockwood. All rights reserved.
|
|
//
|
|
|
|
import XCTest
|
|
@testable import SwiftFormat
|
|
|
|
final class WrapArgumentsTests: XCTestCase {
|
|
func testIndentFirstElementWhenApplyingWrap() {
|
|
let input = """
|
|
let foo = Set([
|
|
Thing(),
|
|
Thing(),
|
|
])
|
|
"""
|
|
let output = """
|
|
let foo = Set([
|
|
Thing(),
|
|
Thing(),
|
|
])
|
|
"""
|
|
testFormatting(for: input, output, rule: .wrapArguments, exclude: [.propertyTypes])
|
|
}
|
|
|
|
func testWrapArgumentsDoesntIndentTrailingComment() {
|
|
let input = """
|
|
foo( // foo
|
|
bar: Int,
|
|
baaz: Int
|
|
)
|
|
"""
|
|
let output = """
|
|
foo( // foo
|
|
bar: Int,
|
|
baaz: Int
|
|
)
|
|
"""
|
|
testFormatting(for: input, output, rule: .wrapArguments)
|
|
}
|
|
|
|
func testWrapArgumentsDoesntIndentClosingBracket() {
|
|
let input = """
|
|
[
|
|
"foo": [
|
|
],
|
|
]
|
|
"""
|
|
testFormatting(for: input, rule: .wrapArguments)
|
|
}
|
|
|
|
func testWrapParametersDoesNotAffectFunctionDeclaration() {
|
|
let input = """
|
|
foo(
|
|
bar _: Int,
|
|
baz _: String
|
|
)
|
|
"""
|
|
let options = FormatOptions(wrapArguments: .preserve, wrapParameters: .afterFirst)
|
|
testFormatting(for: input, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testWrapParametersClosureAfterParameterListDoesNotWrapClosureArguments() {
|
|
let input = """
|
|
func foo() {}
|
|
bar = (baz: 5, quux: 7,
|
|
quuz: 10)
|
|
"""
|
|
let options = FormatOptions(wrapArguments: .preserve, wrapParameters: .beforeFirst)
|
|
testFormatting(for: input, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testWrapParametersNotSetWrapArgumentsAfterFirstDefaultsToAfterFirst() {
|
|
let input = """
|
|
func foo(
|
|
bar _: Int,
|
|
baz _: String
|
|
) {}
|
|
"""
|
|
let output = """
|
|
func foo(bar _: Int,
|
|
baz _: String) {}
|
|
"""
|
|
let options = FormatOptions(wrapArguments: .afterFirst)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testWrapParametersNotSetWrapArgumentsBeforeFirstDefaultsToBeforeFirst() {
|
|
let input = """
|
|
func foo(bar _: Int,
|
|
baz _: String) {}
|
|
"""
|
|
let output = """
|
|
func foo(
|
|
bar _: Int,
|
|
baz _: String
|
|
) {}
|
|
"""
|
|
let options = FormatOptions(wrapArguments: .beforeFirst)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testWrapParametersNotSetWrapArgumentsPreserveDefaultsToPreserve() {
|
|
let input = """
|
|
func foo(
|
|
bar _: Int,
|
|
baz _: String) {}
|
|
"""
|
|
let output = """
|
|
func foo(
|
|
bar _: Int,
|
|
baz _: String
|
|
) {}
|
|
"""
|
|
let options = FormatOptions(wrapArguments: .preserve)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testWrapParametersFunctionDeclarationClosingParenOnSameLine() {
|
|
let input = """
|
|
func foo(
|
|
bar _: Int,
|
|
baz _: String
|
|
) {}
|
|
"""
|
|
let output = """
|
|
func foo(
|
|
bar _: Int,
|
|
baz _: String) {}
|
|
"""
|
|
let options = FormatOptions(wrapArguments: .beforeFirst, closingParenPosition: .sameLine)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testWrapParametersFunctionDeclarationClosingParenOnNextLine() {
|
|
let input = """
|
|
func foo(
|
|
bar _: Int,
|
|
baz _: String) {}
|
|
"""
|
|
let output = """
|
|
func foo(
|
|
bar _: Int,
|
|
baz _: String
|
|
) {}
|
|
"""
|
|
let options = FormatOptions(wrapArguments: .beforeFirst, closingParenPosition: .balanced)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testWrapParametersFunctionDeclarationClosingParenOnSameLineAndForce() {
|
|
let input = """
|
|
func foo(
|
|
bar _: Int,
|
|
baz _: String
|
|
) {}
|
|
"""
|
|
let output = """
|
|
func foo(
|
|
bar _: Int,
|
|
baz _: String) {}
|
|
"""
|
|
let options = FormatOptions(wrapArguments: .beforeFirst, closingParenPosition: .sameLine, callSiteClosingParenPosition: .sameLine)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testWrapParametersFunctionDeclarationClosingParenOnNextLineAndForce() {
|
|
let input = """
|
|
func foo(
|
|
bar _: Int,
|
|
baz _: String) {}
|
|
"""
|
|
let output = """
|
|
func foo(
|
|
bar _: Int,
|
|
baz _: String
|
|
) {}
|
|
"""
|
|
let options = FormatOptions(wrapArguments: .beforeFirst, closingParenPosition: .balanced, callSiteClosingParenPosition: .sameLine)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testWrapParametersFunctionDeclarationClosingParenOnNextLineSingleArgument() {
|
|
let input = """
|
|
func foo(
|
|
bar _: Int) {}
|
|
"""
|
|
let output = """
|
|
func foo(
|
|
bar _: Int
|
|
) {}
|
|
"""
|
|
let options = FormatOptions(wrapArguments: .beforeFirst, closingParenPosition: .balanced, maxWidth: 100)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testWrapParametersFunctionCallClosingParenOnNextLineAndForce() {
|
|
let input = """
|
|
foo(
|
|
bar: 42,
|
|
baz: "foo"
|
|
)
|
|
"""
|
|
let output = """
|
|
foo(
|
|
bar: 42,
|
|
baz: "foo")
|
|
"""
|
|
let options = FormatOptions(wrapArguments: .beforeFirst, closingParenPosition: .balanced, callSiteClosingParenPosition: .sameLine)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testWrapParametersFunctionCallClosingParenBalancedAndForce() {
|
|
let input = """
|
|
foo(
|
|
bar: 42,
|
|
baz: "foo")
|
|
"""
|
|
let output = """
|
|
foo(
|
|
bar: 42,
|
|
baz: "foo"
|
|
)
|
|
"""
|
|
let options = FormatOptions(wrapArguments: .beforeFirst, closingParenPosition: .sameLine, callSiteClosingParenPosition: .balanced)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testWrapParametersFunctionCallClosingParenBalancedSingleArgument() {
|
|
let input = """
|
|
foo(
|
|
bar: 42)
|
|
"""
|
|
let output = """
|
|
foo(
|
|
bar: 42
|
|
)
|
|
"""
|
|
let options = FormatOptions(wrapArguments: .beforeFirst, closingParenPosition: .sameLine, callSiteClosingParenPosition: .balanced, maxWidth: 100)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testIndentMultilineStringWhenWrappingArguments() {
|
|
let input = """
|
|
foobar(foo: \"\""
|
|
baz
|
|
\"\"",
|
|
bar: \"\""
|
|
baz
|
|
\"\"")
|
|
"""
|
|
let options = FormatOptions(wrapArguments: .afterFirst)
|
|
testFormatting(for: input, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testHandleXcodeTokenApplyingWrap() {
|
|
let input = """
|
|
test(image: \u{003c}#T##UIImage#>, name: "Name")
|
|
"""
|
|
|
|
let output = """
|
|
test(
|
|
image: \u{003c}#T##UIImage#>,
|
|
name: "Name"
|
|
)
|
|
"""
|
|
let options = FormatOptions(wrapArguments: .beforeFirst, maxWidth: 20)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testIssue1530() {
|
|
let input = """
|
|
extension DRAutoWeatherReadRequestResponse {
|
|
static let mock = DRAutoWeatherReadRequestResponse(
|
|
offlineFirstWeather: DRAutoWeatherReadRequestResponse.DROfflineFirstWeather(
|
|
daily: .mockWeatherID, hourly: []
|
|
)
|
|
)
|
|
}
|
|
"""
|
|
let options = FormatOptions(wrapArguments: .beforeFirst)
|
|
testFormatting(for: input, rule: .wrapArguments, options: options, exclude: [.propertyTypes])
|
|
}
|
|
|
|
// MARK: wrapParameters
|
|
|
|
// MARK: preserve
|
|
|
|
func testAfterFirstPreserved() {
|
|
let input = """
|
|
func foo(bar _: Int,
|
|
baz _: String) {}
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .preserve)
|
|
testFormatting(for: input, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testAfterFirstPreservedIndentFixed() {
|
|
let input = """
|
|
func foo(bar _: Int,
|
|
baz _: String) {}
|
|
"""
|
|
let output = """
|
|
func foo(bar _: Int,
|
|
baz _: String) {}
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .preserve)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testAfterFirstPreservedNewlineRemoved() {
|
|
let input = """
|
|
func foo(bar _: Int,
|
|
baz _: String
|
|
) {}
|
|
"""
|
|
let output = """
|
|
func foo(bar _: Int,
|
|
baz _: String) {}
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .preserve)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testBeforeFirstPreserved() {
|
|
let input = """
|
|
func foo(
|
|
bar _: Int,
|
|
baz _: String
|
|
) {}
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .preserve)
|
|
testFormatting(for: input, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testBeforeFirstPreservedIndentFixed() {
|
|
let input = """
|
|
func foo(
|
|
bar _: Int,
|
|
baz _: String
|
|
) {}
|
|
"""
|
|
let output = """
|
|
func foo(
|
|
bar _: Int,
|
|
baz _: String
|
|
) {}
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .preserve)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testBeforeFirstPreservedNewlineAdded() {
|
|
let input = """
|
|
func foo(
|
|
bar _: Int,
|
|
baz _: String) {}
|
|
"""
|
|
let output = """
|
|
func foo(
|
|
bar _: Int,
|
|
baz _: String
|
|
) {}
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .preserve)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testWrapParametersAfterMultilineComment() {
|
|
let input = """
|
|
/**
|
|
Some function comment.
|
|
*/
|
|
func barFunc(
|
|
_ firstParam: FirstParamType,
|
|
secondParam: SecondParamType
|
|
)
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .preserve)
|
|
testFormatting(for: input, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
// MARK: afterFirst
|
|
|
|
func testBeforeFirstConvertedToAfterFirst() {
|
|
let input = """
|
|
func foo(
|
|
bar _: Int,
|
|
baz _: String
|
|
) {}
|
|
"""
|
|
let output = """
|
|
func foo(bar _: Int,
|
|
baz _: String) {}
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .afterFirst)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testNoWrapInnerArguments() {
|
|
let input = """
|
|
func foo(
|
|
bar _: Int,
|
|
baz _: foo(bar, baz)
|
|
) {}
|
|
"""
|
|
let output = """
|
|
func foo(bar _: Int,
|
|
baz _: foo(bar, baz)) {}
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .afterFirst)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
// MARK: afterFirst, maxWidth
|
|
|
|
func testWrapAfterFirstIfMaxLengthExceeded() {
|
|
let input = """
|
|
func foo(bar: Int, baz: String) -> Bool {}
|
|
"""
|
|
let output = """
|
|
func foo(bar: Int,
|
|
baz: String) -> Bool {}
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .afterFirst, maxWidth: 20)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options,
|
|
exclude: [.unusedArguments, .wrap])
|
|
}
|
|
|
|
func testWrapAfterFirstIfMaxLengthExceeded2() {
|
|
let input = """
|
|
func foo(bar: Int, baz: String, quux: Bool) -> Bool {}
|
|
"""
|
|
let output = """
|
|
func foo(bar: Int,
|
|
baz: String,
|
|
quux: Bool) -> Bool {}
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .afterFirst, maxWidth: 20)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options,
|
|
exclude: [.unusedArguments, .wrap])
|
|
}
|
|
|
|
func testWrapAfterFirstIfMaxLengthExceeded3() {
|
|
let input = """
|
|
func foo(bar: Int, baz: String, aVeryLongLastArgumentThatExceedsTheMaxWidthByItself: Bool) -> Bool {}
|
|
"""
|
|
let output = """
|
|
func foo(bar: Int, baz: String,
|
|
aVeryLongLastArgumentThatExceedsTheMaxWidthByItself: Bool) -> Bool {}
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .afterFirst, maxWidth: 32)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options,
|
|
exclude: [.unusedArguments, .wrap])
|
|
}
|
|
|
|
func testWrapAfterFirstIfMaxLengthExceeded3WithWrap() {
|
|
let input = """
|
|
func foo(bar: Int, baz: String, aVeryLongLastArgumentThatExceedsTheMaxWidthByItself: Bool) -> Bool {}
|
|
"""
|
|
let output = """
|
|
func foo(bar: Int, baz: String,
|
|
aVeryLongLastArgumentThatExceedsTheMaxWidthByItself: Bool)
|
|
-> Bool {}
|
|
"""
|
|
let output2 = """
|
|
func foo(bar: Int, baz: String,
|
|
aVeryLongLastArgumentThatExceedsTheMaxWidthByItself: Bool)
|
|
-> Bool {}
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .afterFirst, maxWidth: 32)
|
|
testFormatting(for: input, [output, output2],
|
|
rules: [.wrapArguments, .wrap],
|
|
options: options, exclude: [.unusedArguments])
|
|
}
|
|
|
|
func testWrapAfterFirstIfMaxLengthExceeded4WithWrap() {
|
|
let input = """
|
|
func foo(bar: String, baz: String, quux: Bool) -> Bool {}
|
|
"""
|
|
let output = """
|
|
func foo(bar: String,
|
|
baz: String,
|
|
quux: Bool) -> Bool {}
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .afterFirst, maxWidth: 31)
|
|
testFormatting(for: input, [output],
|
|
rules: [.wrapArguments, .wrap],
|
|
options: options, exclude: [.unusedArguments])
|
|
}
|
|
|
|
func testWrapAfterFirstIfMaxLengthExceededInClassScopeWithWrap() {
|
|
let input = """
|
|
class TestClass {
|
|
func foo(bar: String, baz: String, quux: Bool) -> Bool {}
|
|
}
|
|
"""
|
|
let output = """
|
|
class TestClass {
|
|
func foo(bar: String,
|
|
baz: String,
|
|
quux: Bool)
|
|
-> Bool {}
|
|
}
|
|
"""
|
|
let output2 = """
|
|
class TestClass {
|
|
func foo(bar: String,
|
|
baz: String,
|
|
quux: Bool)
|
|
-> Bool {}
|
|
}
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .afterFirst, maxWidth: 31)
|
|
testFormatting(for: input, [output, output2],
|
|
rules: [.wrapArguments, .wrap],
|
|
options: options, exclude: [.unusedArguments])
|
|
}
|
|
|
|
func testWrapParametersListInClosureType() {
|
|
let input = """
|
|
var mathFunction: (Int,
|
|
Int, String) -> Int = { _, _, _ in
|
|
0
|
|
}
|
|
"""
|
|
let output = """
|
|
var mathFunction: (Int,
|
|
Int,
|
|
String) -> Int = { _, _, _ in
|
|
0
|
|
}
|
|
"""
|
|
let output2 = """
|
|
var mathFunction: (Int,
|
|
Int,
|
|
String)
|
|
-> Int = { _, _, _ in
|
|
0
|
|
}
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .afterFirst, maxWidth: 30)
|
|
testFormatting(for: input, [output, output2],
|
|
rules: [.wrapArguments],
|
|
options: options)
|
|
}
|
|
|
|
func testWrapParametersAfterFirstIfMaxLengthExceededInReturnType() {
|
|
let input = """
|
|
func foo(bar: Int, baz: String, quux: Bool) -> LongReturnType {}
|
|
"""
|
|
let output2 = """
|
|
func foo(bar: Int, baz: String,
|
|
quux: Bool) -> LongReturnType {}
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .afterFirst, maxWidth: 50)
|
|
testFormatting(for: input, [input, output2], rules: [.wrapArguments],
|
|
options: options, exclude: [.unusedArguments])
|
|
}
|
|
|
|
func testWrapParametersAfterFirstWithSeparatedArgumentLabels() {
|
|
let input = """
|
|
func foo(with
|
|
bar: Int, and
|
|
baz: String, and
|
|
quux: Bool
|
|
) -> LongReturnType {}
|
|
"""
|
|
let output = """
|
|
func foo(with bar: Int,
|
|
and baz: String,
|
|
and quux: Bool) -> LongReturnType {}
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .afterFirst)
|
|
testFormatting(for: input, output, rule: .wrapArguments,
|
|
options: options, exclude: [.unusedArguments])
|
|
}
|
|
|
|
// MARK: beforeFirst
|
|
|
|
func testWrapAfterFirstConvertedToWrapBefore() {
|
|
let input = """
|
|
func foo(bar _: Int,
|
|
baz _: String) {}
|
|
"""
|
|
let output = """
|
|
func foo(
|
|
bar _: Int,
|
|
baz _: String
|
|
) {}
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .beforeFirst)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testLinebreakInsertedAtEndOfWrappedFunction() {
|
|
let input = """
|
|
func foo(
|
|
bar _: Int,
|
|
baz _: String) {}
|
|
"""
|
|
let output = """
|
|
func foo(
|
|
bar _: Int,
|
|
baz _: String
|
|
) {}
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .beforeFirst)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testAfterFirstConvertedToBeforeFirst() {
|
|
let input = """
|
|
func foo(bar _: Int,
|
|
baz _: String) {}
|
|
"""
|
|
let output = """
|
|
func foo(
|
|
bar _: Int,
|
|
baz _: String
|
|
) {}
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .beforeFirst)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testWrapParametersListBeforeFirstInClosureType() {
|
|
let input = """
|
|
var mathFunction: (Int,
|
|
Int, String) -> Int = { _, _, _ in
|
|
0
|
|
}
|
|
"""
|
|
let output = """
|
|
var mathFunction: (
|
|
Int,
|
|
Int,
|
|
String
|
|
) -> Int = { _, _, _ in
|
|
0
|
|
}
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .beforeFirst)
|
|
testFormatting(for: input, [output],
|
|
rules: [.wrapArguments],
|
|
options: options)
|
|
}
|
|
|
|
func testWrapParametersListBeforeFirstInThrowingClosureType() {
|
|
let input = """
|
|
var mathFunction: (Int,
|
|
Int, String) throws -> Int = { _, _, _ in
|
|
0
|
|
}
|
|
"""
|
|
let output = """
|
|
var mathFunction: (
|
|
Int,
|
|
Int,
|
|
String
|
|
) throws -> Int = { _, _, _ in
|
|
0
|
|
}
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .beforeFirst)
|
|
testFormatting(for: input, [output],
|
|
rules: [.wrapArguments],
|
|
options: options)
|
|
}
|
|
|
|
func testWrapParametersListBeforeFirstInTypedThrowingClosureType() {
|
|
let input = """
|
|
var mathFunction: (Int,
|
|
Int, String) throws(Foo) -> Int = { _, _, _ in
|
|
0
|
|
}
|
|
"""
|
|
let output = """
|
|
var mathFunction: (
|
|
Int,
|
|
Int,
|
|
String
|
|
) throws(Foo) -> Int = { _, _, _ in
|
|
0
|
|
}
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .beforeFirst)
|
|
testFormatting(for: input, [output],
|
|
rules: [.wrapArguments],
|
|
options: options)
|
|
}
|
|
|
|
func testWrapParametersListBeforeFirstInRethrowingClosureType() {
|
|
let input = """
|
|
var mathFunction: (Int,
|
|
Int, String) rethrows -> Int = { _, _, _ in
|
|
0
|
|
}
|
|
"""
|
|
let output = """
|
|
var mathFunction: (
|
|
Int,
|
|
Int,
|
|
String
|
|
) rethrows -> Int = { _, _, _ in
|
|
0
|
|
}
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .beforeFirst)
|
|
testFormatting(for: input, [output],
|
|
rules: [.wrapArguments],
|
|
options: options)
|
|
}
|
|
|
|
func testWrapParametersListBeforeFirstInClosureTypeAsFunctionParameter() {
|
|
let input = """
|
|
func foo(bar: (Int,
|
|
Bool, String) -> Int) -> Int {}
|
|
"""
|
|
let output = """
|
|
func foo(bar: (
|
|
Int,
|
|
Bool,
|
|
String
|
|
) -> Int) -> Int {}
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .beforeFirst)
|
|
testFormatting(for: input, [output],
|
|
rules: [.wrapArguments],
|
|
options: options,
|
|
exclude: [.unusedArguments])
|
|
}
|
|
|
|
func testWrapParametersListBeforeFirstInClosureTypeAsFunctionParameterWithOtherParams() {
|
|
let input = """
|
|
func foo(bar: Int, baz: (Int,
|
|
Bool, String) -> Int) -> Int {}
|
|
"""
|
|
let output = """
|
|
func foo(bar: Int, baz: (
|
|
Int,
|
|
Bool,
|
|
String
|
|
) -> Int) -> Int {}
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .beforeFirst)
|
|
testFormatting(for: input, [output],
|
|
rules: [.wrapArguments],
|
|
options: options,
|
|
exclude: [.unusedArguments])
|
|
}
|
|
|
|
func testWrapParametersListBeforeFirstInClosureTypeAsFunctionParameterWithOtherParamsAfterWrappedClosure() {
|
|
let input = """
|
|
func foo(bar: Int, baz: (Int,
|
|
Bool, String) -> Int, quux: String) -> Int {}
|
|
"""
|
|
let output = """
|
|
func foo(bar: Int, baz: (
|
|
Int,
|
|
Bool,
|
|
String
|
|
) -> Int, quux: String) -> Int {}
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .beforeFirst)
|
|
testFormatting(for: input, [output],
|
|
rules: [.wrapArguments],
|
|
options: options,
|
|
exclude: [.unusedArguments])
|
|
}
|
|
|
|
func testWrapParametersListBeforeFirstInEscapingClosureTypeAsFunctionParameter() {
|
|
let input = """
|
|
func foo(bar: @escaping (Int,
|
|
Bool, String) -> Int) -> Int {}
|
|
"""
|
|
let output = """
|
|
func foo(bar: @escaping (
|
|
Int,
|
|
Bool,
|
|
String
|
|
) -> Int) -> Int {}
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .beforeFirst)
|
|
testFormatting(for: input, [output],
|
|
rules: [.wrapArguments],
|
|
options: options,
|
|
exclude: [.unusedArguments])
|
|
}
|
|
|
|
func testWrapParametersListBeforeFirstInNoEscapeClosureTypeAsFunctionParameter() {
|
|
let input = """
|
|
func foo(bar: @noescape (Int,
|
|
Bool, String) -> Int) -> Int {}
|
|
"""
|
|
let output = """
|
|
func foo(bar: @noescape (
|
|
Int,
|
|
Bool,
|
|
String
|
|
) -> Int) -> Int {}
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .beforeFirst)
|
|
testFormatting(for: input, [output],
|
|
rules: [.wrapArguments],
|
|
options: options,
|
|
exclude: [.unusedArguments])
|
|
}
|
|
|
|
func testWrapParametersListBeforeFirstInEscapingAutoclosureTypeAsFunctionParameter() {
|
|
let input = """
|
|
func foo(bar: @escaping @autoclosure (Int,
|
|
Bool, String) -> Int) -> Int {}
|
|
"""
|
|
let output = """
|
|
func foo(bar: @escaping @autoclosure (
|
|
Int,
|
|
Bool,
|
|
String
|
|
) -> Int) -> Int {}
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .beforeFirst)
|
|
testFormatting(for: input, [output],
|
|
rules: [.wrapArguments],
|
|
options: options,
|
|
exclude: [.unusedArguments])
|
|
}
|
|
|
|
// MARK: beforeFirst, maxWidth
|
|
|
|
func testWrapBeforeFirstIfMaxLengthExceeded() {
|
|
let input = """
|
|
func foo(bar: Int, baz: String) -> Bool {}
|
|
"""
|
|
let output = """
|
|
func foo(
|
|
bar: Int,
|
|
baz: String
|
|
) -> Bool {}
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .beforeFirst, maxWidth: 20)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options,
|
|
exclude: [.unusedArguments])
|
|
}
|
|
|
|
func testNoWrapBeforeFirstIfMaxLengthNotExceeded() {
|
|
let input = """
|
|
func foo(bar: Int, baz: String) -> Bool {}
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .beforeFirst, maxWidth: 42)
|
|
testFormatting(for: input, rule: .wrapArguments, options: options,
|
|
exclude: [.unusedArguments])
|
|
}
|
|
|
|
func testNoWrapGenericsIfClosingBracketWithinMaxWidth() {
|
|
let input = """
|
|
func foo<T: Bar>(bar: Int, baz: String) -> Bool {}
|
|
"""
|
|
let output = """
|
|
func foo<T: Bar>(
|
|
bar: Int,
|
|
baz: String
|
|
) -> Bool {}
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .beforeFirst, maxWidth: 20)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options,
|
|
exclude: [.unusedArguments])
|
|
}
|
|
|
|
func testWrapAlreadyWrappedArgumentsIfMaxLengthExceeded() {
|
|
let input = """
|
|
func foo(
|
|
bar: Int, baz: String, quux: Bool
|
|
) -> Bool {}
|
|
"""
|
|
let output = """
|
|
func foo(
|
|
bar: Int, baz: String,
|
|
quux: Bool
|
|
) -> Bool {}
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .beforeFirst, maxWidth: 26)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options,
|
|
exclude: [.unusedArguments])
|
|
}
|
|
|
|
func testWrapParametersBeforeFirstIfMaxLengthExceededInReturnType() {
|
|
let input = """
|
|
func foo(bar: Int, baz: String, quux: Bool) -> LongReturnType {}
|
|
"""
|
|
let output2 = """
|
|
func foo(
|
|
bar: Int,
|
|
baz: String,
|
|
quux: Bool
|
|
) -> LongReturnType {}
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .beforeFirst, maxWidth: 50)
|
|
testFormatting(for: input, [input, output2], rules: [.wrapArguments],
|
|
options: options, exclude: [.unusedArguments])
|
|
}
|
|
|
|
func testWrapParametersBeforeFirstWithSeparatedArgumentLabels() {
|
|
let input = """
|
|
func foo(with
|
|
bar: Int, and
|
|
baz: String
|
|
) -> LongReturnType {}
|
|
"""
|
|
let output = """
|
|
func foo(
|
|
with bar: Int,
|
|
and baz: String
|
|
) -> LongReturnType {}
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .beforeFirst)
|
|
testFormatting(for: input, output, rule: .wrapArguments,
|
|
options: options, exclude: [.unusedArguments])
|
|
}
|
|
|
|
func testWrapParametersListBeforeFirstInClosureTypeWithMaxWidth() {
|
|
let input = """
|
|
var mathFunction: (Int, Int, String) -> Int = { _, _, _ in
|
|
0
|
|
}
|
|
"""
|
|
let output = """
|
|
var mathFunction: (
|
|
Int,
|
|
Int,
|
|
String
|
|
) -> Int = { _, _, _ in
|
|
0
|
|
}
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .beforeFirst, maxWidth: 30)
|
|
testFormatting(for: input, [output], rules: [.wrapArguments],
|
|
options: options)
|
|
}
|
|
|
|
func testNoWrapBeforeFirstMaxWidthNotExceededWithLineBreakSinceLastEndOfArgumentScope() {
|
|
let input = """
|
|
class Foo {
|
|
func foo() {
|
|
bar()
|
|
}
|
|
|
|
func bar(foo: String, bar: Int) {
|
|
quux()
|
|
}
|
|
}
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .beforeFirst, maxWidth: 37)
|
|
testFormatting(for: input, rule: .wrapArguments,
|
|
options: options, exclude: [.unusedArguments])
|
|
}
|
|
|
|
func testNoWrapSubscriptWithSingleElement() {
|
|
let input = """
|
|
guard let foo = bar[0] {}
|
|
"""
|
|
let output = """
|
|
guard let foo = bar[
|
|
0
|
|
] {}
|
|
"""
|
|
let options = FormatOptions(wrapCollections: .beforeFirst, maxWidth: 20)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options,
|
|
exclude: [.wrap])
|
|
}
|
|
|
|
func testWrapArrayWithSingleElementIfOverMaxWidth() {
|
|
let input = """
|
|
let foo = [0]
|
|
"""
|
|
let output = """
|
|
let foo = [
|
|
0,
|
|
]
|
|
"""
|
|
let options = FormatOptions(wrapCollections: .beforeFirst, maxWidth: 11)
|
|
testFormatting(for: input, [output], rules: [.wrapArguments, .trailingCommas], options: options,
|
|
exclude: [.wrap])
|
|
}
|
|
|
|
func testWrapPartiallyWrappedArrayWithSingleElement() {
|
|
let input = """
|
|
let foo = [
|
|
0]
|
|
"""
|
|
let output = """
|
|
let foo = [
|
|
0,
|
|
]
|
|
"""
|
|
let options = FormatOptions(wrapCollections: .beforeFirst, maxWidth: 100)
|
|
testFormatting(for: input, [output], rules: [.wrapArguments, .trailingCommas], options: options,
|
|
exclude: [.wrap])
|
|
}
|
|
|
|
func testWrapDictionaryWithSingleElementIfOverMaxWidth() {
|
|
let input = """
|
|
let foo = [bar: baz]
|
|
"""
|
|
let output = """
|
|
let foo = [
|
|
bar: baz,
|
|
]
|
|
"""
|
|
let options = FormatOptions(wrapCollections: .beforeFirst, maxWidth: 15)
|
|
testFormatting(for: input, [output], rules: [.wrapArguments, .trailingCommas], options: options,
|
|
exclude: [.wrap])
|
|
}
|
|
|
|
func testNoWrapImageLiteral() {
|
|
let input = """
|
|
if let image = #imageLiteral(resourceName: \"abc.png\") {}
|
|
"""
|
|
let options = FormatOptions(wrapCollections: .beforeFirst, maxWidth: 30)
|
|
testFormatting(for: input, rule: .wrapArguments, options: options,
|
|
exclude: [.wrap])
|
|
}
|
|
|
|
func testNoWrapColorLiteral() {
|
|
let input = """
|
|
if let color = #colorLiteral(red: 0.2392156863, green: 0.6470588235, blue: 0.3647058824, alpha: 1) {}
|
|
"""
|
|
let options = FormatOptions(wrapCollections: .beforeFirst, maxWidth: 30)
|
|
testFormatting(for: input, rule: .wrapArguments, options: options,
|
|
exclude: [.wrap])
|
|
}
|
|
|
|
func testWrapArgumentsNoIndentBlankLines() {
|
|
let input = """
|
|
let foo = [
|
|
|
|
bar,
|
|
|
|
]
|
|
"""
|
|
let options = FormatOptions(wrapCollections: .beforeFirst)
|
|
testFormatting(for: input, rule: .wrapArguments, options: options,
|
|
exclude: [.wrap, .blankLinesAtStartOfScope, .blankLinesAtEndOfScope])
|
|
}
|
|
|
|
// MARK: closingParenPosition = true
|
|
|
|
func testParenOnSameLineWhenWrapAfterFirstConvertedToWrapBefore() {
|
|
let input = """
|
|
func foo(bar _: Int,
|
|
baz _: String) {}
|
|
"""
|
|
let output = """
|
|
func foo(
|
|
bar _: Int,
|
|
baz _: String) {}
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .beforeFirst, closingParenPosition: .sameLine)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testParenOnSameLineWhenWrapBeforeFirstUnchanged() {
|
|
let input = """
|
|
func foo(
|
|
bar _: Int,
|
|
baz _: String
|
|
) {}
|
|
"""
|
|
let output = """
|
|
func foo(
|
|
bar _: Int,
|
|
baz _: String) {}
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .beforeFirst, closingParenPosition: .sameLine)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testParenOnSameLineWhenWrapBeforeFirstPreserved() {
|
|
let input = """
|
|
func foo(
|
|
bar _: Int,
|
|
baz _: String
|
|
) {}
|
|
"""
|
|
let output = """
|
|
func foo(
|
|
bar _: Int,
|
|
baz _: String) {}
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .preserve, closingParenPosition: .sameLine)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
// MARK: indent with tabs
|
|
|
|
func testTabIndentWrappedFunctionWithSmartTabs() {
|
|
let input = """
|
|
func foo(bar: Int,
|
|
baz: Int) {}
|
|
"""
|
|
let options = FormatOptions(indent: "\t", wrapParameters: .afterFirst, tabWidth: 2)
|
|
testFormatting(for: input, rule: .wrapArguments, options: options,
|
|
exclude: [.unusedArguments])
|
|
}
|
|
|
|
func testTabIndentWrappedFunctionWithoutSmartTabs() {
|
|
let input = """
|
|
func foo(bar: Int,
|
|
baz: Int) {}
|
|
"""
|
|
let output = """
|
|
func foo(bar: Int,
|
|
\t\t\t\t baz: Int) {}
|
|
"""
|
|
let options = FormatOptions(indent: "\t", wrapParameters: .afterFirst,
|
|
tabWidth: 2, smartTabs: false)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options,
|
|
exclude: [.unusedArguments])
|
|
}
|
|
|
|
// MARK: - wrapArguments --wrapArguments
|
|
|
|
func testWrapArgumentsDoesNotAffectFunctionDeclaration() {
|
|
let input = """
|
|
func foo(
|
|
bar _: Int,
|
|
baz _: String
|
|
) {}
|
|
"""
|
|
let options = FormatOptions(wrapArguments: .afterFirst, wrapParameters: .preserve)
|
|
testFormatting(for: input, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testWrapArgumentsDoesNotAffectInit() {
|
|
let input = """
|
|
init(
|
|
bar _: Int,
|
|
baz _: String
|
|
) {}
|
|
"""
|
|
let options = FormatOptions(wrapArguments: .afterFirst, wrapParameters: .preserve)
|
|
testFormatting(for: input, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testWrapArgumentsDoesNotAffectSubscript() {
|
|
let input = """
|
|
subscript(
|
|
bar _: Int,
|
|
baz _: String
|
|
) -> Int {}
|
|
"""
|
|
let options = FormatOptions(wrapArguments: .afterFirst, wrapParameters: .preserve)
|
|
testFormatting(for: input, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testWrapArgumentsDoesNotAffectAsyncFunctionDeclaration() {
|
|
let input = """
|
|
func foo(
|
|
bar _: Int,
|
|
baz _: String
|
|
) async {}
|
|
"""
|
|
let options = FormatOptions(wrapArguments: .afterFirst, wrapParameters: .preserve)
|
|
testFormatting(for: input, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testWrapParametersUsedForAsyncFunctionDeclaration() {
|
|
let input = """
|
|
func testAsync(first: String,
|
|
second: String,
|
|
third: String) async {
|
|
debugPrint("")
|
|
}
|
|
"""
|
|
let options = FormatOptions(wrapArguments: .beforeFirst, wrapParameters: .afterFirst)
|
|
testFormatting(for: input, rule: .wrapArguments, options: options,
|
|
exclude: [.unusedArguments, .wrapMultilineStatementBraces])
|
|
}
|
|
|
|
// MARK: afterFirst
|
|
|
|
func testWrapArgumentsConvertBeforeFirstToAfterFirst() {
|
|
let input = """
|
|
foo(
|
|
bar _: Int,
|
|
baz _: String
|
|
)
|
|
"""
|
|
let output = """
|
|
foo(bar _: Int,
|
|
baz _: String)
|
|
"""
|
|
let options = FormatOptions(wrapArguments: .afterFirst)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testCorrectWrapIndentForNestedArguments() {
|
|
let input = """
|
|
foo(
|
|
bar: (
|
|
x: 0,
|
|
y: 0
|
|
),
|
|
baz: (
|
|
x: 0,
|
|
y: 0
|
|
)
|
|
)
|
|
"""
|
|
let output = """
|
|
foo(bar: (x: 0,
|
|
y: 0),
|
|
baz: (x: 0,
|
|
y: 0))
|
|
"""
|
|
let options = FormatOptions(wrapArguments: .afterFirst)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testNoRemoveLinebreakAfterCommentInArguments() {
|
|
let input = """
|
|
a(b // comment
|
|
)
|
|
"""
|
|
let options = FormatOptions(wrapArguments: .afterFirst)
|
|
testFormatting(for: input, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testNoRemoveLinebreakAfterCommentInArguments2() {
|
|
let input = """
|
|
foo(bar: bar
|
|
// ,
|
|
// baz: baz
|
|
) {}
|
|
"""
|
|
let options = FormatOptions(wrapArguments: .afterFirst)
|
|
testFormatting(for: input, rule: .wrapArguments, options: options, exclude: [.indent])
|
|
}
|
|
|
|
func testConsecutiveCodeCommentsNotIndented() {
|
|
let input = """
|
|
foo(bar: bar,
|
|
// bar,
|
|
// baz,
|
|
quux)
|
|
"""
|
|
let options = FormatOptions(wrapArguments: .afterFirst)
|
|
testFormatting(for: input, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
// MARK: afterFirst maxWidth
|
|
|
|
func testWrapArgumentsAfterFirst() {
|
|
let input = """
|
|
foo(bar: Int, baz: String, quux: Bool)
|
|
"""
|
|
let output = """
|
|
foo(bar: Int,
|
|
baz: String,
|
|
quux: Bool)
|
|
"""
|
|
let options = FormatOptions(wrapArguments: .afterFirst, maxWidth: 20)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options,
|
|
exclude: [.unusedArguments, .wrap])
|
|
}
|
|
|
|
// MARK: beforeFirst
|
|
|
|
func testClosureInsideParensNotWrappedOntoNextLine() {
|
|
let input = """
|
|
foo({
|
|
bar()
|
|
})
|
|
"""
|
|
let options = FormatOptions(wrapArguments: .beforeFirst)
|
|
testFormatting(for: input, rule: .wrapArguments, options: options,
|
|
exclude: [.trailingClosures])
|
|
}
|
|
|
|
func testNoMangleCommentedLinesWhenWrappingArguments() {
|
|
let input = """
|
|
foo(bar: bar, quux: quux
|
|
// ,
|
|
// baz: baz
|
|
) {}
|
|
"""
|
|
let output = """
|
|
foo(
|
|
bar: bar,
|
|
quux: quux
|
|
// ,
|
|
// baz: baz
|
|
) {}
|
|
"""
|
|
let options = FormatOptions(wrapArguments: .beforeFirst)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testNoMangleCommentedLinesWhenWrappingArgumentsWithNoCommas() {
|
|
let input = """
|
|
foo(bar: bar, quux: quux
|
|
// baz: baz
|
|
) {}
|
|
"""
|
|
let output = """
|
|
foo(
|
|
bar: bar,
|
|
quux: quux
|
|
// baz: baz
|
|
) {}
|
|
"""
|
|
let options = FormatOptions(wrapArguments: .beforeFirst)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
// MARK: preserve
|
|
|
|
func testWrapArgumentsDoesNotAffectLessThanOperator() {
|
|
let input = """
|
|
func foo() {
|
|
guard foo < bar.count else { return nil }
|
|
}
|
|
"""
|
|
let options = FormatOptions(wrapArguments: .preserve)
|
|
testFormatting(for: input, rule: .wrapArguments,
|
|
options: options, exclude: [.wrapConditionalBodies])
|
|
}
|
|
|
|
// MARK: - --wrapArguments, --wrapParameter
|
|
|
|
// MARK: beforeFirst
|
|
|
|
func testNoMistakeTernaryExpressionForArguments() {
|
|
let input = """
|
|
(foo ?
|
|
bar :
|
|
baz)
|
|
"""
|
|
let options = FormatOptions(wrapArguments: .beforeFirst, wrapParameters: .beforeFirst)
|
|
testFormatting(for: input, rule: .wrapArguments, options: options,
|
|
exclude: [.redundantParens])
|
|
}
|
|
|
|
// MARK: beforeFirst, maxWidth : string interpolation
|
|
|
|
func testNoWrapBeforeFirstArgumentInStringInterpolation() {
|
|
let input = """
|
|
"a very long string literal with \\(interpolation) inside"
|
|
"""
|
|
let options = FormatOptions(wrapArguments: .beforeFirst,
|
|
wrapParameters: .beforeFirst,
|
|
maxWidth: 40)
|
|
testFormatting(for: input, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testNoWrapBeforeFirstArgumentInStringInterpolation2() {
|
|
let input = """
|
|
"a very long string literal with \\(interpolation) inside"
|
|
"""
|
|
let options = FormatOptions(wrapArguments: .beforeFirst,
|
|
wrapParameters: .beforeFirst,
|
|
maxWidth: 50)
|
|
testFormatting(for: input, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testNoWrapBeforeFirstArgumentInStringInterpolation3() {
|
|
let input = """
|
|
"a very long string literal with \\(interpolated, variables) inside"
|
|
"""
|
|
let options = FormatOptions(wrapArguments: .beforeFirst,
|
|
wrapParameters: .beforeFirst,
|
|
maxWidth: 40)
|
|
testFormatting(for: input, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testNoWrapBeforeNestedFirstArgumentInStringInterpolation() {
|
|
let input = """
|
|
"a very long string literal with \\(foo(interpolated)) inside"
|
|
"""
|
|
let options = FormatOptions(wrapArguments: .beforeFirst,
|
|
wrapParameters: .beforeFirst,
|
|
maxWidth: 45)
|
|
testFormatting(for: input, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testNoWrapBeforeNestedFirstArgumentInStringInterpolation2() {
|
|
let input = """
|
|
"a very long string literal with \\(foo(interpolated, variables)) inside"
|
|
"""
|
|
let options = FormatOptions(wrapArguments: .beforeFirst,
|
|
wrapParameters: .beforeFirst,
|
|
maxWidth: 45)
|
|
testFormatting(for: input, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testWrapProtocolFuncParametersBeforeFirst() {
|
|
let input = """
|
|
public protocol Foo {
|
|
public func stringify<T>(_ value: T, label: String) -> (T, String)
|
|
}
|
|
"""
|
|
let output = """
|
|
public protocol Foo {
|
|
public func stringify<T>(
|
|
_ value: T,
|
|
label: String
|
|
) -> (T, String)
|
|
}
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .beforeFirst, maxWidth: 30)
|
|
testFormatting(for: input, output, rule: .wrapArguments,
|
|
options: options)
|
|
}
|
|
|
|
// MARK: afterFirst maxWidth : string interpolation
|
|
|
|
func testNoWrapAfterFirstArgumentInStringInterpolation() {
|
|
let input = """
|
|
"a very long string literal with \\(interpolated) inside"
|
|
"""
|
|
let options = FormatOptions(wrapArguments: .afterFirst,
|
|
wrapParameters: .afterFirst,
|
|
maxWidth: 46)
|
|
testFormatting(for: input, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testNoWrapAfterFirstArgumentInStringInterpolation2() {
|
|
let input = """
|
|
"a very long string literal with \\(interpolated, variables) inside"
|
|
"""
|
|
let options = FormatOptions(wrapArguments: .afterFirst,
|
|
wrapParameters: .afterFirst,
|
|
maxWidth: 50)
|
|
testFormatting(for: input, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testNoWrapAfterNestedFirstArgumentInStringInterpolation() {
|
|
let input = """
|
|
"a very long string literal with \\(foo(interpolated, variables)) inside"
|
|
"""
|
|
let options = FormatOptions(wrapArguments: .afterFirst,
|
|
wrapParameters: .afterFirst,
|
|
maxWidth: 55)
|
|
testFormatting(for: input, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
// macros
|
|
|
|
func testWrapMacroParametersBeforeFirst() {
|
|
let input = """
|
|
@freestanding(expression)
|
|
public macro stringify<T>(_ value: T, label: String) -> (T, String)
|
|
"""
|
|
let output = """
|
|
@freestanding(expression)
|
|
public macro stringify<T>(
|
|
_ value: T,
|
|
label: String
|
|
) -> (T, String)
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .beforeFirst, maxWidth: 30)
|
|
testFormatting(for: input, output, rule: .wrapArguments,
|
|
options: options)
|
|
}
|
|
|
|
// MARK: - wrapArguments --wrapCollections
|
|
|
|
// MARK: beforeFirst
|
|
|
|
func testNoDoubleSpaceAddedToWrappedArray() {
|
|
let input = """
|
|
[ foo,
|
|
bar ]
|
|
"""
|
|
let output = """
|
|
[
|
|
foo,
|
|
bar
|
|
]
|
|
"""
|
|
let options = FormatOptions(trailingCommas: .never, wrapCollections: .beforeFirst)
|
|
testFormatting(for: input, [output], rules: [.wrapArguments, .spaceInsideBrackets],
|
|
options: options)
|
|
}
|
|
|
|
func testTrailingCommasAddedToWrappedArray() {
|
|
let input = """
|
|
[foo,
|
|
bar]
|
|
"""
|
|
let output = """
|
|
[
|
|
foo,
|
|
bar,
|
|
]
|
|
"""
|
|
let options = FormatOptions(trailingCommas: .always, wrapCollections: .beforeFirst)
|
|
testFormatting(for: input, [output], rules: [.wrapArguments, .trailingCommas],
|
|
options: options)
|
|
}
|
|
|
|
func testTrailingCommasAddedToWrappedNestedDictionary() {
|
|
let input = """
|
|
[foo: [bar: baz,
|
|
bar2: baz2]]
|
|
"""
|
|
let output = """
|
|
[foo: [
|
|
bar: baz,
|
|
bar2: baz2,
|
|
]]
|
|
"""
|
|
let options = FormatOptions(trailingCommas: .always, wrapCollections: .beforeFirst)
|
|
testFormatting(for: input, [output], rules: [.wrapArguments, .trailingCommas],
|
|
options: options)
|
|
}
|
|
|
|
func testTrailingCommasAddedToSingleLineNestedDictionary() {
|
|
let input = """
|
|
[
|
|
foo: [bar: baz, bar2: baz2]]
|
|
"""
|
|
let output = """
|
|
[
|
|
foo: [bar: baz, bar2: baz2],
|
|
]
|
|
"""
|
|
let options = FormatOptions(trailingCommas: .always, wrapCollections: .beforeFirst)
|
|
testFormatting(for: input, [output], rules: [.wrapArguments, .trailingCommas],
|
|
options: options)
|
|
}
|
|
|
|
func testTrailingCommasAddedToWrappedNestedDictionaries() {
|
|
let input = """
|
|
[foo: [bar: baz,
|
|
bar2: baz2],
|
|
foo2: [bar: baz,
|
|
bar2: baz2]]
|
|
"""
|
|
let output = """
|
|
[
|
|
foo: [
|
|
bar: baz,
|
|
bar2: baz2,
|
|
],
|
|
foo2: [
|
|
bar: baz,
|
|
bar2: baz2,
|
|
],
|
|
]
|
|
"""
|
|
let options = FormatOptions(trailingCommas: .always, wrapCollections: .beforeFirst)
|
|
testFormatting(for: input, [output], rules: [.wrapArguments, .trailingCommas],
|
|
options: options)
|
|
}
|
|
|
|
func testSpaceAroundEnumValuesInArray() {
|
|
let input = """
|
|
[
|
|
.foo,
|
|
.bar, .baz,
|
|
]
|
|
"""
|
|
let options = FormatOptions(wrapCollections: .beforeFirst)
|
|
testFormatting(for: input, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
// MARK: beforeFirst maxWidth
|
|
|
|
func testWrapCollectionOnOneLineBeforeFirstWidthExceededInChainedFunctionCallAfterCollection() {
|
|
let input = """
|
|
let foo = ["bar", "baz"].quux(quuz)
|
|
"""
|
|
let output = """
|
|
let foo = ["bar", "baz"]
|
|
.quux(quuz)
|
|
"""
|
|
let options = FormatOptions(wrapCollections: .beforeFirst, maxWidth: 26)
|
|
testFormatting(for: input, [output],
|
|
rules: [.wrap, .wrapArguments], options: options)
|
|
}
|
|
|
|
// MARK: afterFirst
|
|
|
|
func testTrailingCommaRemovedInWrappedArray() {
|
|
let input = """
|
|
[
|
|
.foo,
|
|
.bar,
|
|
.baz,
|
|
]
|
|
"""
|
|
let output = """
|
|
[.foo,
|
|
.bar,
|
|
.baz]
|
|
"""
|
|
let options = FormatOptions(wrapCollections: .afterFirst)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testNoRemoveLinebreakAfterCommentInElements() {
|
|
let input = """
|
|
[a, // comment
|
|
]
|
|
"""
|
|
let options = FormatOptions(wrapCollections: .afterFirst)
|
|
testFormatting(for: input, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testWrapCollectionsConsecutiveCodeCommentsNotIndented() {
|
|
let input = """
|
|
let a = [foo,
|
|
// bar,
|
|
// baz,
|
|
quux]
|
|
"""
|
|
let options = FormatOptions(wrapCollections: .afterFirst)
|
|
testFormatting(for: input, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testWrapCollectionsConsecutiveCodeCommentsNotIndentedInWrapBeforeFirst() {
|
|
let input = """
|
|
let a = [
|
|
foo,
|
|
// bar,
|
|
// baz,
|
|
quux,
|
|
]
|
|
"""
|
|
let options = FormatOptions(wrapCollections: .beforeFirst)
|
|
testFormatting(for: input, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
// MARK: preserve
|
|
|
|
func testNoBeforeFirstPreservedAndTrailingCommaIgnoredInMultilineNestedDictionary() {
|
|
let input = """
|
|
[foo: [bar: baz,
|
|
bar2: baz2]]
|
|
"""
|
|
let output = """
|
|
[foo: [bar: baz,
|
|
bar2: baz2]]
|
|
"""
|
|
let options = FormatOptions(trailingCommas: .always, wrapCollections: .preserve)
|
|
testFormatting(for: input, [output], rules: [.wrapArguments, .trailingCommas],
|
|
options: options)
|
|
}
|
|
|
|
func testBeforeFirstPreservedAndTrailingCommaAddedInSingleLineNestedDictionary() {
|
|
let input = """
|
|
[
|
|
foo: [bar: baz, bar2: baz2]]
|
|
"""
|
|
let output = """
|
|
[
|
|
foo: [bar: baz, bar2: baz2],
|
|
]
|
|
"""
|
|
let options = FormatOptions(trailingCommas: .always, wrapCollections: .preserve)
|
|
testFormatting(for: input, [output], rules: [.wrapArguments, .trailingCommas],
|
|
options: options)
|
|
}
|
|
|
|
func testBeforeFirstPreservedAndTrailingCommaAddedInSingleLineNestedDictionaryWithOneNestedItem() {
|
|
let input = """
|
|
[
|
|
foo: [bar: baz]]
|
|
"""
|
|
let output = """
|
|
[
|
|
foo: [bar: baz],
|
|
]
|
|
"""
|
|
let options = FormatOptions(trailingCommas: .always, wrapCollections: .preserve)
|
|
testFormatting(for: input, [output], rules: [.wrapArguments, .trailingCommas],
|
|
options: options)
|
|
}
|
|
|
|
// MARK: - wrapArguments --wrapCollections & --wrapArguments
|
|
|
|
// MARK: beforeFirst maxWidth
|
|
|
|
func testWrapArgumentsBeforeFirstWhenArgumentsExceedMaxWidthAndArgumentIsCollection() {
|
|
let input = """
|
|
foo(bar: ["baz", "quux"], quuz: corge)
|
|
"""
|
|
let output = """
|
|
foo(
|
|
bar: ["baz", "quux"],
|
|
quuz: corge
|
|
)
|
|
"""
|
|
let options = FormatOptions(wrapArguments: .beforeFirst,
|
|
wrapCollections: .beforeFirst,
|
|
maxWidth: 26)
|
|
testFormatting(for: input, [output],
|
|
rules: [.wrapArguments], options: options)
|
|
}
|
|
|
|
// MARK: afterFirst maxWidth
|
|
|
|
func testWrapArgumentsAfterFirstWhenArgumentsExceedMaxWidthAndArgumentIsCollection() {
|
|
let input = """
|
|
foo(bar: ["baz", "quux"], quuz: corge)
|
|
"""
|
|
let output = """
|
|
foo(bar: ["baz", "quux"],
|
|
quuz: corge)
|
|
"""
|
|
let options = FormatOptions(wrapArguments: .afterFirst,
|
|
wrapCollections: .beforeFirst,
|
|
maxWidth: 26)
|
|
testFormatting(for: input, [output],
|
|
rules: [.wrapArguments], options: options)
|
|
}
|
|
|
|
// MARK: - wrapArguments Multiple Wraps On Same Line
|
|
|
|
func testWrapAfterFirstWhenChainedFunctionAndThenArgumentsExceedMaxWidth() {
|
|
let input = """
|
|
foo.bar(baz: [qux, quux]).quuz([corge: grault], garply: waldo)
|
|
"""
|
|
let output = """
|
|
foo.bar(baz: [qux, quux])
|
|
.quuz([corge: grault],
|
|
garply: waldo)
|
|
"""
|
|
let options = FormatOptions(wrapArguments: .afterFirst,
|
|
wrapCollections: .afterFirst,
|
|
maxWidth: 28)
|
|
testFormatting(for: input, [output],
|
|
rules: [.wrapArguments, .wrap], options: options)
|
|
}
|
|
|
|
func testWrapAfterFirstWrapCollectionsBeforeFirstWhenChainedFunctionAndThenArgumentsExceedMaxWidth() {
|
|
let input = """
|
|
foo.bar(baz: [qux, quux]).quuz([corge: grault], garply: waldo)
|
|
"""
|
|
let output = """
|
|
foo.bar(baz: [qux, quux])
|
|
.quuz([corge: grault],
|
|
garply: waldo)
|
|
"""
|
|
let options = FormatOptions(wrapArguments: .afterFirst,
|
|
wrapCollections: .beforeFirst,
|
|
maxWidth: 28)
|
|
testFormatting(for: input, [output],
|
|
rules: [.wrapArguments, .wrap], options: options)
|
|
}
|
|
|
|
func testNoMangleNestedFunctionCalls() {
|
|
let input = """
|
|
points.append(.curve(
|
|
quadraticBezier(p0.position.x, Double(p1.x), Double(p2.x), t),
|
|
quadraticBezier(p0.position.y, Double(p1.y), Double(p2.y), t)
|
|
))
|
|
"""
|
|
let output = """
|
|
points.append(.curve(
|
|
quadraticBezier(
|
|
p0.position.x,
|
|
Double(p1.x),
|
|
Double(p2.x),
|
|
t
|
|
),
|
|
quadraticBezier(
|
|
p0.position.y,
|
|
Double(p1.y),
|
|
Double(p2.y),
|
|
t
|
|
)
|
|
))
|
|
"""
|
|
let options = FormatOptions(wrapArguments: .beforeFirst, maxWidth: 40)
|
|
testFormatting(for: input, [output],
|
|
rules: [.wrapArguments, .wrap], options: options)
|
|
}
|
|
|
|
func testWrapArguments_typealias_beforeFirst() {
|
|
let input = """
|
|
typealias Dependencies = FooProviding & BarProviding & BaazProviding & QuuxProviding
|
|
"""
|
|
|
|
let output = """
|
|
typealias Dependencies
|
|
= FooProviding
|
|
& BarProviding
|
|
& BaazProviding
|
|
& QuuxProviding
|
|
"""
|
|
|
|
let options = FormatOptions(wrapTypealiases: .beforeFirst, maxWidth: 40)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options, exclude: [.sortTypealiases])
|
|
}
|
|
|
|
func testWrapArguments_multipleTypealiases_beforeFirst() {
|
|
let input = """
|
|
enum Namespace {
|
|
typealias DependenciesA = FooProviding & BarProviding
|
|
typealias DependenciesB = BaazProviding & QuuxProviding
|
|
}
|
|
"""
|
|
|
|
let output = """
|
|
enum Namespace {
|
|
typealias DependenciesA
|
|
= FooProviding
|
|
& BarProviding
|
|
typealias DependenciesB
|
|
= BaazProviding
|
|
& QuuxProviding
|
|
}
|
|
"""
|
|
|
|
let options = FormatOptions(wrapTypealiases: .beforeFirst, maxWidth: 45)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options, exclude: [.sortTypealiases])
|
|
}
|
|
|
|
func testWrapArguments_typealias_afterFirst() {
|
|
let input = """
|
|
typealias Dependencies = FooProviding & BarProviding & BaazProviding & QuuxProviding
|
|
"""
|
|
|
|
let output = """
|
|
typealias Dependencies = FooProviding
|
|
& BarProviding
|
|
& BaazProviding
|
|
& QuuxProviding
|
|
"""
|
|
|
|
let options = FormatOptions(wrapTypealiases: .afterFirst, maxWidth: 40)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options, exclude: [.sortTypealiases])
|
|
}
|
|
|
|
func testWrapArguments_multipleTypealiases_afterFirst() {
|
|
let input = """
|
|
enum Namespace {
|
|
typealias DependenciesA = FooProviding & BarProviding
|
|
typealias DependenciesB = BaazProviding & QuuxProviding
|
|
}
|
|
"""
|
|
|
|
let output = """
|
|
enum Namespace {
|
|
typealias DependenciesA = FooProviding
|
|
& BarProviding
|
|
typealias DependenciesB = BaazProviding
|
|
& QuuxProviding
|
|
}
|
|
"""
|
|
|
|
let options = FormatOptions(wrapTypealiases: .afterFirst, maxWidth: 45)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options, exclude: [.sortTypealiases])
|
|
}
|
|
|
|
func testWrapArguments_typealias_shorterThanMaxWidth() {
|
|
let input = """
|
|
typealias Dependencies = FooProviding & BarProviding & BaazProviding
|
|
"""
|
|
|
|
let options = FormatOptions(wrapTypealiases: .afterFirst, maxWidth: 100)
|
|
testFormatting(for: input, rule: .wrapArguments, options: options, exclude: [.sortTypealiases])
|
|
}
|
|
|
|
func testWrapArguments_typealias_shorterThanMaxWidth_butWrappedInconsistently() {
|
|
let input = """
|
|
typealias Dependencies = FooProviding & BarProviding &
|
|
BaazProviding & QuuxProviding
|
|
"""
|
|
|
|
let output = """
|
|
typealias Dependencies = FooProviding
|
|
& BarProviding
|
|
& BaazProviding
|
|
& QuuxProviding
|
|
"""
|
|
|
|
let options = FormatOptions(wrapTypealiases: .afterFirst, maxWidth: 200)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options, exclude: [.sortTypealiases])
|
|
}
|
|
|
|
func testWrapArguments_typealias_shorterThanMaxWidth_butWrappedInconsistently2() {
|
|
let input = """
|
|
enum Namespace {
|
|
typealias Dependencies = FooProviding & BarProviding
|
|
& BaazProviding & QuuxProviding
|
|
}
|
|
"""
|
|
|
|
let output = """
|
|
enum Namespace {
|
|
typealias Dependencies
|
|
= FooProviding
|
|
& BarProviding
|
|
& BaazProviding
|
|
& QuuxProviding
|
|
}
|
|
"""
|
|
|
|
let options = FormatOptions(wrapTypealiases: .beforeFirst, maxWidth: 200)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options, exclude: [.sortTypealiases])
|
|
}
|
|
|
|
func testWrapArguments_typealias_shorterThanMaxWidth_butWrappedInconsistently3() {
|
|
let input = """
|
|
typealias Dependencies
|
|
= FooProviding & BarProviding &
|
|
BaazProviding & QuuxProviding
|
|
"""
|
|
|
|
let output = """
|
|
typealias Dependencies = FooProviding
|
|
& BarProviding
|
|
& BaazProviding
|
|
& QuuxProviding
|
|
"""
|
|
|
|
let options = FormatOptions(wrapTypealiases: .afterFirst, maxWidth: 200)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options, exclude: [.sortTypealiases])
|
|
}
|
|
|
|
func testWrapArguments_typealias_shorterThanMaxWidth_butWrappedInconsistently4() {
|
|
let input = """
|
|
typealias Dependencies
|
|
= FooProviding
|
|
& BarProviding
|
|
& BaazProviding
|
|
& QuuxProviding
|
|
"""
|
|
|
|
let output = """
|
|
typealias Dependencies = FooProviding
|
|
& BarProviding
|
|
& BaazProviding
|
|
& QuuxProviding
|
|
"""
|
|
|
|
let options = FormatOptions(wrapTypealiases: .afterFirst, maxWidth: 200)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options, exclude: [.sortTypealiases])
|
|
}
|
|
|
|
func testWrapArguments_typealias_shorterThanMaxWidth_butWrappedInconsistentlyWithComment() {
|
|
let input = """
|
|
typealias Dependencies = FooProviding & BarProviding // trailing comment 1
|
|
// Inline Comment 1
|
|
& BaazProviding & QuuxProviding // trailing comment 2
|
|
"""
|
|
|
|
let output = """
|
|
typealias Dependencies
|
|
= FooProviding
|
|
& BarProviding // trailing comment 1
|
|
// Inline Comment 1
|
|
& BaazProviding
|
|
& QuuxProviding // trailing comment 2
|
|
"""
|
|
|
|
let options = FormatOptions(wrapTypealiases: .beforeFirst, maxWidth: 200)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options, exclude: [.sortTypealiases])
|
|
}
|
|
|
|
func testWrapArguments_typealias_singleTypePreserved() {
|
|
let input = """
|
|
typealias Dependencies = FooProviding
|
|
"""
|
|
|
|
let options = FormatOptions(wrapTypealiases: .beforeFirst, maxWidth: 10)
|
|
testFormatting(for: input, rule: .wrapArguments, options: options, exclude: [.wrap])
|
|
}
|
|
|
|
func testWrapArguments_typealias_preservesCommentsBetweenTypes() {
|
|
let input = """
|
|
typealias Dependencies
|
|
// We use `FooProviding` because `FooFeature` depends on `Foo`
|
|
= FooProviding
|
|
// We use `BarProviding` because `BarFeature` depends on `Bar`
|
|
& BarProviding
|
|
// We use `BaazProviding` because `BaazFeature` depends on `Baaz`
|
|
& BaazProviding
|
|
"""
|
|
|
|
let options = FormatOptions(wrapTypealiases: .beforeFirst, maxWidth: 100)
|
|
testFormatting(for: input, rule: .wrapArguments, options: options, exclude: [.sortTypealiases])
|
|
}
|
|
|
|
func testWrapArguments_typealias_preservesCommentsAfterTypes() {
|
|
let input = """
|
|
typealias Dependencies
|
|
= FooProviding // We use `FooProviding` because `FooFeature` depends on `Foo`
|
|
& BarProviding // We use `BarProviding` because `BarFeature` depends on `Bar`
|
|
& BaazProviding // We use `BaazProviding` because `BaazFeature` depends on `Baaz`
|
|
"""
|
|
|
|
let options = FormatOptions(wrapTypealiases: .beforeFirst, maxWidth: 100)
|
|
testFormatting(for: input, rule: .wrapArguments, options: options, exclude: [.sortTypealiases])
|
|
}
|
|
|
|
func testWrapArguments_typealias_withAssociatedType() {
|
|
let input = """
|
|
typealias Collections = Collection<Int> & Collection<String> & Collection<Double> & Collection<Float>
|
|
"""
|
|
|
|
let output = """
|
|
typealias Collections
|
|
= Collection<Int>
|
|
& Collection<String>
|
|
& Collection<Double>
|
|
& Collection<Float>
|
|
"""
|
|
|
|
let options = FormatOptions(wrapTypealiases: .beforeFirst, maxWidth: 50)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options, exclude: [.sortTypealiases])
|
|
}
|
|
|
|
// MARK: - -return wrap-if-multiline
|
|
|
|
func testWrapReturnOnMultilineFunctionDeclaration() {
|
|
let input = """
|
|
func multilineFunction(
|
|
foo _: String,
|
|
bar _: String) -> String {}
|
|
"""
|
|
|
|
let output = """
|
|
func multilineFunction(
|
|
foo _: String,
|
|
bar _: String)
|
|
-> String {}
|
|
"""
|
|
|
|
let options = FormatOptions(
|
|
wrapArguments: .beforeFirst,
|
|
closingParenPosition: .sameLine,
|
|
wrapReturnType: .ifMultiline
|
|
)
|
|
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testWrapReturnOnMultilineFunctionDeclarationInProtocol() {
|
|
let input = """
|
|
protocol MyProtocol {
|
|
func multilineFunction(
|
|
foo _: String,
|
|
bar _: String) -> String
|
|
}
|
|
"""
|
|
|
|
let output = """
|
|
protocol MyProtocol {
|
|
func multilineFunction(
|
|
foo _: String,
|
|
bar _: String)
|
|
-> String
|
|
}
|
|
"""
|
|
|
|
let options = FormatOptions(
|
|
wrapArguments: .beforeFirst,
|
|
closingParenPosition: .sameLine,
|
|
wrapReturnType: .ifMultiline
|
|
)
|
|
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testWrapReturnAndEffectOnMultilineFunctionDeclaration() {
|
|
let input = """
|
|
func multilineFunction(
|
|
foo _: String,
|
|
bar _: String) async -> String {}
|
|
"""
|
|
|
|
let output = """
|
|
func multilineFunction(
|
|
foo _: String,
|
|
bar _: String)
|
|
async -> String {}
|
|
"""
|
|
|
|
let options = FormatOptions(
|
|
wrapArguments: .beforeFirst,
|
|
closingParenPosition: .sameLine,
|
|
wrapReturnType: .ifMultiline,
|
|
wrapEffects: .ifMultiline
|
|
)
|
|
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testDoesntWrapReturnAndEffectOnSingleLineFunctionDeclaration() {
|
|
let input = """
|
|
func singleLineFunction() async throws -> String {}
|
|
"""
|
|
|
|
let options = FormatOptions(
|
|
wrapArguments: .beforeFirst,
|
|
closingParenPosition: .sameLine,
|
|
wrapReturnType: .ifMultiline,
|
|
wrapEffects: .ifMultiline
|
|
)
|
|
|
|
testFormatting(for: input, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testDoesntWrapReturnAndTypedEffectOnSingleLineFunctionDeclaration() {
|
|
let input = """
|
|
func singleLineFunction() async throws(Foo) -> String {}
|
|
"""
|
|
|
|
let options = FormatOptions(
|
|
wrapArguments: .beforeFirst,
|
|
closingParenPosition: .sameLine,
|
|
wrapReturnType: .ifMultiline,
|
|
wrapEffects: .ifMultiline
|
|
)
|
|
|
|
testFormatting(for: input, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testWrapEffectOnMultilineFunctionDeclaration() {
|
|
let input = """
|
|
func multilineFunction(
|
|
foo _: String,
|
|
bar _: String) async throws
|
|
-> String {}
|
|
"""
|
|
|
|
let output = """
|
|
func multilineFunction(
|
|
foo _: String,
|
|
bar _: String)
|
|
async throws -> String {}
|
|
"""
|
|
|
|
let options = FormatOptions(
|
|
wrapArguments: .beforeFirst,
|
|
closingParenPosition: .sameLine,
|
|
wrapReturnType: .ifMultiline,
|
|
wrapEffects: .ifMultiline
|
|
)
|
|
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testUnwrapEffectOnMultilineInit() {
|
|
let input = """
|
|
init(
|
|
foo: String,
|
|
bar: String
|
|
)
|
|
async throws
|
|
{
|
|
print(foo, bar)
|
|
}
|
|
"""
|
|
|
|
let output = """
|
|
init(
|
|
foo: String,
|
|
bar: String
|
|
) async throws {
|
|
print(foo, bar)
|
|
}
|
|
"""
|
|
|
|
let options = FormatOptions(
|
|
wrapArguments: .beforeFirst,
|
|
closingParenPosition: .balanced,
|
|
wrapReturnType: .never,
|
|
wrapEffects: .never
|
|
)
|
|
|
|
testFormatting(for: input, [output], rules: [.wrapArguments, .braces], options: options)
|
|
}
|
|
|
|
func testWrapEffectOnMultilineProtocolRequirement() {
|
|
let input = """
|
|
protocol MyProtocol {
|
|
func multilineFunction(
|
|
foo _: String,
|
|
bar _: String) async throws
|
|
-> String
|
|
}
|
|
"""
|
|
|
|
let output = """
|
|
protocol MyProtocol {
|
|
func multilineFunction(
|
|
foo _: String,
|
|
bar _: String)
|
|
async throws -> String
|
|
}
|
|
"""
|
|
|
|
let options = FormatOptions(
|
|
wrapArguments: .beforeFirst,
|
|
closingParenPosition: .sameLine,
|
|
wrapReturnType: .ifMultiline,
|
|
wrapEffects: .ifMultiline
|
|
)
|
|
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testUnwrapEffectOnMultilineFunctionDeclaration() {
|
|
let input = """
|
|
func multilineFunction(
|
|
foo _: String,
|
|
bar _: String)
|
|
async throws -> String {}
|
|
"""
|
|
|
|
let output = """
|
|
func multilineFunction(
|
|
foo _: String,
|
|
bar _: String) async throws
|
|
-> String {}
|
|
"""
|
|
|
|
let options = FormatOptions(
|
|
wrapArguments: .beforeFirst,
|
|
closingParenPosition: .sameLine,
|
|
wrapReturnType: .ifMultiline,
|
|
wrapEffects: .never
|
|
)
|
|
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testUnwrapEffectAndReturnTypeOnMultilineFunctionDeclaration() {
|
|
let input = """
|
|
func multilineFunction(
|
|
foo _: String,
|
|
bar _: String)
|
|
async throws -> String {}
|
|
"""
|
|
|
|
let output = """
|
|
func multilineFunction(
|
|
foo _: String,
|
|
bar _: String
|
|
) async throws -> String {}
|
|
"""
|
|
|
|
let options = FormatOptions(
|
|
wrapArguments: .beforeFirst,
|
|
closingParenPosition: .balanced,
|
|
wrapReturnType: .never,
|
|
wrapEffects: .never
|
|
)
|
|
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testFormatReturnTypeOnMultilineFunctionDeclarationWithLineComment() {
|
|
let input = """
|
|
func multilineFunction(
|
|
foo _: String,
|
|
bar _: String)
|
|
async throws
|
|
-> String // this is a comment
|
|
{}
|
|
"""
|
|
|
|
let output = """
|
|
func multilineFunction(
|
|
foo _: String,
|
|
bar _: String
|
|
) async throws -> String // this is a comment
|
|
{}
|
|
"""
|
|
|
|
let options = FormatOptions(
|
|
wrapArguments: .beforeFirst,
|
|
closingParenPosition: .balanced,
|
|
wrapReturnType: .never,
|
|
wrapEffects: .never
|
|
)
|
|
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testUnwrapClosingBraceInVoidThrowingMethod() {
|
|
let input = """
|
|
func multilineFunction(
|
|
foo: String,
|
|
bar: String)
|
|
async throws
|
|
{
|
|
print(foo, bar)
|
|
}
|
|
"""
|
|
|
|
let output = """
|
|
func multilineFunction(
|
|
foo: String,
|
|
bar: String
|
|
) async throws {
|
|
print(foo, bar)
|
|
}
|
|
"""
|
|
|
|
let options = FormatOptions(
|
|
wrapArguments: .beforeFirst,
|
|
closingParenPosition: .balanced,
|
|
wrapReturnType: .never,
|
|
wrapEffects: .never
|
|
)
|
|
|
|
testFormatting(for: input, [output], rules: [.wrapArguments, .braces], options: options)
|
|
}
|
|
|
|
func testUnwrapClosingBraceInVoidNonThrowingMethod() {
|
|
let input = """
|
|
func multilineFunction(
|
|
foo: String,
|
|
bar: String)
|
|
{
|
|
print(foo, bar)
|
|
}
|
|
"""
|
|
|
|
let output = """
|
|
func multilineFunction(
|
|
foo: String,
|
|
bar: String
|
|
) {
|
|
print(foo, bar)
|
|
}
|
|
"""
|
|
|
|
let options = FormatOptions(
|
|
wrapArguments: .beforeFirst,
|
|
closingParenPosition: .balanced,
|
|
wrapReturnType: .never,
|
|
wrapEffects: .never
|
|
)
|
|
|
|
testFormatting(for: input, [output], rules: [.wrapArguments, .braces], options: options)
|
|
}
|
|
|
|
func testWrapReturnIfMultilineOnClosureArgument() {
|
|
let input = """
|
|
func multilineFunctionWithClosureArgument(
|
|
closure: ((
|
|
_ view: ChartContainerView<Self>,
|
|
_ content: Content,
|
|
_ traitCollection: UITraitCollection,
|
|
_ state: ItemCellState) -> Void)? = nil) -> String
|
|
{
|
|
print(closure)
|
|
}
|
|
"""
|
|
|
|
let output = """
|
|
func multilineFunctionWithClosureArgument(
|
|
closure: ((
|
|
_ view: ChartContainerView<Self>,
|
|
_ content: Content,
|
|
_ traitCollection: UITraitCollection,
|
|
_ state: ItemCellState)
|
|
-> Void)? = nil)
|
|
-> String
|
|
{
|
|
print(closure)
|
|
}
|
|
"""
|
|
|
|
let options = FormatOptions(
|
|
wrapArguments: .beforeFirst,
|
|
closingParenPosition: .sameLine,
|
|
wrapReturnType: .ifMultiline,
|
|
maxWidth: 100
|
|
)
|
|
|
|
testFormatting(for: input, [output], rules: [.wrapArguments, .wrap, .indent], options: options)
|
|
}
|
|
|
|
func testPreservesReturnInClosure() {
|
|
let input = """
|
|
public private(set) var foo: ((
|
|
UIAccessibility.Notification,
|
|
Any?,
|
|
Bool,
|
|
TimeInterval,
|
|
String,
|
|
Int,
|
|
String) -> Void)?
|
|
"""
|
|
|
|
let output = """
|
|
public private(set) var foo: ((
|
|
UIAccessibility.Notification,
|
|
Any?,
|
|
Bool,
|
|
TimeInterval,
|
|
String,
|
|
Int,
|
|
String)
|
|
-> Void)?
|
|
"""
|
|
|
|
let options = FormatOptions(
|
|
wrapArguments: .beforeFirst,
|
|
wrapCollections: .beforeFirst,
|
|
closingParenPosition: .sameLine,
|
|
wrapReturnType: .ifMultiline,
|
|
maxWidth: 100,
|
|
wrapEffects: .ifMultiline
|
|
)
|
|
|
|
testFormatting(for: input, [output], rules: [.wrapArguments, .wrap], options: options)
|
|
}
|
|
|
|
func testFormatReturnTypeOnMultilineFunctionDeclarationWithBlockComment() {
|
|
let input = """
|
|
func multilineFunction(
|
|
foo _: String,
|
|
bar _: String)
|
|
async throws
|
|
-> String /* block comment */
|
|
{}
|
|
"""
|
|
|
|
let output = """
|
|
func multilineFunction(
|
|
foo _: String,
|
|
bar _: String
|
|
) async throws -> String /* block comment */ {}
|
|
"""
|
|
|
|
let options = FormatOptions(
|
|
wrapArguments: .beforeFirst,
|
|
closingParenPosition: .balanced,
|
|
wrapReturnType: .never,
|
|
wrapEffects: .never
|
|
)
|
|
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testUnwrapReturnTypeOnMultilineFunctionDeclaration() {
|
|
let input = """
|
|
func multilineFunction(
|
|
foo _: String,
|
|
bar _: String)
|
|
-> String {}
|
|
"""
|
|
|
|
let output = """
|
|
func multilineFunction(
|
|
foo _: String,
|
|
bar _: String
|
|
) -> String {}
|
|
"""
|
|
|
|
let options = FormatOptions(
|
|
wrapArguments: .beforeFirst,
|
|
closingParenPosition: .balanced,
|
|
wrapReturnType: .never,
|
|
wrapEffects: .never
|
|
)
|
|
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testUnwrapReturnTypeOnMultilineSubscriptDeclaration() {
|
|
let input = """
|
|
subscript(
|
|
foo _: String,
|
|
bar _: String)
|
|
-> String {}
|
|
"""
|
|
|
|
let output = """
|
|
subscript(
|
|
foo _: String,
|
|
bar _: String
|
|
) -> String {}
|
|
"""
|
|
|
|
let options = FormatOptions(
|
|
wrapArguments: .beforeFirst,
|
|
closingParenPosition: .balanced,
|
|
wrapReturnType: .never,
|
|
wrapEffects: .never
|
|
)
|
|
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testUnwrapBraceForReturnTypeOnMultilineFunctionDeclaration() {
|
|
let input = """
|
|
func multilineFunction(
|
|
foo _: String,
|
|
bar _: String)
|
|
-> String
|
|
{
|
|
print("hello")
|
|
}
|
|
"""
|
|
|
|
let output = """
|
|
func multilineFunction(
|
|
foo _: String,
|
|
bar _: String
|
|
) -> String {
|
|
print("hello")
|
|
}
|
|
"""
|
|
|
|
let options = FormatOptions(
|
|
wrapArguments: .beforeFirst,
|
|
closingParenPosition: .balanced,
|
|
wrapReturnType: .never,
|
|
wrapEffects: .never
|
|
)
|
|
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testAllmanBraceWithWrapReturnTypeNever() {
|
|
let input = """
|
|
func makeStuff(
|
|
param1: String = "",
|
|
param2: Int? = nil,
|
|
param3: String = ""
|
|
) -> String {
|
|
print(param1, param2, param3)
|
|
return "return"
|
|
}
|
|
"""
|
|
let output = """
|
|
func makeStuff(
|
|
param1: String = "",
|
|
param2: Int? = nil,
|
|
param3: String = ""
|
|
) -> String
|
|
{
|
|
print(param1, param2, param3)
|
|
return "return"
|
|
}
|
|
"""
|
|
let options = FormatOptions(allmanBraces: true, wrapReturnType: .never)
|
|
testFormatting(for: input, [output], rules: [.wrapArguments, .braces], options: options)
|
|
}
|
|
|
|
func testWrapArgumentsDoesntBreakFunctionDeclaration_issue_1776() {
|
|
let input = """
|
|
struct OpenAPIController: RouteCollection {
|
|
let info = InfoObject(title: "Swagger {{cookiecutter.service_name}} - OpenAPI",
|
|
description: "{{cookiecutter.description}}",
|
|
contact: .init(email: "{{cookiecutter.email}}"),
|
|
version: Version(0, 0, 1))
|
|
func boot(routes: RoutesBuilder) throws {
|
|
routes.get("swagger", "swagger.json") {
|
|
$0.application.routes.openAPI(info: info)
|
|
}
|
|
.excludeFromOpenAPI()
|
|
}
|
|
}
|
|
"""
|
|
|
|
let options = FormatOptions(wrapEffects: .never)
|
|
testFormatting(for: input, rule: .wrapArguments, options: options, exclude: [.propertyTypes])
|
|
}
|
|
|
|
func testWrapEffectsNeverPreservesComments() {
|
|
let input = """
|
|
func multilineFunction(
|
|
foo _: String,
|
|
bar _: String)
|
|
// Comment here between the parameters and effects
|
|
async throws -> String {}
|
|
"""
|
|
|
|
let output = """
|
|
func multilineFunction(
|
|
foo _: String,
|
|
bar _: String) async throws -> String {}
|
|
"""
|
|
|
|
let options = FormatOptions(closingParenPosition: .sameLine, wrapEffects: .never)
|
|
testFormatting(
|
|
for: input, output, rule: .wrapArguments, options: options,
|
|
exclude: [.indent]
|
|
)
|
|
}
|
|
|
|
func testWrapReturnOnMultilineFunctionDeclarationWithAfterFirst() {
|
|
let input = """
|
|
func multilineFunction(foo _: String,
|
|
bar _: String) -> String {}
|
|
"""
|
|
|
|
let output = """
|
|
func multilineFunction(foo _: String,
|
|
bar _: String)
|
|
-> String {}
|
|
"""
|
|
|
|
let options = FormatOptions(
|
|
wrapArguments: .afterFirst,
|
|
closingParenPosition: .sameLine,
|
|
wrapReturnType: .ifMultiline
|
|
)
|
|
|
|
testFormatting(
|
|
for: input, output, rule: .wrapArguments, options: options,
|
|
exclude: [.indent]
|
|
)
|
|
}
|
|
|
|
func testWrapReturnOnMultilineThrowingFunctionDeclarationWithAfterFirst() {
|
|
let input = """
|
|
func multilineFunction(foo _: String,
|
|
bar _: String) throws -> String {}
|
|
"""
|
|
|
|
let output = """
|
|
func multilineFunction(foo _: String,
|
|
bar _: String) throws
|
|
-> String {}
|
|
"""
|
|
|
|
let options = FormatOptions(
|
|
wrapArguments: .afterFirst,
|
|
closingParenPosition: .sameLine,
|
|
wrapReturnType: .ifMultiline
|
|
)
|
|
|
|
testFormatting(
|
|
for: input, output, rule: .wrapArguments, options: options,
|
|
exclude: [.indent]
|
|
)
|
|
}
|
|
|
|
func testWrapReturnAndEffectOnMultilineThrowingFunctionDeclarationWithAfterFirst() {
|
|
let input = """
|
|
func multilineFunction(foo _: String,
|
|
bar _: String) throws -> String {}
|
|
"""
|
|
|
|
let output = """
|
|
func multilineFunction(foo _: String,
|
|
bar _: String)
|
|
throws -> String {}
|
|
"""
|
|
|
|
let options = FormatOptions(
|
|
wrapArguments: .afterFirst,
|
|
closingParenPosition: .sameLine,
|
|
wrapReturnType: .ifMultiline,
|
|
wrapEffects: .ifMultiline
|
|
)
|
|
|
|
testFormatting(
|
|
for: input, output, rule: .wrapArguments, options: options,
|
|
exclude: [.indent]
|
|
)
|
|
}
|
|
|
|
func testWrapEffectsNeverDoesntUnwrapAsyncLet() {
|
|
let input = """
|
|
async let createdAd = createAd(
|
|
subcategoryID: subcategory.id,
|
|
shopID: shop?.id)
|
|
async let locationCity = createEditAdWorker.loadNearestCity(coordinates: coordinates)
|
|
"""
|
|
|
|
let options = FormatOptions(
|
|
wrapArguments: .beforeFirst,
|
|
closingParenPosition: .sameLine,
|
|
wrapReturnType: .ifMultiline,
|
|
wrapEffects: .ifMultiline
|
|
)
|
|
|
|
testFormatting(for: input, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testWrapEffectsWrapsAsyncEffectBeforeLetProperty() {
|
|
let input = """
|
|
@attached(body) macro GenerateBody() = #externalMacro(module: "...", type: "...")
|
|
|
|
@GenerateBody // generates the body
|
|
func foo(
|
|
_ bar: Baaz,
|
|
_ baaz: Baaz) async
|
|
|
|
let quux: Quux
|
|
"""
|
|
|
|
let output = """
|
|
@attached(body) macro GenerateBody() = #externalMacro(module: "...", type: "...")
|
|
|
|
@GenerateBody // generates the body
|
|
func foo(
|
|
_ bar: Baaz,
|
|
_ baaz: Baaz)
|
|
async
|
|
|
|
let quux: Quux
|
|
"""
|
|
|
|
let options = FormatOptions(
|
|
wrapArguments: .beforeFirst,
|
|
closingParenPosition: .sameLine,
|
|
wrapReturnType: .ifMultiline,
|
|
wrapEffects: .ifMultiline
|
|
)
|
|
|
|
testFormatting(for: input, [output], rules: [.wrapArguments, .indent], options: options)
|
|
}
|
|
|
|
func testWrapsThrowsBeforeAsyncLet() {
|
|
let input = """
|
|
@GenerateBody // generates the body
|
|
func foo(
|
|
_ bar: Baaz,
|
|
_ baaz: Baaz) throws
|
|
|
|
async let quux: Quux
|
|
"""
|
|
|
|
let output = """
|
|
@GenerateBody // generates the body
|
|
func foo(
|
|
_ bar: Baaz,
|
|
_ baaz: Baaz)
|
|
throws
|
|
|
|
async let quux: Quux
|
|
"""
|
|
|
|
let options = FormatOptions(
|
|
wrapArguments: .beforeFirst,
|
|
closingParenPosition: .sameLine,
|
|
wrapReturnType: .ifMultiline,
|
|
wrapEffects: .ifMultiline
|
|
)
|
|
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testDoesntWrapReturnOnMultilineThrowingFunction() {
|
|
let input = """
|
|
func multilineFunction(foo _: String,
|
|
bar _: String)
|
|
throws -> String {}
|
|
"""
|
|
|
|
let options = FormatOptions(
|
|
wrapArguments: .afterFirst,
|
|
closingParenPosition: .sameLine,
|
|
wrapReturnType: .ifMultiline
|
|
)
|
|
|
|
testFormatting(
|
|
for: input, rule: .wrapArguments, options: options,
|
|
exclude: [.indent]
|
|
)
|
|
}
|
|
|
|
func testDoesntWrapReturnOnSingleLineFunctionDeclaration() {
|
|
let input = """
|
|
func multilineFunction(foo _: String, bar _: String) -> String {}
|
|
"""
|
|
|
|
let options = FormatOptions(
|
|
wrapArguments: .beforeFirst,
|
|
closingParenPosition: .sameLine,
|
|
wrapReturnType: .ifMultiline
|
|
)
|
|
|
|
testFormatting(for: input, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testDoesntWrapReturnOnSingleLineFunctionDeclarationAfterMultilineArray() {
|
|
let input = """
|
|
final class Foo {
|
|
private static let array = [
|
|
"one",
|
|
]
|
|
|
|
private func singleLine() -> String {}
|
|
}
|
|
"""
|
|
|
|
let options = FormatOptions(
|
|
wrapArguments: .beforeFirst,
|
|
closingParenPosition: .sameLine,
|
|
wrapReturnType: .ifMultiline
|
|
)
|
|
|
|
testFormatting(for: input, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testDoesntWrapReturnOnSingleLineFunctionDeclarationAfterMultilineMethodCall() {
|
|
let input = """
|
|
public final class Foo {
|
|
public var multiLineMethodCall = Foo.multiLineMethodCall(
|
|
bar: bar,
|
|
baz: baz)
|
|
|
|
func singleLine() -> String {
|
|
return "method body"
|
|
}
|
|
}
|
|
"""
|
|
|
|
let options = FormatOptions(
|
|
wrapArguments: .beforeFirst,
|
|
closingParenPosition: .sameLine,
|
|
wrapReturnType: .ifMultiline
|
|
)
|
|
|
|
testFormatting(for: input, rule: .wrapArguments, options: options, exclude: [.propertyTypes])
|
|
}
|
|
|
|
func testPreserveReturnOnMultilineFunctionDeclarationByDefault() {
|
|
let input = """
|
|
func multilineFunction(
|
|
foo _: String,
|
|
bar _: String) -> String
|
|
{}
|
|
"""
|
|
|
|
let options = FormatOptions(
|
|
wrapArguments: .beforeFirst,
|
|
closingParenPosition: .sameLine
|
|
)
|
|
|
|
testFormatting(for: input, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
// MARK: wrapConditions before-first
|
|
|
|
func testWrapConditionsBeforeFirstPreservesMultilineStatements() {
|
|
let input = """
|
|
if
|
|
let unwrappedFoo = Foo(
|
|
bar: bar,
|
|
baz: baz),
|
|
unwrappedFoo.elements
|
|
.compactMap({ $0 })
|
|
.filter({
|
|
if $0.matchesCondition {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
})
|
|
.isEmpty,
|
|
let bar = unwrappedFoo.bar,
|
|
let baz = unwrappedFoo.bar?
|
|
.first(where: { $0.isBaz }),
|
|
let unwrappedFoo2 = Foo(
|
|
bar: bar2,
|
|
baz: baz2),
|
|
let quux = baz.quux
|
|
{}
|
|
"""
|
|
testFormatting(
|
|
for: input, rules: [.wrapArguments, .indent],
|
|
options: FormatOptions(closingParenPosition: .sameLine, wrapConditions: .beforeFirst),
|
|
exclude: [.propertyTypes]
|
|
)
|
|
}
|
|
|
|
func testWrapConditionsBeforeFirst() {
|
|
let input = """
|
|
if let foo = foo,
|
|
let bar = bar,
|
|
foo == bar {}
|
|
|
|
else if foo != bar,
|
|
let quux = quux {}
|
|
|
|
if let baz = baz {}
|
|
|
|
guard baz.filter({ $0 == foo }),
|
|
let bar = bar else {}
|
|
|
|
while let foo = foo,
|
|
let bar = bar {}
|
|
"""
|
|
let output = """
|
|
if
|
|
let foo = foo,
|
|
let bar = bar,
|
|
foo == bar {}
|
|
|
|
else if
|
|
foo != bar,
|
|
let quux = quux {}
|
|
|
|
if let baz = baz {}
|
|
|
|
guard
|
|
baz.filter({ $0 == foo }),
|
|
let bar = bar else {}
|
|
|
|
while
|
|
let foo = foo,
|
|
let bar = bar {}
|
|
"""
|
|
testFormatting(
|
|
for: input, output, rule: .wrapArguments,
|
|
options: FormatOptions(indent: " ", wrapConditions: .beforeFirst),
|
|
exclude: [.wrapConditionalBodies]
|
|
)
|
|
}
|
|
|
|
func testWrapConditionsBeforeFirstWhereShouldPreserveExisting() {
|
|
let input = """
|
|
else {}
|
|
|
|
else
|
|
{}
|
|
|
|
if foo == bar
|
|
{}
|
|
|
|
guard let foo = bar else
|
|
{}
|
|
|
|
guard let foo = bar
|
|
else {}
|
|
"""
|
|
testFormatting(
|
|
for: input, rule: .wrapArguments,
|
|
options: FormatOptions(indent: " ", wrapConditions: .beforeFirst),
|
|
exclude: [.elseOnSameLine, .wrapConditionalBodies, .blankLinesAfterGuardStatements]
|
|
)
|
|
}
|
|
|
|
func testWrapConditionsAfterFirst() {
|
|
let input = """
|
|
if
|
|
let foo = foo,
|
|
let bar = bar,
|
|
foo == bar {}
|
|
|
|
else if
|
|
foo != bar,
|
|
let quux = quux {}
|
|
|
|
else {}
|
|
|
|
if let baz = baz {}
|
|
|
|
guard
|
|
baz.filter({ $0 == foo }),
|
|
let bar = bar else {}
|
|
|
|
while
|
|
let foo = foo,
|
|
let bar = bar {}
|
|
"""
|
|
let output = """
|
|
if let foo = foo,
|
|
let bar = bar,
|
|
foo == bar {}
|
|
|
|
else if foo != bar,
|
|
let quux = quux {}
|
|
|
|
else {}
|
|
|
|
if let baz = baz {}
|
|
|
|
guard baz.filter({ $0 == foo }),
|
|
let bar = bar else {}
|
|
|
|
while let foo = foo,
|
|
let bar = bar {}
|
|
"""
|
|
testFormatting(
|
|
for: input, output, rule: .wrapArguments,
|
|
options: FormatOptions(indent: " ", wrapConditions: .afterFirst),
|
|
exclude: [.wrapConditionalBodies]
|
|
)
|
|
}
|
|
|
|
func testWrapConditionsAfterFirstWhenFirstLineIsComment() {
|
|
let input = """
|
|
guard
|
|
// Apply this rule to any function-like declaration
|
|
["func", "init", "subscript"].contains(keyword.string),
|
|
// Opaque generic parameter syntax is only supported in Swift 5.7+
|
|
formatter.options.swiftVersion >= "5.7",
|
|
// Validate that this is a generic method using angle bracket syntax,
|
|
// and find the indices for all of the key tokens
|
|
let paramListStartIndex = formatter.index(of: .startOfScope("("), after: keywordIndex),
|
|
let paramListEndIndex = formatter.endOfScope(at: paramListStartIndex),
|
|
let genericSignatureStartIndex = formatter.index(of: .startOfScope("<"), after: keywordIndex),
|
|
let genericSignatureEndIndex = formatter.endOfScope(at: genericSignatureStartIndex),
|
|
genericSignatureStartIndex < paramListStartIndex,
|
|
genericSignatureEndIndex < paramListStartIndex,
|
|
let openBraceIndex = formatter.index(of: .startOfScope("{"), after: paramListEndIndex),
|
|
let closeBraceIndex = formatter.endOfScope(at: openBraceIndex)
|
|
else { return }
|
|
"""
|
|
let output = """
|
|
guard // Apply this rule to any function-like declaration
|
|
["func", "init", "subscript"].contains(keyword.string),
|
|
// Opaque generic parameter syntax is only supported in Swift 5.7+
|
|
formatter.options.swiftVersion >= "5.7",
|
|
// Validate that this is a generic method using angle bracket syntax,
|
|
// and find the indices for all of the key tokens
|
|
let paramListStartIndex = formatter.index(of: .startOfScope("("), after: keywordIndex),
|
|
let paramListEndIndex = formatter.endOfScope(at: paramListStartIndex),
|
|
let genericSignatureStartIndex = formatter.index(of: .startOfScope("<"), after: keywordIndex),
|
|
let genericSignatureEndIndex = formatter.endOfScope(at: genericSignatureStartIndex),
|
|
genericSignatureStartIndex < paramListStartIndex,
|
|
genericSignatureEndIndex < paramListStartIndex,
|
|
let openBraceIndex = formatter.index(of: .startOfScope("{"), after: paramListEndIndex),
|
|
let closeBraceIndex = formatter.endOfScope(at: openBraceIndex)
|
|
else { return }
|
|
"""
|
|
testFormatting(
|
|
for: input, [output], rules: [.wrapArguments, .indent],
|
|
options: FormatOptions(wrapConditions: .afterFirst),
|
|
exclude: [.wrapConditionalBodies]
|
|
)
|
|
}
|
|
|
|
func testWrapConditionsAfterFirstGuardElseOnOwnLine() {
|
|
let input = """
|
|
guard let something = complexCall(...),
|
|
isOnline,
|
|
shouldReallyRefresh
|
|
else { return }
|
|
"""
|
|
testFormatting(
|
|
for: input, rule: .wrapArguments,
|
|
options: FormatOptions(wrapConditions: .afterFirst),
|
|
exclude: [.wrapConditionalBodies]
|
|
)
|
|
}
|
|
|
|
func testWrapConditionsBeforeFirstGuardElseOnOwnLine() {
|
|
let input = """
|
|
guard
|
|
let something = complexCall(...),
|
|
isOnline,
|
|
shouldReallyRefresh
|
|
else { return }
|
|
"""
|
|
testFormatting(
|
|
for: input, rule: .wrapArguments,
|
|
options: FormatOptions(wrapConditions: .beforeFirst),
|
|
exclude: [.wrapConditionalBodies]
|
|
)
|
|
}
|
|
|
|
func testWrapConditionsAfterFirstGuardElseOnOwnLineIndented() {
|
|
let input = """
|
|
func foo() {
|
|
guard let something = complexCall(...),
|
|
isOnline,
|
|
shouldReallyRefresh
|
|
else { return }
|
|
}
|
|
"""
|
|
testFormatting(
|
|
for: input, rule: .wrapArguments,
|
|
options: FormatOptions(wrapConditions: .afterFirst),
|
|
exclude: [.wrapConditionalBodies]
|
|
)
|
|
}
|
|
|
|
func testWrapConditionsAfterFirstIfBraceOnOwnLine() {
|
|
let input = """
|
|
if let something = complexCall(...),
|
|
isOnline,
|
|
shouldReallyRefresh
|
|
{
|
|
print("True branch")
|
|
}
|
|
"""
|
|
testFormatting(
|
|
for: input, rule: .wrapArguments,
|
|
options: FormatOptions(wrapConditions: .afterFirst)
|
|
)
|
|
}
|
|
|
|
func testWrapConditionsBeforeFirstIfBraceOnOwnLine() {
|
|
let input = """
|
|
if
|
|
let something = complexCall(...),
|
|
isOnline,
|
|
shouldReallyRefresh
|
|
{
|
|
print("True branch")
|
|
}
|
|
"""
|
|
testFormatting(
|
|
for: input, rule: .wrapArguments,
|
|
options: FormatOptions(wrapConditions: .beforeFirst)
|
|
)
|
|
}
|
|
|
|
func testWrapPartiallyWrappedFunctionCall() {
|
|
let input = """
|
|
func foo(
|
|
bar: Bar, baaz: Baaz,
|
|
quux: Quux,
|
|
) {
|
|
print(
|
|
bar, baaz,
|
|
)
|
|
}
|
|
"""
|
|
|
|
let output = """
|
|
func foo(
|
|
bar: Bar,
|
|
baaz: Baaz,
|
|
quux: Quux,
|
|
) {
|
|
print(
|
|
bar,
|
|
baaz,
|
|
)
|
|
}
|
|
"""
|
|
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: FormatOptions(wrapArguments: .beforeFirst, allowPartialWrapping: false), exclude: [.unusedArguments, .trailingCommas])
|
|
}
|
|
|
|
func testWrapPartiallyWrappedFunctionCallTwoLines() {
|
|
let input = """
|
|
func foo(
|
|
foo: Foo, bar: Bar,
|
|
baaz: Baaz, quux: Quux
|
|
) {
|
|
print(
|
|
foo, bar,
|
|
baaz, quux
|
|
)
|
|
}
|
|
"""
|
|
|
|
let output = """
|
|
func foo(
|
|
foo: Foo,
|
|
bar: Bar,
|
|
baaz: Baaz,
|
|
quux: Quux
|
|
) {
|
|
print(
|
|
foo,
|
|
bar,
|
|
baaz,
|
|
quux
|
|
)
|
|
}
|
|
"""
|
|
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: FormatOptions(wrapArguments: .beforeFirst, allowPartialWrapping: false))
|
|
}
|
|
|
|
func testWrapPartiallyWrappedArray() {
|
|
let input = """
|
|
let foo = [
|
|
foo, bar,
|
|
baaz, quux,
|
|
]
|
|
"""
|
|
|
|
let output = """
|
|
let foo = [
|
|
foo,
|
|
bar,
|
|
baaz,
|
|
quux,
|
|
]
|
|
"""
|
|
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: FormatOptions(wrapArguments: .beforeFirst, allowPartialWrapping: false))
|
|
}
|
|
|
|
func testArrayWithBlankLine() {
|
|
let input = """
|
|
let foo = [
|
|
foo,
|
|
bar,
|
|
|
|
baaz,
|
|
quux,
|
|
]
|
|
"""
|
|
|
|
testFormatting(for: input, rule: .wrapArguments, options: FormatOptions(wrapArguments: .beforeFirst, allowPartialWrapping: false))
|
|
}
|
|
|
|
func testPartiallyWrappedArrayWithBlankLine() {
|
|
let input = """
|
|
let foo = [
|
|
foo, bar,
|
|
|
|
baaz, quux,
|
|
]
|
|
"""
|
|
|
|
let output = """
|
|
let foo = [
|
|
foo,
|
|
bar,
|
|
|
|
baaz,
|
|
quux,
|
|
]
|
|
"""
|
|
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: FormatOptions(wrapArguments: .beforeFirst, allowPartialWrapping: false))
|
|
}
|
|
|
|
func testWrapArgumentsBeforeFirstDoesntWrapClosingParenIfFirstArgumentNotWrapped() {
|
|
let input = """
|
|
return .tuple(string
|
|
.split { $0.isNewline }
|
|
.map { .string("\\($0)") })
|
|
"""
|
|
|
|
testFormatting(for: input, rule: .wrapArguments, options: FormatOptions(
|
|
wrapArguments: .beforeFirst, closingParenPosition: .balanced, maxWidth: 1000
|
|
))
|
|
}
|
|
|
|
func testNoWrapEmptyFuncParensBeforeFirst() {
|
|
let input = """
|
|
func aVeryLongFunctionNameThatExceedsTheMaxWidthLimit() {
|
|
foo()
|
|
}
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .beforeFirst, maxWidth: 40)
|
|
testFormatting(for: input, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testNoWrapEmptyInitParensBeforeFirst() {
|
|
let input = """
|
|
init() {
|
|
foo()
|
|
}
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .beforeFirst, maxWidth: 8)
|
|
testFormatting(for: input, rule: .wrapArguments, options: options,
|
|
exclude: [.wrap])
|
|
}
|
|
|
|
func testUnwrapAlreadyWrappedEmptyFuncParensBeforeFirst() {
|
|
let input = """
|
|
func aVeryLongFunctionNameThatExceedsTheMaxWidthLimit(
|
|
) {
|
|
foo()
|
|
}
|
|
"""
|
|
let output = """
|
|
func aVeryLongFunctionNameThatExceedsTheMaxWidthLimit() {
|
|
foo()
|
|
}
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .beforeFirst, maxWidth: 40)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testWrapThresholdWrapsWhenExpressionExceedsThreshold() {
|
|
let input = """
|
|
func foo(bar _: Int, baz _: String) {}
|
|
"""
|
|
let output = """
|
|
func foo(
|
|
bar _: Int,
|
|
baz _: String
|
|
) {}
|
|
"""
|
|
// Line is 38 chars — under maxWidth (100) but over listWrapThreshold (20)
|
|
let options = FormatOptions(wrapParameters: .beforeFirst, maxWidth: 100, listWrapThreshold: 20)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testWrapThresholdDoesNotWrapShortExpression() {
|
|
let input = """
|
|
let result = max(a, b)
|
|
"""
|
|
// Line is 22 chars — under listWrapThreshold (40)
|
|
let options = FormatOptions(wrapArguments: .beforeFirst, maxWidth: 100, listWrapThreshold: 40)
|
|
testFormatting(for: input, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testWrapThresholdZeroWrapsMultiArgumentCalls() {
|
|
let input = """
|
|
let x = foo(a, b)
|
|
"""
|
|
let output = """
|
|
let x = foo(
|
|
a,
|
|
b
|
|
)
|
|
"""
|
|
// listWrapThreshold 0 — wraps multi-argument calls regardless of length
|
|
let options = FormatOptions(wrapArguments: .beforeFirst, maxWidth: 200, listWrapThreshold: 0)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testWrapThresholdWrapsSingleArgumentCall() {
|
|
let input = """
|
|
let x = someVeryLongFunctionName(someVeryLongArgumentName: someVeryLongValue)
|
|
"""
|
|
let output = """
|
|
let x = someVeryLongFunctionName(
|
|
someVeryLongArgumentName: someVeryLongValue
|
|
)
|
|
"""
|
|
// Single-argument call — listWrapThreshold wraps it when line exceeds threshold
|
|
let options = FormatOptions(wrapArguments: .beforeFirst, maxWidth: 200, listWrapThreshold: 0)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testWrapThresholdDoesNotWrapZeroArgumentCall() {
|
|
let input = """
|
|
let x = someVeryLongFunctionName()
|
|
"""
|
|
// Zero-argument call — listWrapThreshold should never wrap it
|
|
let options = FormatOptions(wrapArguments: .beforeFirst, maxWidth: 200, listWrapThreshold: 0)
|
|
testFormatting(for: input, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testWrapThresholdDefaultPreservesExistingBehaviour() {
|
|
let input = """
|
|
func foo(bar _: Int, baz _: String) {}
|
|
"""
|
|
// listWrapThreshold defaults to -1 (none), so only maxWidth triggers wrapping.
|
|
// Line is 38 chars — under maxWidth 100, so nothing wraps.
|
|
let options = FormatOptions(wrapParameters: .beforeFirst, maxWidth: 100)
|
|
testFormatting(for: input, rule: .wrapArguments, options: options)
|
|
}
|
|
|
|
func testWrapThresholdDoesNotAffectPartiallyWrappedExpressions() {
|
|
// Expressions that are already partially wrapped should be handled by
|
|
// completePartialWrapping, not influenced by listWrapThreshold.
|
|
let input = """
|
|
func foo(bar _: Int,
|
|
baz _: String) {}
|
|
"""
|
|
let output = """
|
|
func foo(
|
|
bar _: Int,
|
|
baz _: String
|
|
) {}
|
|
"""
|
|
let options = FormatOptions(wrapParameters: .beforeFirst, maxWidth: 100, listWrapThreshold: 200)
|
|
testFormatting(for: input, output, rule: .wrapArguments, options: options)
|
|
}
|
|
}
|