mirror of
https://github.com/nicklockwood/SwiftFormat.git
synced 2026-05-17 10:30:35 +00:00
206 lines
7.6 KiB
Swift
206 lines
7.6 KiB
Swift
//
|
|
// CommandLineTests.swift
|
|
// SwiftFormat
|
|
//
|
|
// Created by Nick Lockwood on 10/01/2017.
|
|
// Copyright 2017 Nick Lockwood
|
|
//
|
|
// Distributed under the permissive MIT license
|
|
// Get the latest version from here:
|
|
//
|
|
// https://github.com/nicklockwood/SwiftFormat
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
// of this software and associated documentation files (the "Software"), to deal
|
|
// in the Software without restriction, including without limitation the rights
|
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
// copies of the Software, and to permit persons to whom the Software is
|
|
// furnished to do so, subject to the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included in all
|
|
// copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
// SOFTWARE.
|
|
//
|
|
|
|
@testable import SwiftFormat
|
|
import XCTest
|
|
|
|
private var readme: String = {
|
|
let directoryURL = URL(fileURLWithPath: #file).deletingLastPathComponent().deletingLastPathComponent()
|
|
let readmeURL = directoryURL.appendingPathComponent("README.md")
|
|
return try! String(contentsOf: readmeURL, encoding: .utf8)
|
|
}()
|
|
|
|
class CommandLineTests: XCTestCase {
|
|
|
|
// MARK: arg preprocessor
|
|
|
|
func testPreprocessArguments() {
|
|
let input = ["", "foo", "bar", "-o", "baz", "-i", "4", "-l", "cr", "-s", "inline"]
|
|
let output = ["0": "", "1": "foo", "2": "bar", "output": "baz", "indent": "4", "linebreaks": "cr", "semicolons": "inline"]
|
|
XCTAssertEqual(try preprocessArguments(input, [
|
|
"output",
|
|
"indent",
|
|
"linebreaks",
|
|
"semicolons",
|
|
]), output)
|
|
}
|
|
|
|
func testEmptyArgsAreRecognized() {
|
|
let input = ["", "--help", "--version"]
|
|
let output = ["0": "", "help": "", "version": ""]
|
|
XCTAssertEqual(try preprocessArguments(input, [
|
|
"help",
|
|
"version",
|
|
]), output)
|
|
}
|
|
|
|
// MARK: format options to arguments
|
|
|
|
func testCommandLineArgumentsHaveValidNames() {
|
|
let arguments = commandLineArguments(for: FormatOptions())
|
|
for key in arguments.keys {
|
|
XCTAssertTrue(commandLineArguments.contains(key), "\(key) is not a valid argument name")
|
|
}
|
|
}
|
|
|
|
func testCommandLineArgumentsAreCorrect() {
|
|
let options = FormatOptions()
|
|
let output = ["allman": "false", "wraparguments": "disabled", "wrapelements": "beforefirst", "removelines": "enabled", "self": "remove", "header": "ignore", "binarygrouping": "4,8", "octalgrouping": "4,8", "patternlet": "hoist", "indentcase": "false", "trimwhitespace": "always", "decimalgrouping": "3,6", "commas": "always", "semicolons": "inline", "indent": "4", "exponentcase": "lowercase", "operatorfunc": "spaced", "elseposition": "same-line", "insertlines": "enabled", "empty": "void", "ranges": "spaced", "hexliteralcase": "uppercase", "linebreaks": "lf", "hexgrouping": "4,8", "comments": "indent", "ifdef": "indent", "stripunusedargs": "always"]
|
|
XCTAssertEqual(commandLineArguments(for: options), output)
|
|
}
|
|
|
|
// MARK: format arguments to options
|
|
|
|
func testFormatArgumentsAreAllImplemented() {
|
|
CLI.print = { _, _ in }
|
|
for key in formatArguments {
|
|
guard let value = commandLineArguments(for: FormatOptions())[key] else {
|
|
XCTFail(key)
|
|
continue
|
|
}
|
|
do {
|
|
_ = try formatOptionsFor([key: value])
|
|
} catch {
|
|
XCTFail("\(error)")
|
|
}
|
|
}
|
|
}
|
|
|
|
func testFileHeaderYearReplacement() {
|
|
do {
|
|
let options = try formatOptionsFor(["header": " Copyright 1981 - {year}"])
|
|
let formatter = DateFormatter()
|
|
formatter.dateFormat = "yyyy"
|
|
let year = formatter.string(from: Date())
|
|
XCTAssertEqual(options.fileHeader, "//Copyright 1981 - \(year)")
|
|
} catch {
|
|
XCTFail("\(error)")
|
|
}
|
|
}
|
|
|
|
// MARK: pipe
|
|
|
|
func testPipe() {
|
|
CLI.print = { message, _ in
|
|
XCTAssertEqual(message, "func foo() {\n bar()\n}\n")
|
|
}
|
|
var readCount = 0
|
|
CLI.readLine = {
|
|
readCount += 1
|
|
switch readCount {
|
|
case 1:
|
|
return "func foo()\n"
|
|
case 2:
|
|
return "{\n"
|
|
case 3:
|
|
return "bar()\n"
|
|
case 4:
|
|
return "}"
|
|
default:
|
|
return nil
|
|
}
|
|
}
|
|
processArguments([""])
|
|
}
|
|
|
|
// MARK: help
|
|
|
|
func testHelpLineLength() {
|
|
CLI.print = { message, _ in
|
|
XCTAssertLessThanOrEqual(message.count, 80, message)
|
|
}
|
|
printHelp()
|
|
}
|
|
|
|
func testHelpOptionsImplemented() {
|
|
CLI.print = { message, _ in
|
|
if message.hasPrefix("--") {
|
|
let name = String(message["--".endIndex ..< message.endIndex]).components(separatedBy: " ")[0]
|
|
XCTAssertTrue(commandLineArguments.contains(name), name)
|
|
}
|
|
}
|
|
printHelp()
|
|
}
|
|
|
|
func testHelpOptionsDocumented() {
|
|
var arguments = Set(commandLineArguments)
|
|
deprecatedArguments.forEach { arguments.remove($0) }
|
|
CLI.print = { message, _ in
|
|
if message.hasPrefix("--") {
|
|
let name = String(message["--".endIndex ..< message.endIndex]).components(separatedBy: " ")[0]
|
|
arguments.remove(name)
|
|
}
|
|
}
|
|
printHelp()
|
|
XCTAssert(arguments.isEmpty, "\(arguments.joined(separator: ","))")
|
|
}
|
|
|
|
// MARK: documentation
|
|
|
|
func testAllRulesInReadme() {
|
|
for ruleName in FormatRules.byName.keys {
|
|
XCTAssertTrue(readme.contains("***\(ruleName)*** - "), ruleName)
|
|
}
|
|
}
|
|
|
|
func testNoInvalidRulesInReadme() {
|
|
let ruleNames = Set(FormatRules.byName.keys)
|
|
var range = readme.startIndex ..< readme.endIndex
|
|
while let match = readme.range(of: "\\*[a-zA-Z]+\\* - ", options: .regularExpression, range: range, locale: nil) {
|
|
let lower = readme.index(after: match.lowerBound)
|
|
let upper = readme.index(match.upperBound, offsetBy: -4)
|
|
let ruleName: String = String(readme[lower ..< upper])
|
|
XCTAssertTrue(ruleNames.contains(ruleName), ruleName)
|
|
range = match.upperBound ..< range.upperBound
|
|
}
|
|
}
|
|
|
|
func testAllOptionsInReadme() {
|
|
var arguments = Set(formatArguments)
|
|
deprecatedArguments.forEach { arguments.remove($0) }
|
|
for argument in arguments {
|
|
XCTAssertTrue(readme.contains("`--\(argument)`"), argument)
|
|
}
|
|
}
|
|
|
|
func testNoInvalidOptionsInReadme() {
|
|
let arguments = Set(commandLineArguments)
|
|
var range = readme.startIndex ..< readme.endIndex
|
|
while let match = readme.range(of: "`--[a-zA-Z]+`", options: .regularExpression, range: range, locale: nil) {
|
|
let lower = readme.index(match.lowerBound, offsetBy: 3)
|
|
let upper = readme.index(before: match.upperBound)
|
|
let argument: String = String(readme[lower ..< upper])
|
|
XCTAssertTrue(arguments.contains(argument), argument)
|
|
range = match.upperBound ..< range.upperBound
|
|
}
|
|
}
|
|
}
|