Reverted 0.6 release

This commit is contained in:
Nick Lockwood
2016-08-26 21:11:37 +01:00
parent 1f01f47ea4
commit eebffd6025
10 changed files with 250 additions and 397 deletions
+2 -2
View File
@@ -2,7 +2,7 @@
// SwiftFormat
// main.swift
//
// Version 0.6
// Version 0.5.1
//
// Created by Nick Lockwood on 12/08/2016.
// Copyright 2016 Charcoal Design
@@ -33,7 +33,7 @@
import Foundation
let version = "0.6"
let version = "0.5.1"
func processInput(inputURL: NSURL, andWriteToOutput outputURL: NSURL, withOptions options: FormattingOptions) -> Int {
let manager = NSFileManager.defaultManager()
Binary file not shown.
+1 -1
View File
@@ -1,6 +1,6 @@
SwiftFormat
Version 0.6, August 26th, 2016
Version 0.5.1, August 25th, 2016
Copyright (c) 2016 Nick Lockwood
-7
View File
@@ -192,8 +192,6 @@ Here are all the rules that SwiftFormat currently applies:
return; --> return;
goto(fail) goto(fail)
*linebreaks* - normalizes all linebreaks to use the same character, as specified in options (either CR, LF or CRLF).
FAQ
-----
@@ -324,11 +322,6 @@ With a syntax tree in place, it should become possible to add much more sophisti
Release notes
----------------
Version 0.6
- Refactored how switch/case is handled, and fixed a bunch of bugs
- Better indenting logic, now handles multiple closure arguments in a single function call
Version 0.5.1
- Fixed critical bug where double unwrap (e.g. `foo??.bar()`) was not handled correctly
+162 -144
View File
@@ -2,7 +2,7 @@
// SwiftFormat
// Formatter.swift
//
// Version 0.6
// Version 0.5.1
//
// Created by Nick Lockwood on 12/08/2016.
// Copyright 2016 Charcoal Design
@@ -67,8 +67,6 @@ public class Formatter {
self.options = options
}
// MARK: access and mutation
/// Returns the token at the specified index, or nil if index is invalid
public func tokenAtIndex(index: Int) -> Token? {
guard index >= 0 && index < tokens.count else { return nil }
@@ -134,8 +132,6 @@ public class Formatter {
}
}
// MARK: enumeration
/// Loops through each token in the array. It is safe to mutate the token
/// array inside the body block, but note that the index and token arguments
/// may not reflect the current token any more after a mutation
@@ -150,33 +146,34 @@ public class Formatter {
indexStack.popLast()
}
/// As above, but only loops through tokens that match the specified filter block
public func forEachToken(matching: (Token) -> Bool, _ body: (Int, Token) -> Void) {
forEachToken { index, token in
if matching(token) {
body(index, token)
}
}
}
/// As above, but only loops through tokens with the specified type
public func forEachToken(ofType type: TokenType, _ body: (Int, Token) -> Void) {
forEachToken({ $0.type == type }, body)
forEachToken(matching: { $0.type == type }, body)
}
/// As above, but only loops through tokens with the specified type and string
public func forEachToken(string: String, ofType type: TokenType, _ body: (Int, Token) -> Void) {
forEachToken({ return $0.type == type && $0.string == string }, body)
forEachToken(matching: {
return $0.type == type && $0.string == string
}, body)
}
/// As above, but only loops through tokens with the specified string.
/// Tokens of type `StringBody` and `CommentBody` are ignored, as these
/// can't be usefully identified by their string value
public func forEachToken(string: String, _ body: (Int, Token) -> Void) {
forEachToken({
forEachToken(matching: {
return $0.string == string && $0.type != .StringBody && $0.type != .CommentBody
}, body)
}
private func forEachToken(matching condition: (Token) -> Bool, _ body: (Int, Token) -> Void) {
forEachToken { index, token in
if condition(token) {
body(index, token)
}
}
}
}
public typealias FormatRule = (Formatter) -> Void
@@ -193,22 +190,22 @@ public func spaceAroundParens(formatter: Formatter) {
func spaceAfter(identifier: String) -> Bool {
switch identifier {
case "internal",
"case",
"for",
"guard",
"if",
"in",
"return",
"switch",
"where",
"while",
"as",
"catch",
"is",
"rethrows",
"throw",
"throws",
"try":
"case",
"for",
"guard",
"if",
"in",
"return",
"switch",
"where",
"while",
"as",
"catch",
"is",
"rethrows",
"throw",
"throws",
"try":
return true
default:
return false
@@ -268,15 +265,15 @@ public func spaceAroundBrackets(formatter: Formatter) {
func spaceAfter(identifier: String) -> Bool {
switch identifier {
case "case",
"guard",
"if",
"in",
"return",
"switch",
"where",
"while",
"as",
"is":
"guard",
"if",
"in",
"return",
"switch",
"where",
"while",
"as",
"is":
return true
default:
return false
@@ -432,16 +429,16 @@ public func spaceAroundOperators(formatter: Formatter) {
func spaceAfter(identifier: String) -> Bool {
switch identifier {
case "case",
"guard",
"if",
"in",
"let",
"return",
"switch",
"where",
"while",
"as",
"is":
"guard",
"if",
"in",
"let",
"return",
"switch",
"where",
"while",
"as",
"is":
return true
default:
return false
@@ -507,7 +504,8 @@ public func spaceAroundOperators(formatter: Formatter) {
(previousNonWhitespaceToken.string != "?" &&
formatter.tokenAtIndex(previousNonWhitespaceTokenIndex - 1)?.type != .Whitespace &&
isUnwrapOperatorSequence(previousNonWhitespaceToken))) &&
!spaceAfter(previousNonWhitespaceToken.string) {
(previousNonWhitespaceToken.type != .Identifier ||
!spaceAfter(previousNonWhitespaceToken.string)) {
if previousTokenWasWhitespace {
formatter.removeTokenAtIndex(i - 1)
}
@@ -567,13 +565,9 @@ public func noConsecutiveSpaces(formatter: Formatter) {
formatter.forEachToken(ofType: .Whitespace) { i, token in
if let previousToken = formatter.tokenAtIndex(i - 1) where previousToken.type != .Linebreak {
if token.string == "" {
formatter.removeTokenAtIndex(i)
} else if token.string != " " {
let scope = currentScopeAtIndex(i)
if scope?.string != "/*" && scope?.string != "//" {
formatter.replaceTokenAtIndex(i, with: Token(.Whitespace, " "))
}
let scope = currentScopeAtIndex(i)
if scope?.string != "/*" && scope?.string != "//" {
formatter.replaceTokenAtIndex(i, with: Token(.Whitespace, " "))
}
}
}
@@ -654,13 +648,15 @@ public func indent(formatter: Formatter) {
return nil
}
func setIndent(indent: String, atIndex index: Int) -> Bool {
func setIndent(indent: String, atIndex index: Int) {
if formatter.tokenAtIndex(index)?.type == .Whitespace {
formatter.replaceTokenAtIndex(index, with: Token(.Whitespace, indent))
return false
} else {
if indent != "" {
formatter.replaceTokenAtIndex(index, with: Token(.Whitespace, indent))
} else {
formatter.removeTokenAtIndex(index)
}
} else if indent != "" {
formatter.insertToken(Token(.Whitespace, indent), atIndex: index)
return true
}
}
@@ -682,50 +678,50 @@ public func indent(formatter: Formatter) {
func tokenIsEndOfStatement(i: Int) -> Bool {
if let token = formatter.tokenAtIndex(i) {
switch token.type {
case .Identifier, .EndOfScope:
case .Identifier:
// TODO: handle context-specific keywords
// in, associativity, convenience, dynamic, didSet, final, get, infix, indirect,
// lazy, left, mutating, none, nonmutating, optional, override, postfix, precedence,
// prefix, Protocol, required, right, set, Type, unowned, weak, willSet
switch token.string {
case "associatedtype",
"class",
"deinit",
"enum",
"extension",
"fileprivate",
"func",
"import",
"init",
"inout",
"internal",
"let",
"open",
"operator",
"private",
"protocol",
"public",
"static",
"struct",
"subscript",
"typealias",
"var",
"case",
"default",
"defer",
"else",
"for",
"guard",
"if",
"switch",
"where",
"while",
"as",
"catch",
"is",
"super",
"throw",
"try":
"class",
"deinit",
"enum",
"extension",
"fileprivate",
"func",
"import",
"init",
"inout",
"internal",
"let",
"open",
"operator",
"private",
"protocol",
"public",
"static",
"struct",
"subscript",
"typealias",
"var",
"case",
"default",
"defer",
"else",
"for",
"guard",
"if",
"switch",
"where",
"while",
"as",
"catch",
"is",
"super",
"throw",
"try":
return false
default:
return true
@@ -756,13 +752,13 @@ public func indent(formatter: Formatter) {
// TODO: handle "in"
switch token.string {
case "as",
"dynamicType",
"false",
"is",
"nil",
"rethrows",
"throws",
"true":
"dynamicType",
"false",
"is",
"nil",
"rethrows",
"throws",
"true":
return false
case "else":
if let token = formatter.tokenAtIndex(lastNonWhitespaceOrLinebreakIndex) {
@@ -790,71 +786,96 @@ public func indent(formatter: Formatter) {
return true
}
setIndent("", atIndex: 0)
formatter.forEachToken { i, token in
var i = i
if token.type == .StartOfScope {
// Handle start of scope
scopeIndexStack.append(i)
var indent = indentStack.last ?? ""
switch token.string {
case "/*":
// Comments only indent one space
indent += " "
case "//", "\"":
// No need to indent
break
default:
if lineIndex > scopeStartLineIndexes.last ?? -1 {
indent += formatter.options.indent
if lineIndex > scopeStartLineIndexes.last ?? -1 {
if token.string == "/*" {
// Comments only indent one space
indent += " "
} else {
indentStack.popLast()
indentStack.append(indentStack.last ?? "")
indent += formatter.options.indent
}
}
indentStack.append(indent)
scopeStartLineIndexes.append(lineIndex)
} else if token.type != .Whitespace {
} else {
if let scopeIndex = scopeIndexStack.last, scope = formatter.tokenAtIndex(scopeIndex) {
// Handle end of scope
if token.closesScopeForToken(scope) {
scopeStartLineIndexes.popLast()
scopeIndexStack.popLast()
indentStack.popLast()
if lineIndex > scopeStartLineIndexes.last ?? -1 { // What is this?
if lineIndex > scopeStartLineIndexes.last ?? -1 {
let start = startOfLine(atIndex: i)
if let nextToken = nextNonWhitespaceToken(fromIndex: start) where
nextToken.type == .EndOfScope && nextToken.string != "*/" {
// Only reduce indent if line begins with a closing scope token
let indent = indentStack.last ?? ""
if setIndent(indent, atIndex: start) {
i += 1
}
setIndent(indent, atIndex: start)
}
}
} else if token.type == .Identifier {
// Handle #elseif/#else
if token.string == "#else" || token.string == "#elseif" {
let indent = indentStack[indentStack.count - 2]
if setIndent(indent, atIndex: startOfLine(atIndex: i)) {
i += 1
setIndent(indent, atIndex: startOfLine(atIndex: i))
}
// Handle switch/case
else if token.string == "case" || token.string == "default" {
if formatter.tokenAtIndex(lastNonWhitespaceIndex)?.string == "if" {
// it was an if case statement
} else if scope.string == "{" {
// walk backwards to see if this is an switch or enum
var isSwitch = true
var subscopeStack: [Token] = []
var j = scopeIndex - 1
loop: while let token = formatter.tokenAtIndex(j) {
switch token.type {
case .Identifier:
if subscopeStack.count == 0 {
if token.string == "switch" {
break loop
}
if token.string == "enum" {
isSwitch = false
break loop
}
}
case .EndOfScope:
subscopeStack.append(token)
case .StartOfScope:
if subscopeStack.count == 0 {
break loop
}
subscopeStack.popLast()
default:
break
}
j -= 1
}
if isSwitch {
let indent = indentStack[indentStack.count - 2]
setIndent(indent, atIndex: startOfLine(atIndex: i))
}
}
}
}
}
// Indent each new line
if token.type == .Linebreak {
var indent = indentStack.last ?? ""
linewrapped = !tokenIsEndOfStatement(lastNonWhitespaceOrLinebreakIndex)
if linewrapped && lineIndex == scopeStartLineIndexes.last {
indent = indentStack.count > 1 ? indentStack[indentStack.count - 2] : ""
scopeStartLineIndexes[scopeStartLineIndexes.count - 1] += 1
indentStack.popLast()
indentStack.append(indentStack.last ?? "")
}
lineIndex += 1
setIndent("", atIndex: i + 1)
// Only indent if line isn't blank
if let nextToken = formatter.tokenAtIndex(i + 2) where nextToken.type != .Linebreak {
indent += (linewrapped ? formatter.options.indent : "")
if let nextToken = formatter.tokenAtIndex(i + 1) where nextToken.type != .Linebreak {
let indent = (indentStack.last ?? "") + (linewrapped ? formatter.options.indent : "")
setIndent(indent, atIndex: i + 1)
}
}
@@ -864,15 +885,12 @@ public func indent(formatter: Formatter) {
if !linewrapped && formatter.tokenAtIndex(lastNonWhitespaceIndex)?.type == .Linebreak &&
!tokenIsStartOfStatement(i) {
linewrapped = true
var indent = indentStack.last ?? ""
if lineIndex - 1 == scopeStartLineIndexes.last {
indent = indentStack.count > 1 ? indentStack[indentStack.count - 2] : ""
scopeStartLineIndexes[scopeStartLineIndexes.count - 1] += 1
}
indent += (linewrapped ? formatter.options.indent : "")
if setIndent(indent, atIndex: startOfLine(atIndex: i)) {
i += 1
if linewrapped && lineIndex - 1 == scopeStartLineIndexes.last {
indentStack.popLast()
indentStack.append(indentStack.last ?? "")
}
let indent = (indentStack.last ?? "") + (linewrapped ? formatter.options.indent : "")
setIndent(indent, atIndex: startOfLine(atIndex: i))
}
lastNonWhitespaceIndex = i
if token.type != .Linebreak {
+1 -1
View File
@@ -2,7 +2,7 @@
// SwiftFormat
// SwiftFormat.h
//
// Version 0.6
// Version 0.5.1
//
// Created by Nick Lockwood on 12/08/2016.
// Copyright 2016 Charcoal Design
+1 -1
View File
@@ -2,7 +2,7 @@
// SwiftFormat
// SwiftFormat.swift
//
// Version 0.6
// Version 0.5.1
//
// Created by Nick Lockwood on 12/08/2016.
// Copyright 2016 Charcoal Design
+81 -111
View File
@@ -2,7 +2,7 @@
// SwiftFormat
// Tokenizer.swift
//
// Version 0.6
// Version 0.5.1
//
// Created by Nick Lockwood on 11/08/2016.
// Copyright 2016 Charcoal Design
@@ -74,34 +74,26 @@ public struct Token: Equatable {
}
public func closesScopeForToken(token: Token) -> Bool {
guard token.type == .StartOfScope else {
guard type != .StringBody && type != .CommentBody else {
return false
}
if type == .EndOfScope {
switch token.string {
case "(":
return string == ")"
case "[":
return string == "]"
case "{":
return string == "}" || string == "case" || string == "default"
case "/*":
return string == "*/"
case "#if":
return string == "#endif"
case ":":
return string == "case" || string == "default" || string == "}"
default:
break
}
}
switch token.string {
case "(":
return string == ")"
case "[":
return string == "]"
case "{":
return string == "}"
case "<":
return string.hasPrefix(">")
case "\"":
return string == "\""
case "/*":
return string == "*/"
case "//":
return type == .Linebreak
case "#if":
return string == "#endif"
default:
return false
}
@@ -203,20 +195,20 @@ private extension String.CharacterView {
}
switch c.unicodeValue {
case 0x00A1 ... 0x00A7,
0x00A9, 0x00AB, 0x00AC, 0x00AE,
0x00B0 ... 0x00B1,
0x00B6, 0x00BB, 0x00BF, 0x00D7, 0x00F7,
0x2016 ... 0x2017,
0x2020 ... 0x2027,
0x2030 ... 0x203E,
0x2041 ... 0x2053,
0x2055 ... 0x205E,
0x2190 ... 0x23FF,
0x2500 ... 0x2775,
0x2794 ... 0x2BFF,
0x2E00 ... 0x2E7F,
0x3001 ... 0x3003,
0x3008 ... 0x3030:
0x00A9, 0x00AB, 0x00AC, 0x00AE,
0x00B0 ... 0x00B1,
0x00B6, 0x00BB, 0x00BF, 0x00D7, 0x00F7,
0x2016 ... 0x2017,
0x2020 ... 0x2027,
0x2030 ... 0x203E,
0x2041 ... 0x2053,
0x2055 ... 0x205E,
0x2190 ... 0x23FF,
0x2500 ... 0x2775,
0x2794 ... 0x2BFF,
0x2E00 ... 0x2E7F,
0x3001 ... 0x3003,
0x3008 ... 0x3030:
return true
default:
return false
@@ -229,11 +221,11 @@ private extension String.CharacterView {
}
switch c.unicodeValue {
case 0x0300 ... 0x036F,
0x1DC0 ... 0x1DFF,
0x20D0 ... 0x20FF,
0xFE00 ... 0xFE0F,
0xFE20 ... 0xFE2F,
0xE0100 ... 0xE01EF:
0x1DC0 ... 0x1DFF,
0x20D0 ... 0x20FF,
0xFE00 ... 0xFE0F,
0xFE20 ... 0xFE2F,
0xE0100 ... 0xE01EF:
return true
default:
return false
@@ -278,51 +270,51 @@ private extension String.CharacterView {
}
switch c.unicodeValue {
case 0x00A8, 0x00AA, 0x00AD, 0x00AF,
0x00B2 ... 0x00B5,
0x00B7 ... 0x00BA,
0x00BC ... 0x00BE,
0x00C0 ... 0x00D6,
0x00D8 ... 0x00F6,
0x00F8 ... 0x00FF,
0x0100 ... 0x02FF,
0x0370 ... 0x167F,
0x1681 ... 0x180D,
0x180F ... 0x1DBF,
0x1E00 ... 0x1FFF,
0x200B ... 0x200D,
0x202A ... 0x202E,
0x203F ... 0x2040,
0x2054,
0x2060 ... 0x206F,
0x2070 ... 0x20CF,
0x2100 ... 0x218F,
0x2460 ... 0x24FF,
0x2776 ... 0x2793,
0x2C00 ... 0x2DFF,
0x2E80 ... 0x2FFF,
0x3004 ... 0x3007,
0x3021 ... 0x302F,
0x3031 ... 0x303F,
0x3040 ... 0xD7FF,
0xF900 ... 0xFD3D,
0xFD40 ... 0xFDCF,
0xFDF0 ... 0xFE1F,
0xFE30 ... 0xFE44,
0xFE47 ... 0xFFFD,
0x10000 ... 0x1FFFD,
0x20000 ... 0x2FFFD,
0x30000 ... 0x3FFFD,
0x40000 ... 0x4FFFD,
0x50000 ... 0x5FFFD,
0x60000 ... 0x6FFFD,
0x70000 ... 0x7FFFD,
0x80000 ... 0x8FFFD,
0x90000 ... 0x9FFFD,
0xA0000 ... 0xAFFFD,
0xB0000 ... 0xBFFFD,
0xC0000 ... 0xCFFFD,
0xD0000 ... 0xDFFFD,
0xE0000 ... 0xEFFFD:
0x00B2 ... 0x00B5,
0x00B7 ... 0x00BA,
0x00BC ... 0x00BE,
0x00C0 ... 0x00D6,
0x00D8 ... 0x00F6,
0x00F8 ... 0x00FF,
0x0100 ... 0x02FF,
0x0370 ... 0x167F,
0x1681 ... 0x180D,
0x180F ... 0x1DBF,
0x1E00 ... 0x1FFF,
0x200B ... 0x200D,
0x202A ... 0x202E,
0x203F ... 0x2040,
0x2054,
0x2060 ... 0x206F,
0x2070 ... 0x20CF,
0x2100 ... 0x218F,
0x2460 ... 0x24FF,
0x2776 ... 0x2793,
0x2C00 ... 0x2DFF,
0x2E80 ... 0x2FFF,
0x3004 ... 0x3007,
0x3021 ... 0x302F,
0x3031 ... 0x303F,
0x3040 ... 0xD7FF,
0xF900 ... 0xFD3D,
0xFD40 ... 0xFDCF,
0xFDF0 ... 0xFE1F,
0xFE30 ... 0xFE44,
0xFE47 ... 0xFFFD,
0x10000 ... 0x1FFFD,
0x20000 ... 0x2FFFD,
0x30000 ... 0x3FFFD,
0x40000 ... 0x4FFFD,
0x50000 ... 0x5FFFD,
0x60000 ... 0x6FFFD,
0x70000 ... 0x7FFFD,
0x80000 ... 0x8FFFD,
0x90000 ... 0x9FFFD,
0xA0000 ... 0xAFFFD,
0xB0000 ... 0xBFFFD,
0xC0000 ... 0xCFFFD,
0xD0000 ... 0xDFFFD,
0xE0000 ... 0xEFFFD:
return true
default:
return false
@@ -335,9 +327,9 @@ private extension String.CharacterView {
}
switch c.unicodeValue {
case 0x0300 ... 0x036F,
0x1DC0 ... 0x1DFF,
0x20D0 ... 0x20FF,
0xFE20 ... 0xFE2F:
0x1DC0 ... 0x1DFF,
0x20D0 ... 0x20FF,
0xFE20 ... 0xFE2F:
return true
default:
return false
@@ -427,8 +419,6 @@ func tokenize(source: String) -> [Token] {
var characters = source.characters
var lastNonWhitespaceIndex: Int?
var closedGenericScopeIndexes: [Int] = []
var nestedSwitches = 0
var inCaseStatement = false
func processStringBody() {
var string = ""
@@ -544,25 +534,6 @@ func tokenize(source: String) -> [Token] {
func processToken() {
let token = tokens.last!
if token.type != .Whitespace {
// Track switch/case statements
if token.type == .Identifier {
if token.string == "switch" {
nestedSwitches += 1
} else if nestedSwitches > 0 && (token.string == "case" || token.string == "default") {
let lastToken = tokens[lastNonWhitespaceIndex!]
if lastToken.string != "if" {
tokens[tokens.count - 1] = Token(.EndOfScope, token.string)
inCaseStatement = true
processToken()
return
}
}
} else if inCaseStatement && token.type == .Operator && token.string == ":" {
tokens[tokens.count - 1] = Token(.StartOfScope, ":")
inCaseStatement = false
processToken()
return
}
// Fix up misidentified generic that is actually a pair of operators
if let lastNonWhitespaceIndex = lastNonWhitespaceIndex {
let lastToken = tokens[lastNonWhitespaceIndex]
@@ -617,9 +588,7 @@ func tokenize(source: String) -> [Token] {
let scope = tokens[scopeIndex]
if token.closesScopeForToken(scope) {
scopeIndexStack.popLast()
if token.string == "}" && scope.string == ":" {
nestedSwitches -= 1
} else if token.string.hasPrefix(">") {
if token.string.hasPrefix(">") {
closedGenericScopeIndexes.append(scopeIndex)
tokens[tokens.count - 1] = Token(.EndOfScope, ">")
if token.string != ">" {
@@ -629,6 +598,7 @@ func tokenize(source: String) -> [Token] {
processToken()
return
}
} else if scopeIndexStack.last != nil && tokens[scopeIndexStack.last!].string == "\"" {
processStringBody()
}
+1 -31
View File
@@ -2,7 +2,7 @@
// SwiftFormat
// FormatterTests.swift
//
// Version 0.6
// Version 0.5.1
//
// Created by Nick Lockwood on 12/08/2016.
// Copyright 2016 Charcoal Design
@@ -360,12 +360,6 @@ class FormatterTests: XCTestCase {
XCTAssertEqual(format(input, rules: [spaceAroundOperators]), output)
}
func testSwitchWithEnumCases() {
let input = "switch x {\ncase.Foo:\nbreak\ndefault:\n break\n}"
let output = "switch x {\ncase .Foo:\nbreak\ndefault:\n break\n}"
XCTAssertEqual(format(input, rules: [spaceAroundOperators]), output)
}
func testSpaceAroundEnumReturn() {
let input = "return.Foo"
let output = "return .Foo"
@@ -624,18 +618,6 @@ class FormatterTests: XCTestCase {
XCTAssertEqual(format(input, rules: [indent]), output)
}
func testNestedBraces() {
let input = "({\n//foo\n}, {\n//bar\n})"
let output = "({\n //foo\n}, {\n //bar\n})"
XCTAssertEqual(format(input, rules: [indent]), output)
}
func testBraceIndentAfterComment() {
let input = "if foo { //comment\nbar\n}"
let output = "if foo { //comment\n bar\n}"
XCTAssertEqual(format(input, rules: [indent]), output)
}
// MARK: indent switch/case
func testSwitchCaseIndenting() {
@@ -644,12 +626,6 @@ class FormatterTests: XCTestCase {
XCTAssertEqual(format(input, rules: [indent]), output)
}
func testSwitchWrappedCaseIndenting() {
let input = "switch x {\ncase foo,\nbar,\n baz:\n break\ndefault:\n break\n}"
let output = "switch x {\ncase foo,\n bar,\n baz:\n break\ndefault:\n break\n}"
XCTAssertEqual(format(input, rules: [indent]), output)
}
func testEnumCaseIndenting() {
let input = "enum Foo {\ncase Bar\ncase Baz\n}"
let output = "enum Foo {\n case Bar\n case Baz\n}"
@@ -724,12 +700,6 @@ class FormatterTests: XCTestCase {
XCTAssertEqual(format(input, rules: [indent]), output)
}
func testNoPermanentReductionInScopeAfterWrap() {
let input = "{foo\nas Bar\nlet baz = 5\n}"
let output = "{foo\n as Bar\n let baz = 5\n}"
XCTAssertEqual(format(input, rules: [indent]), output)
}
func testWrappedLineBeforeOperator() {
let input = "if x {\nlet y = foo\n+ bar\n}"
let output = "if x {\n let y = foo\n + bar\n}"
+1 -99
View File
@@ -2,7 +2,7 @@
// SwiftFormat
// TokenizerTests.swift
//
// Version 0.6
// Version 0.5.1
//
// Created by Nick Lockwood on 12/08/2016.
// Copyright 2016 Charcoal Design
@@ -917,104 +917,6 @@ class TokenizerTests: XCTestCase {
XCTAssertEqualArrays(tokenize(input), output)
}
// MARK: case statements
func testSingleLineEnum() {
let input = "enum Foo {case Bar, Baz}"
let output = [
Token(.Identifier, "enum"),
Token(.Whitespace, " "),
Token(.Identifier, "Foo"),
Token(.Whitespace, " "),
Token(.StartOfScope, "{"),
Token(.Identifier, "case"),
Token(.Whitespace, " "),
Token(.Identifier, "Bar"),
Token(.Operator, ","),
Token(.Whitespace, " "),
Token(.Identifier, "Baz"),
Token(.EndOfScope, "}"),
]
XCTAssertEqualArrays(tokenize(input), output)
}
func testSingleLineGenericEnum() {
let input = "enum Foo<T> {case Bar, Baz}"
let output = [
Token(.Identifier, "enum"),
Token(.Whitespace, " "),
Token(.Identifier, "Foo"),
Token(.StartOfScope, "<"),
Token(.Identifier, "T"),
Token(.EndOfScope, ">"),
Token(.Whitespace, " "),
Token(.StartOfScope, "{"),
Token(.Identifier, "case"),
Token(.Whitespace, " "),
Token(.Identifier, "Bar"),
Token(.Operator, ","),
Token(.Whitespace, " "),
Token(.Identifier, "Baz"),
Token(.EndOfScope, "}"),
]
XCTAssertEqualArrays(tokenize(input), output)
}
func testMultilineLineEnum() {
let input = "enum Foo {\ncase Bar\ncase Baz\n}"
let output = [
Token(.Identifier, "enum"),
Token(.Whitespace, " "),
Token(.Identifier, "Foo"),
Token(.Whitespace, " "),
Token(.StartOfScope, "{"),
Token(.Linebreak, "\n"),
Token(.Identifier, "case"),
Token(.Whitespace, " "),
Token(.Identifier, "Bar"),
Token(.Linebreak, "\n"),
Token(.Identifier, "case"),
Token(.Whitespace, " "),
Token(.Identifier, "Baz"),
Token(.Linebreak, "\n"),
Token(.EndOfScope, "}"),
]
XCTAssertEqualArrays(tokenize(input), output)
}
func testSwitchStatement() {
let input = "switch x {\ncase 1:\nbreak\ncase 2:\nbreak\ndefault:\nbreak\n}"
let output = [
Token(.Identifier, "switch"),
Token(.Whitespace, " "),
Token(.Identifier, "x"),
Token(.Whitespace, " "),
Token(.StartOfScope, "{"),
Token(.Linebreak, "\n"),
Token(.EndOfScope, "case"),
Token(.Whitespace, " "),
Token(.Number, "1"),
Token(.StartOfScope, ":"),
Token(.Linebreak, "\n"),
Token(.Identifier, "break"),
Token(.Linebreak, "\n"),
Token(.EndOfScope, "case"),
Token(.Whitespace, " "),
Token(.Number, "2"),
Token(.StartOfScope, ":"),
Token(.Linebreak, "\n"),
Token(.Identifier, "break"),
Token(.Linebreak, "\n"),
Token(.EndOfScope, "default"),
Token(.StartOfScope, ":"),
Token(.Linebreak, "\n"),
Token(.Identifier, "break"),
Token(.Linebreak, "\n"),
Token(.EndOfScope, "}"),
]
XCTAssertEqualArrays(tokenize(input), output)
}
// MARK: linebreaks
func testLF() {