diff --git a/CommandLineTool/main.swift b/CommandLineTool/main.swift index 4b2bae8f..607ab354 100644 --- a/CommandLineTool/main.swift +++ b/CommandLineTool/main.swift @@ -2,7 +2,7 @@ // main.swift // SwiftFormat // -// Version 0.7.1 +// Version 0.8 // // Created by Nick Lockwood on 12/08/2016. // Copyright 2016 Charcoal Design @@ -33,7 +33,7 @@ import Foundation -let version = "0.7.1" +let version = "0.8" func processInput(inputURL: NSURL, andWriteToOutput outputURL: NSURL, withOptions options: FormatOptions) -> Int { let manager = NSFileManager.defaultManager() @@ -89,6 +89,7 @@ func showHelp() { print(" -i, --indent number of spaces to indent, or \"tab\" to use tabs") print(" -l, --linebreaks linebreak character to use. \"cr\", \"crlf\" or \"lf\" (default)") print(" -s, --semicolons allow semicolons. values are \"never\" or \"inline\" (default)") + print(" -r, --ranges spacing for ranges. either \"spaced\" or \"nospace\" (default)") print(" -h, --help this help page") print(" -v, --version version information") print("") @@ -106,6 +107,7 @@ func processArguments(args: [String]) { "indent", "linebreaks", "semicolons", + "ranges", "help", "version", ]) else { @@ -149,6 +151,8 @@ func processArguments(args: [String]) { options.allowInlineSemicolons = true case "never": options.allowInlineSemicolons = false + case "": + print("error: --semicolons option expects a value.") default: print("error: unsupported semicolons value: \(semicolons).") return @@ -162,11 +166,26 @@ func processArguments(args: [String]) { options.linebreak = "\n" case "crlf": options.linebreak = "\r\n" + case "": + print("error: --linebreaks option expects a value.") default: print("error: unsupported linebreak value: \(linebreaks).") return } } + if let ranges = args["ranges"] { + switch ranges.lowercaseString { + case "space", "spaced", "spaces": + options.spaceAroundRangeOperators = true + case "nospace": + options.spaceAroundRangeOperators = false + case "": + print("error: --ranges option expects a value.") + default: + print("error: unsupported ranges value: \(ranges).") + return + } + } // If no input file, try stdin if inputURL == nil { diff --git a/CommandLineTool/swiftformat b/CommandLineTool/swiftformat index e40fad67..3c468bc1 100755 Binary files a/CommandLineTool/swiftformat and b/CommandLineTool/swiftformat differ diff --git a/README.md b/README.md index 4ebccc56..a8d67298 100644 --- a/README.md +++ b/README.md @@ -113,7 +113,7 @@ Here are all the rules that SwiftFormat currently applies: *spaceAroundGenerics* - removes the space around < >. For example: - Foo () --> Foo() + Foo () --> Foo() *spaceInsideGenerics* - removes the space inside < >. For example: @@ -125,6 +125,18 @@ Here are all the rules that SwiftFormat currently applies: a+b+c --> a + b + c +*spaceAroundComments* - adds space around /* ... */ comments and before // comments: + + let a = 5// assignment --> let a = 5 // assignment + + func foo() {/* no-op */} --> func foo() { /* no-op */ } + +*spaceInsideComments* - adds space inside /* ... */ comments and at the start of // comments: + + let a = 5 //assignment --> let a = 5 // assignment + + func foo() { /*no-op*/ } --> func foo() { /* no-op */ } + *consecutiveSpaces* - reduces a sequence of spaces to a single space: let foo = 5 --> let foo = 5 @@ -341,6 +353,10 @@ Release notes Version 0.8 +- Added new `ranges` rules that adds/removes space around range operators (e.g. `0 ..< count`) depending on command-line options +- Added a new `--ranges` command-line option, which can be used to restore the previous spacing for range operators +- Added new `spaceAroundComments` rule, which adds a space around /* ... */ comments and before // comments +- Added new `spaceInsideComments` rule, which adds a space inside /* ... */ comments and at the start of // comments - Added new `blankLinesAtEndOfScope` rule, which removes blank lines at the end of braces, brackets and parens - Removed double blank line at end of file diff --git a/SwiftFormat.xcodeproj/project.pbxproj b/SwiftFormat.xcodeproj/project.pbxproj index afbbe685..3e5a98d5 100644 --- a/SwiftFormat.xcodeproj/project.pbxproj +++ b/SwiftFormat.xcodeproj/project.pbxproj @@ -116,8 +116,8 @@ children = ( 0142F06E1D72FE10007D66CC /* SwiftFormatTests.swift */, 018E82741D62E730008CA0F8 /* TokenizerTests.swift */, - 01A0EAB31D5DB4D000A0A8E3 /* RulesTests.swift */, 01B3987A1D763424009ADE61 /* FormatterTests.swift */, + 01A0EAB31D5DB4D000A0A8E3 /* RulesTests.swift */, 01A0EAB51D5DB4D000A0A8E3 /* Info.plist */, ); path = SwiftFormatTests; @@ -271,7 +271,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "CommandLineTool/swiftformat ."; + shellScript = "CommandLineTool/swiftformat . -r spaced"; }; 017AEBB11D6F256300764325 /* Format Code */ = { isa = PBXShellScriptBuildPhase; diff --git a/SwiftFormat/Formatter.swift b/SwiftFormat/Formatter.swift index 240a7b14..c5a049ab 100644 --- a/SwiftFormat/Formatter.swift +++ b/SwiftFormat/Formatter.swift @@ -2,7 +2,7 @@ // Formatter.swift // SwiftFormat // -// Version 0.7.1 +// Version 0.8 // // Created by Nick Lockwood on 12/08/2016. // Copyright 2016 Charcoal Design @@ -39,14 +39,17 @@ public struct FormatOptions { public var indent: String public var linebreak: String public var allowInlineSemicolons: Bool + public var spaceAroundRangeOperators: Bool public init(indent: String = " ", linebreak: String = "\n", - allowInlineSemicolons: Bool = true) { + allowInlineSemicolons: Bool = true, + spaceAroundRangeOperators: Bool = false) { self.indent = indent self.linebreak = linebreak self.allowInlineSemicolons = allowInlineSemicolons + self.spaceAroundRangeOperators = spaceAroundRangeOperators } } diff --git a/SwiftFormat/Rules.swift b/SwiftFormat/Rules.swift index 351d1422..aad5b1f0 100644 --- a/SwiftFormat/Rules.swift +++ b/SwiftFormat/Rules.swift @@ -2,7 +2,7 @@ // Rules.swift // SwiftFormat // -// Version 0.7.1 +// Version 0.8 // // Created by Nick Lockwood on 12/08/2016. // Copyright 2016 Charcoal Design @@ -390,11 +390,13 @@ public func spaceAroundOperators(formatter: Formatter) { formatter.insertToken(Token(.Whitespace, " "), atIndex: i) } } - } else if let previousToken = formatter.tokenAtIndex(i - 1) where isLvalue(previousToken) { - if let nextToken = formatter.tokenAtIndex(i + 1) where isRvalue(nextToken) { - // Insert space before and after the infix token - formatter.insertToken(Token(.Whitespace, " "), atIndex: i + 1) - formatter.insertToken(Token(.Whitespace, " "), atIndex: i) + } else if token.string != "..." && token.string != "..<" { + if let previousToken = formatter.tokenAtIndex(i - 1) where isLvalue(previousToken) { + if let nextToken = formatter.tokenAtIndex(i + 1) where isRvalue(nextToken) { + // Insert space before and after the infix token + formatter.insertToken(Token(.Whitespace, " "), atIndex: i + 1) + formatter.insertToken(Token(.Whitespace, " "), atIndex: i) + } } } case .StartOfScope: @@ -406,6 +408,96 @@ public func spaceAroundOperators(formatter: Formatter) { } } +/// Add space around comments +public func spaceAroundComments(formatter: Formatter) { + formatter.forEachToken(ofType: .StartOfScope) { i, token in + guard let previousToken = formatter.tokenAtIndex(i - 1) where + (token.string == "/*" || token.string == "//") else { return } + if !previousToken.isWhitespaceOrLinebreak { + formatter.insertToken(Token(.Whitespace, " "), atIndex: i) + } + } + formatter.forEachToken("*/") { i, token in + guard let nextToken = formatter.tokenAtIndex(i + 1) else { return } + if !nextToken.isWhitespaceOrLinebreak { + formatter.insertToken(Token(.Whitespace, " "), atIndex: i + 1) + } + } +} + +/// Add space inside comments, taking care not to mangle headerdoc or +/// carefully preformatted comments, such as star boxes, etc. +public func spaceInsideComments(formatter: Formatter) { + formatter.forEachToken("/*") { i, token in + guard let nextToken = formatter.tokenAtIndex(i + 1) else { return } + if !nextToken.isWhitespaceOrLinebreak { + let string = nextToken.string + if string.hasPrefix("*") { + if !string.hasPrefix("**") && !string.hasPrefix("*/") { + let string = "* " + string.substringFromIndex(string.startIndex.advancedBy(1)) + formatter.replaceTokenAtIndex(i + 1, with: Token(.CommentBody, string)) + } + } else { + formatter.insertToken(Token(.Whitespace, " "), atIndex: i + 1) + } + } + } + formatter.forEachToken("//") { i, token in + guard let nextToken = formatter.tokenAtIndex(i + 1) else { return } + if !nextToken.isWhitespaceOrLinebreak { + let string = nextToken.string + if string.hasPrefix("/") { + let string = "/ " + string.substringFromIndex(string.startIndex.advancedBy(1)) + formatter.replaceTokenAtIndex(i + 1, with: Token(.CommentBody, string)) + } else { + formatter.insertToken(Token(.Whitespace, " "), atIndex: i + 1) + } + } + } + formatter.forEachToken("*/") { i, token in + guard let previousToken = formatter.tokenAtIndex(i - 1) else { return } + if !previousToken.isWhitespaceOrLinebreak && !previousToken.string.hasSuffix("*") { + formatter.insertToken(Token(.Whitespace, " "), atIndex: i) + } + } +} + +/// Add or removes the space around range operators +public func ranges(formatter: Formatter) { + func nextNonWhitespaceToken(fromIndex index: Int) -> Token? { + var index = index + 1 + while let token = formatter.tokenAtIndex(index) { + if !token.isWhitespaceOrCommentOrLinebreak { + return token + } + index += 1 + } + return nil + } + + formatter.forEachToken(ofType: .Operator) { i, token in + if token.string == "..." || token.string == "..<" { + if !formatter.options.spaceAroundRangeOperators { + if formatter.tokenAtIndex(i + 1)?.type == .Whitespace { + formatter.removeTokenAtIndex(i + 1) + } + if formatter.tokenAtIndex(i - 1)?.type == .Whitespace { + formatter.removeTokenAtIndex(i - 1) + } + } else if let nextToken = nextNonWhitespaceToken(fromIndex: i) { + if nextToken.string != ")" && nextToken.string != "," { + if formatter.tokenAtIndex(i + 1)?.isWhitespaceOrLinebreak == false { + formatter.insertToken(Token(.Whitespace, " "), atIndex: i + 1) + } + if formatter.tokenAtIndex(i - 1)?.isWhitespaceOrLinebreak == false { + formatter.insertToken(Token(.Whitespace, " "), atIndex: i) + } + } + } + } + } +} + /// Collapse all consecutive whitespace characters to a single space, except at /// the start of a line or inside a comment or string, as these have no semantic /// meaning and lead to noise in commits. @@ -1063,6 +1155,8 @@ public let defaultRules: [FormatRule] = [ spaceAroundGenerics, spaceInsideGenerics, spaceAroundOperators, + spaceAroundComments, + spaceInsideComments, consecutiveSpaces, trailingWhitespace, consecutiveBlankLines, @@ -1070,4 +1164,5 @@ public let defaultRules: [FormatRule] = [ linebreakAtEndOfFile, trailingCommas, todos, + ranges, ] diff --git a/SwiftFormat/SwiftFormat.h b/SwiftFormat/SwiftFormat.h index aeadbacf..47805f16 100644 --- a/SwiftFormat/SwiftFormat.h +++ b/SwiftFormat/SwiftFormat.h @@ -2,7 +2,7 @@ // SwiftFormat.h // SwiftFormat // -// Version 0.7.1 +// Version 0.8 // // Created by Nick Lockwood on 12/08/2016. // Copyright 2016 Charcoal Design diff --git a/SwiftFormat/SwiftFormat.swift b/SwiftFormat/SwiftFormat.swift index 42cc7fd9..24d03904 100644 --- a/SwiftFormat/SwiftFormat.swift +++ b/SwiftFormat/SwiftFormat.swift @@ -2,7 +2,7 @@ // SwiftFormat.swift // SwiftFormat // -// Version 0.7.1 +// Version 0.8 // // Created by Nick Lockwood on 12/08/2016. // Copyright 2016 Charcoal Design diff --git a/SwiftFormat/Tokenizer.swift b/SwiftFormat/Tokenizer.swift index 3448ac16..cce79120 100644 --- a/SwiftFormat/Tokenizer.swift +++ b/SwiftFormat/Tokenizer.swift @@ -2,7 +2,7 @@ // Tokenizer.swift // SwiftFormat // -// Version 0.7.1 +// Version 0.8 // // Created by Nick Lockwood on 11/08/2016. // Copyright 2016 Charcoal Design @@ -63,12 +63,16 @@ public struct Token: Equatable { case .StartOfScope: return string == "//" || string == "/*" case .EndOfScope: - return string == "//" + return string == "*/" default: return false } } + public var isWhitespaceOrLinebreak: Bool { + return type == .Linebreak || type == .Whitespace + } + public var isWhitespaceOrCommentOrLinebreak: Bool { return type == .Linebreak || isWhitespaceOrComment } diff --git a/SwiftFormatTests/FormatterTests.swift b/SwiftFormatTests/FormatterTests.swift index 06c82e9e..21afd415 100644 --- a/SwiftFormatTests/FormatterTests.swift +++ b/SwiftFormatTests/FormatterTests.swift @@ -2,7 +2,7 @@ // FormatterTests.swift // SwiftFormat // -// Version 0.7.1 +// Version 0.8 // // Created by Nick Lockwood on 30/08/2016. // Copyright 2016 Charcoal Design diff --git a/SwiftFormatTests/RulesTests.swift b/SwiftFormatTests/RulesTests.swift index 5046ca96..32610d00 100644 --- a/SwiftFormatTests/RulesTests.swift +++ b/SwiftFormatTests/RulesTests.swift @@ -2,7 +2,7 @@ // RulesTests.swift // SwiftFormat // -// Version 0.7.1 +// Version 0.8 // // Created by Nick Lockwood on 12/08/2016. // Copyright 2016 Charcoal Design @@ -583,7 +583,12 @@ class RulesTests: XCTestCase { let input = "foo/* hello */-bar" let output = "foo/* hello */ - bar" XCTAssertEqual(format(input, rules: [spaceAroundOperators]), output) - XCTAssertEqual(format(input + "\n", rules: defaultRules), output + "\n") + } + + func testSpaceAroundCommentsInInfixExpression() { + let input = "a/* */+/* */b" + let output = "a/* */ + /* */b" + XCTAssertEqual(format(input, rules: [spaceAroundOperators]), output) } func testSpaceAroundCommentInPrefixExpression() { @@ -593,10 +598,77 @@ class RulesTests: XCTestCase { XCTAssertEqual(format(input + "\n", rules: defaultRules), output + "\n") } - func testSpaceAroundCommentsInInfixExpression() { - let input = "a/* */+/* */b" - let output = "a/* */ + /* */b" - XCTAssertEqual(format(input, rules: [spaceAroundOperators]), output) + // MARK: spaceAroundComments + + func testSpaceAroundCommentInParens() { + let input = "(/* foo */)" + let output = "( /* foo */ )" + XCTAssertEqual(format(input, rules: [spaceAroundComments]), output) + XCTAssertEqual(format(input + "\n", rules: defaultRules), output + "\n") + } + + func testNoSpaceAroundCommentAtStartAndEndOfFile() { + let input = "/* foo */" + let output = "/* foo */" + XCTAssertEqual(format(input, rules: [spaceAroundComments]), output) + XCTAssertEqual(format(input + "\n", rules: defaultRules), output + "\n") + } + + func testSpaceAroundSingleLineComment() { + let input = "func() {// comment\n}" + let output = "func() { // comment\n}" + XCTAssertEqual(format(input, rules: [spaceAroundComments]), output) + XCTAssertEqual(format(input + "\n", rules: defaultRules), output + "\n") + } + + // MARK: spaceInsideComments + + func testSpaceInsideMultilineComment() { + let input = "/*foo\n bar*/" + let output = "/* foo\n bar */" + XCTAssertEqual(format(input, rules: [spaceInsideComments]), output) + XCTAssertEqual(format(input + "\n", rules: defaultRules), output + "\n") + } + + func testSpaceInsideSingleLineMultilineComment() { + let input = "/*foo*/" + let output = "/* foo */" + XCTAssertEqual(format(input, rules: [spaceInsideComments]), output) + XCTAssertEqual(format(input + "\n", rules: defaultRules), output + "\n") + } + + func testNoSpaceInsideEmptyMultilineComment() { + let input = "/**/" + let output = "/**/" + XCTAssertEqual(format(input, rules: [spaceInsideComments]), output) + XCTAssertEqual(format(input + "\n", rules: defaultRules), output + "\n") + } + + func testSpaceInsideSingleLineComment() { + let input = "//foo" + let output = "// foo" + XCTAssertEqual(format(input, rules: [spaceInsideComments]), output) + XCTAssertEqual(format(input + "\n", rules: defaultRules), output + "\n") + } + + func testSpaceInsideMultilineHeaderdocComment() { + let input = "/**foo\n bar*/" + let output = "/** foo\n bar */" + XCTAssertEqual(format(input, rules: [spaceInsideComments]), output) + XCTAssertEqual(format(input + "\n", rules: defaultRules), output + "\n") + } + + func testSpaceInsideSingleLineHeaderdocComment() { + let input = "///foo" + let output = "/// foo" + XCTAssertEqual(format(input, rules: [spaceInsideComments]), output) + XCTAssertEqual(format(input + "\n", rules: defaultRules), output + "\n") + } + + func testPreformattedMultilineComment() { + let input = "/*********************\n *****Hello World*****\n *********************/" + let output = "/*********************\n *****Hello World*****\n *********************/" + XCTAssertEqual(format(input, rules: [spaceInsideComments]), output) XCTAssertEqual(format(input + "\n", rules: defaultRules), output + "\n") } @@ -654,15 +726,15 @@ class RulesTests: XCTestCase { } func testtrailingWhitespaceInMultilineComments() { - let input = "/*foo \n bar */" - let output = "/*foo\n bar */" + let input = "/* foo \n bar */" + let output = "/* foo\n bar */" XCTAssertEqual(format(input, rules: [trailingWhitespace]), output) XCTAssertEqual(format(input + "\n", rules: defaultRules), output + "\n") } func testtrailingWhitespaceInSingleLineComments() { - let input = "//foo \n//bar " - let output = "//foo\n//bar" + let input = "// foo \n// bar " + let output = "// foo\n// bar" XCTAssertEqual(format(input, rules: [trailingWhitespace]), output) XCTAssertEqual(format(input + "\n", rules: defaultRules), output + "\n") } @@ -693,8 +765,8 @@ class RulesTests: XCTestCase { // MARK: blankLinesAtEndOfScope func testBlankLinesRemovedAtEndOfFunction() { - let input = "func() {\n //code\n\n}" - let output = "func() {\n //code\n}" + let input = "func() {\n // code\n\n}" + let output = "func() {\n // code\n}" XCTAssertEqual(format(input, rules: [blankLinesAtEndOfScope]), output) XCTAssertEqual(format(input + "\n", rules: defaultRules), output + "\n") } @@ -776,22 +848,22 @@ class RulesTests: XCTestCase { } func testNoIndentBlankLines() { - let input = "{\n\n//foo\n}" - let output = "{\n\n //foo\n}" + let input = "{\n\n// foo\n}" + let output = "{\n\n // foo\n}" XCTAssertEqual(format(input, rules: [indent]), output) XCTAssertEqual(format(input + "\n", rules: defaultRules), output + "\n") } func testNestedBraces() { - let input = "({\n//foo\n}, {\n//bar\n})" - let output = "({\n //foo\n}, {\n //bar\n})" + let input = "({\n// foo\n}, {\n// bar\n})" + let output = "({\n // foo\n}, {\n // bar\n})" XCTAssertEqual(format(input, rules: [indent]), output) XCTAssertEqual(format(input + "\n", rules: defaultRules), output + "\n") } func testBraceIndentAfterComment() { - let input = "if foo { //comment\nbar\n}" - let output = "if foo { //comment\n bar\n}" + let input = "if foo { // comment\nbar\n}" + let output = "if foo { // comment\n bar\n}" XCTAssertEqual(format(input, rules: [indent]), output) XCTAssertEqual(format(input + "\n", rules: defaultRules), output + "\n") } @@ -927,8 +999,8 @@ class RulesTests: XCTestCase { } func testWrappedLineAfterForKeyword() { - let input = "for\ni in 0 ..< 5 {}" - let output = "for\n i in 0 ..< 5 {}" + let input = "for\ni in range {}" + let output = "for\n i in range {}" XCTAssertEqual(format(input, rules: [indent]), output) XCTAssertEqual(format(input + "\n", rules: defaultRules), output + "\n") } @@ -983,15 +1055,15 @@ class RulesTests: XCTestCase { } func testIndentElseAfterComment() { - let input = "if x {}\n//comment\nelse {}" - let output = "if x {}\n//comment\nelse {}" + let input = "if x {}\n// comment\nelse {}" + let output = "if x {}\n// comment\nelse {}" XCTAssertEqual(format(input, rules: [indent]), output) XCTAssertEqual(format(input + "\n", rules: defaultRules), output + "\n") } func testWrappedLinesWithComments() { - let input = "let foo = bar ||\n//baz||\nquux" - let output = "let foo = bar ||\n //baz||\n quux" + let input = "let foo = bar ||\n // baz||\nquux" + let output = "let foo = bar ||\n // baz||\n quux" XCTAssertEqual(format(input, rules: [indent]), output) XCTAssertEqual(format(input + "\n", rules: defaultRules), output + "\n") } @@ -1013,8 +1085,8 @@ class RulesTests: XCTestCase { } func testNestedCommentIndenting() { - let input = "/*foo\n/*\nbar\n*/\n*/" - let output = "/*foo\n /*\n bar\n */\n */" + let input = "/* foo\n/*\nbar\n*/\n*/" + let output = "/* foo\n /*\n bar\n */\n */" XCTAssertEqual(format(input, rules: [indent]), output) XCTAssertEqual(format(input + "\n", rules: defaultRules), output + "\n") } @@ -1022,22 +1094,22 @@ class RulesTests: XCTestCase { // MARK: indent #if/#else/#elseif/#endif func testIfEndifIndenting() { - let input = "#if x\n//foo\n#endif" - let output = "#if x\n //foo\n#endif" + let input = "#if x\n// foo\n#endif" + let output = "#if x\n // foo\n#endif" XCTAssertEqual(format(input, rules: [indent]), output) XCTAssertEqual(format(input + "\n", rules: defaultRules), output + "\n") } func testIfElseEndifIndenting() { - let input = "#if x\n//foo\n#else\n//bar\n#endif" - let output = "#if x\n //foo\n#else\n //bar\n#endif" + let input = "#if x\n// foo\n#else\n// bar\n#endif" + let output = "#if x\n // foo\n#else\n // bar\n#endif" XCTAssertEqual(format(input, rules: [indent]), output) XCTAssertEqual(format(input + "\n", rules: defaultRules), output + "\n") } func testIfElseifEndifIndenting() { - let input = "#if x\n//foo\n#elseif y\n//bar\n#endif" - let output = "#if x\n //foo\n#elseif y\n //bar\n#endif" + let input = "#if x\n// foo\n#elseif y\n// bar\n#endif" + let output = "#if x\n // foo\n#elseif y\n // bar\n#endif" XCTAssertEqual(format(input, rules: [indent]), output) XCTAssertEqual(format(input + "\n", rules: defaultRules), output + "\n") } @@ -1052,8 +1124,8 @@ class RulesTests: XCTestCase { } func testBracesAfterComment() { - let input = "func foo() //comment\n{\n statement\n}" - let output = "func foo() { //comment\n statement\n}" + let input = "func foo() // comment\n{\n statement\n}" + let output = "func foo() { // comment\n statement\n}" XCTAssertEqual(format(input, rules: [knrBraces]), output) XCTAssertEqual(format(input + "\n", rules: defaultRules), output + "\n") } @@ -1142,8 +1214,8 @@ class RulesTests: XCTestCase { // MARK: todos func testMarkIsUpdated() { - let input = "//MARK foo" - let output = "//MARK: foo" + let input = "// MARK foo" + let output = "// MARK: foo" XCTAssertEqual(format(input, rules: [todos]), output) XCTAssertEqual(format(input + "\n", rules: defaultRules), output + "\n") } @@ -1163,23 +1235,23 @@ class RulesTests: XCTestCase { } func testMarkWithColonSeparatedBySpace() { - let input = "//MARK : foo" - let output = "//MARK: foo" + let input = "// MARK : foo" + let output = "// MARK: foo" XCTAssertEqual(format(input, rules: [todos]), output) XCTAssertEqual(format(input + "\n", rules: defaultRules), output + "\n") } func testMarkWithNoSpaceAfterColon() { // NOTE: this was an unintended side-effect, but I like it - let input = "//MARK:foo" - let output = "//MARK: foo" + let input = "// MARK:foo" + let output = "// MARK: foo" XCTAssertEqual(format(input, rules: [todos]), output) XCTAssertEqual(format(input + "\n", rules: defaultRules), output + "\n") } func testCorrectMarkIsIgnored() { - let input = "//MARK: foo" - let output = "//MARK: foo" + let input = "// MARK: foo" + let output = "// MARK: foo" XCTAssertEqual(format(input, rules: [todos]), output) XCTAssertEqual(format(input + "\n", rules: defaultRules), output + "\n") } @@ -1238,8 +1310,8 @@ class RulesTests: XCTestCase { } func testReplaceSemicolonFollowedByComment() { - let input = "print(\"hello\"); //comment\nprint(\"goodbye\")" - let output = "print(\"hello\") //comment\nprint(\"goodbye\")" + let input = "print(\"hello\"); // comment\nprint(\"goodbye\")" + let output = "print(\"hello\") // comment\nprint(\"goodbye\")" let options = FormatOptions(allowInlineSemicolons: true) XCTAssertEqual(format(input, rules: [semicolons], options: options), output) XCTAssertEqual(format(input + "\n", rules: defaultRules, options: options), output + "\n") @@ -1265,4 +1337,52 @@ class RulesTests: XCTestCase { XCTAssertEqual(format(input, rules: [semicolons]), output) XCTAssertEqual(format(input + "\n", rules: defaultRules), output + "\n") } + + // MARK: ranges + + func testSpaceAroundRangeOperatorsWithDefaultOptions() { + let input = "foo ..< bar" + let output = "foo..