From 2c824584266e422a37390af5e6927745119477cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Hern=C3=A1ndez?= Date: Sun, 18 Dec 2016 22:43:07 +0000 Subject: [PATCH 1/8] Add check to ignore urls for line_length rule --- CHANGELOG.md | 4 ++++ .../Rules/LineLengthRule.swift | 19 +++++++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8aae634cc..417d41e0a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -134,6 +134,10 @@ ##### Enhancements +* Add check to ignore urls in `line_length` rule. + [Javier Hernández](https://github.com/jaherhi) + [#384](https://github.com/realm/SwiftLint/issues/384) + * Add `closure_end_indentation` opt-in rule that validates closure closing braces according to these rules: * If the method call has chained breaking lines on each method diff --git a/Source/SwiftLintFramework/Rules/LineLengthRule.swift b/Source/SwiftLintFramework/Rules/LineLengthRule.swift index 877bf3cd8..50986e37b 100644 --- a/Source/SwiftLintFramework/Rules/LineLengthRule.swift +++ b/Source/SwiftLintFramework/Rules/LineLengthRule.swift @@ -20,12 +20,16 @@ public struct LineLengthRule: ConfigurationProviderRule, SourceKitFreeRule { nonTriggeringExamples: [ String(repeating: "/", count: 120) + "\n", String(repeating: "#colorLiteral(red: 0.9607843161, green: 0.7058823705, blue: 0.200000003, alpha: 1)", count: 120) + "\n", - String(repeating: "#imageLiteral(resourceName: \"image.jpg\")", count: 120) + "\n" + String(repeating: "#imageLiteral(resourceName: \"image.jpg\")", count: 120) + "\n", + "https://github.com/realm/SwiftLint " + String(repeating: "/", count: 118) + + " https://github.com/realm/SwiftLint\n", + "https://github.com/realm/SwiftLint/" + String(repeating: "a", count: 120) ], triggeringExamples: [ String(repeating: "/", count: 121) + "\n", String(repeating: "#colorLiteral(red: 0.9607843161, green: 0.7058823705, blue: 0.200000003, alpha: 1)", count: 121) + "\n", - String(repeating: "#imageLiteral(resourceName: \"image.jpg\")", count: 121) + "\n" + String(repeating: "#imageLiteral(resourceName: \"image.jpg\")", count: 121) + "\n", + String(repeating: "/", count: 121) + "https://github.com/realm/SwiftLint\n" ] ) @@ -40,6 +44,7 @@ public struct LineLengthRule: ConfigurationProviderRule, SourceKitFreeRule { } var strippedString = line.content + strippedString = stripUrls(fromSourceString: strippedString) strippedString = stripLiterals(fromSourceString: strippedString, withDelimiter: "#colorLiteral") strippedString = stripLiterals(fromSourceString: strippedString, @@ -87,4 +92,14 @@ public struct LineLengthRule: ConfigurationProviderRule, SourceKitFreeRule { return modifiedString } + private func stripUrls(fromSourceString sourceString: String) -> String { + let types = NSTextCheckingResult.CheckingType.link.rawValue + let range = NSRange(location: 0, length: sourceString.bridge().length) + guard let urlDetector = try? NSDataDetector(types: types) else { + return sourceString + } + return urlDetector.stringByReplacingMatches(in: sourceString, options: [], + range: range, withTemplate: "") + } + } From ed42d9b38eb08b7c232f50a0bd5aea36bd57f5e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Hern=C3=A1ndez?= Date: Wed, 21 Dec 2016 01:38:49 +0000 Subject: [PATCH 2/8] Add line length configuration to ignore urls --- CHANGELOG.md | 3 +- .../Rules/LineLengthRule.swift | 19 ++- .../LineLengthConfiguration.swift | 48 +++++++ SwiftLint.xcodeproj/project.pbxproj | 4 + .../RuleConfigurationTests.swift | 135 ++++++++++++++++++ .../SwiftLintFrameworkTests/RulesTests.swift | 22 ++- 6 files changed, 217 insertions(+), 14 deletions(-) create mode 100644 Source/SwiftLintFramework/Rules/RuleConfigurations/LineLengthConfiguration.swift diff --git a/CHANGELOG.md b/CHANGELOG.md index 417d41e0a..fcef10479 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -134,7 +134,8 @@ ##### Enhancements -* Add check to ignore urls in `line_length` rule. +* Add check to ignore urls in `line_length` rule when `ignores_urls` + configuration is enabled. [Javier Hernández](https://github.com/jaherhi) [#384](https://github.com/realm/SwiftLint/issues/384) diff --git a/Source/SwiftLintFramework/Rules/LineLengthRule.swift b/Source/SwiftLintFramework/Rules/LineLengthRule.swift index 50986e37b..07b6e0881 100644 --- a/Source/SwiftLintFramework/Rules/LineLengthRule.swift +++ b/Source/SwiftLintFramework/Rules/LineLengthRule.swift @@ -9,7 +9,7 @@ import SourceKittenFramework public struct LineLengthRule: ConfigurationProviderRule, SourceKitFreeRule { - public var configuration = SeverityLevelsConfiguration(warning: 120, error: 200) + public var configuration = LineLengthConfiguration(warning: 120, error: 200, ignoresUrls: false) public init() {} @@ -20,16 +20,12 @@ public struct LineLengthRule: ConfigurationProviderRule, SourceKitFreeRule { nonTriggeringExamples: [ String(repeating: "/", count: 120) + "\n", String(repeating: "#colorLiteral(red: 0.9607843161, green: 0.7058823705, blue: 0.200000003, alpha: 1)", count: 120) + "\n", - String(repeating: "#imageLiteral(resourceName: \"image.jpg\")", count: 120) + "\n", - "https://github.com/realm/SwiftLint " + String(repeating: "/", count: 118) - + " https://github.com/realm/SwiftLint\n", - "https://github.com/realm/SwiftLint/" + String(repeating: "a", count: 120) + String(repeating: "#imageLiteral(resourceName: \"image.jpg\")", count: 120) + "\n" ], triggeringExamples: [ String(repeating: "/", count: 121) + "\n", String(repeating: "#colorLiteral(red: 0.9607843161, green: 0.7058823705, blue: 0.200000003, alpha: 1)", count: 121) + "\n", - String(repeating: "#imageLiteral(resourceName: \"image.jpg\")", count: 121) + "\n", - String(repeating: "/", count: 121) + "https://github.com/realm/SwiftLint\n" + String(repeating: "#imageLiteral(resourceName: \"image.jpg\")", count: 121) + "\n" ] ) @@ -44,7 +40,9 @@ public struct LineLengthRule: ConfigurationProviderRule, SourceKitFreeRule { } var strippedString = line.content - strippedString = stripUrls(fromSourceString: strippedString) + if configuration.ignoresUrls { + strippedString = stripUrls(fromSourceString: strippedString) + } strippedString = stripLiterals(fromSourceString: strippedString, withDelimiter: "#colorLiteral") strippedString = stripLiterals(fromSourceString: strippedString, @@ -56,7 +54,7 @@ public struct LineLengthRule: ConfigurationProviderRule, SourceKitFreeRule { return StyleViolation(ruleDescription: type(of: self).description, severity: param.severity, location: Location(file: file.path, line: line.index), - reason: "Line should be \(configuration.warning) characters or less: " + + reason: "Line should be \(configuration.length.warning) characters or less: " + "currently \(length) characters") } return nil @@ -98,8 +96,7 @@ public struct LineLengthRule: ConfigurationProviderRule, SourceKitFreeRule { guard let urlDetector = try? NSDataDetector(types: types) else { return sourceString } - return urlDetector.stringByReplacingMatches(in: sourceString, options: [], - range: range, withTemplate: "") + return urlDetector.stringByReplacingMatches(in: sourceString, options: [], range: range, withTemplate: "") } } diff --git a/Source/SwiftLintFramework/Rules/RuleConfigurations/LineLengthConfiguration.swift b/Source/SwiftLintFramework/Rules/RuleConfigurations/LineLengthConfiguration.swift new file mode 100644 index 000000000..eaf29e22b --- /dev/null +++ b/Source/SwiftLintFramework/Rules/RuleConfigurations/LineLengthConfiguration.swift @@ -0,0 +1,48 @@ +// +// LineLengthConfiguration.swift +// SwiftLint +// +// Created by Javier Hernández on 21/12/16. +// Copyright © 2016 Realm. All rights reserved. +// + +import Foundation + +public struct LineLengthConfiguration: RuleConfiguration, Equatable { + public var consoleDescription: String { + return length.consoleDescription + ", ignores urls: \(ignoresUrls)" + } + + var length: SeverityLevelsConfiguration + var ignoresUrls: Bool + + var params: [RuleParameter] { + return length.params + } + + public init(warning: Int, error: Int?, ignoresUrls: Bool) { + length = SeverityLevelsConfiguration(warning: warning, error: error) + self.ignoresUrls = ignoresUrls + } + + public mutating func applyConfiguration(_ configuration: Any) throws { + if let configurationArray = [Int].array(of: configuration), !configurationArray.isEmpty { + let warning = configurationArray[0] + let error = (configurationArray.count > 1) ? configurationArray[1] : nil + length = SeverityLevelsConfiguration(warning: warning, error: error) + } else if let configDict = configuration as? [String: Any], !configDict.isEmpty + && Set(configDict.keys).isSubset(of: ["warning", "error", "ignores_urls"]) { + let warning = configDict["warning"] as? Int ?? length.warning + let error = configDict["error"] as? Int + length = SeverityLevelsConfiguration(warning: warning, error: error) + ignoresUrls = configDict["ignores_urls"] as? Bool ?? ignoresUrls + } else { + throw ConfigurationError.unknownConfiguration + } + } + +} + +public func == (lhs: LineLengthConfiguration, rhs: LineLengthConfiguration) -> Bool { + return lhs.length == rhs.length && lhs.ignoresUrls == rhs.ignoresUrls +} diff --git a/SwiftLint.xcodeproj/project.pbxproj b/SwiftLint.xcodeproj/project.pbxproj index c4a46cc6a..b3b752757 100644 --- a/SwiftLint.xcodeproj/project.pbxproj +++ b/SwiftLint.xcodeproj/project.pbxproj @@ -24,6 +24,7 @@ 2E336D1B1DF08BFB00CCFE77 /* EmojiReporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E336D191DF08AF200CCFE77 /* EmojiReporter.swift */; }; 2E5761AA1C573B83003271AF /* FunctionParameterCountRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E5761A91C573B83003271AF /* FunctionParameterCountRule.swift */; }; 37B3FA8B1DFD45A700AD30D2 /* Dictionary+SwiftLint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37B3FA8A1DFD45A700AD30D2 /* Dictionary+SwiftLint.swift */; }; + 3B034B6E1E0BE549005D49A9 /* LineLengthConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B034B6C1E0BE544005D49A9 /* LineLengthConfiguration.swift */; }; 3B0B14541C505D6300BE82F7 /* SeverityConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B0B14531C505D6300BE82F7 /* SeverityConfiguration.swift */; }; 3B1150CA1C31FC3F00D83B1E /* Yaml+SwiftLint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B1150C91C31FC3F00D83B1E /* Yaml+SwiftLint.swift */; }; 3B12C9C11C3209CB000B423F /* test.yml in Resources */ = {isa = PBXBuildFile; fileRef = 3B12C9BF1C3209AC000B423F /* test.yml */; }; @@ -264,6 +265,7 @@ 2E336D191DF08AF200CCFE77 /* EmojiReporter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EmojiReporter.swift; sourceTree = ""; }; 2E5761A91C573B83003271AF /* FunctionParameterCountRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FunctionParameterCountRule.swift; sourceTree = ""; }; 37B3FA8A1DFD45A700AD30D2 /* Dictionary+SwiftLint.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Dictionary+SwiftLint.swift"; sourceTree = ""; }; + 3B034B6C1E0BE544005D49A9 /* LineLengthConfiguration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LineLengthConfiguration.swift; sourceTree = ""; }; 3B0B14531C505D6300BE82F7 /* SeverityConfiguration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SeverityConfiguration.swift; sourceTree = ""; }; 3B1150C91C31FC3F00D83B1E /* Yaml+SwiftLint.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Yaml+SwiftLint.swift"; sourceTree = ""; }; 3B12C9BF1C3209AC000B423F /* test.yml */ = {isa = PBXFileReference; lastKnownFileType = text; path = test.yml; sourceTree = ""; }; @@ -512,6 +514,7 @@ D4C4A34A1DEA4FD700E0E04C /* AttributesConfiguration.swift */, D43B04671E07228D004016AF /* ColonConfiguration.swift */, D4C4A3511DEFBBB700E0E04C /* FileHeaderConfiguration.swift */, + 3B034B6C1E0BE544005D49A9 /* LineLengthConfiguration.swift */, 3BCC04D01C4F56D3006073C3 /* NameConfiguration.swift */, D4DA1DFD1E1A10DB0037413D /* NumberSeparatorConfiguration.swift */, 78F032471D7D614300BE709A /* OverridenSuperCallConfiguration.swift */, @@ -1120,6 +1123,7 @@ D4C4A34E1DEA877200E0E04C /* FileHeaderRule.swift in Sources */, 009E092A1DFEE4DD00B588A7 /* ProhibitedSuperConfiguration.swift in Sources */, BFF028AE1CBCF8A500B38A9D /* TrailingWhitespaceConfiguration.swift in Sources */, + 3B034B6E1E0BE549005D49A9 /* LineLengthConfiguration.swift in Sources */, D4C4A34C1DEA4FF000E0E04C /* AttributesConfiguration.swift in Sources */, 83D71E281B131ECE000395DE /* RuleDescription.swift in Sources */, 3B12C9C51C322032000B423F /* MasterRuleList.swift in Sources */, diff --git a/Tests/SwiftLintFrameworkTests/RuleConfigurationTests.swift b/Tests/SwiftLintFrameworkTests/RuleConfigurationTests.swift index 403c5bb00..56d09cc4c 100644 --- a/Tests/SwiftLintFrameworkTests/RuleConfigurationTests.swift +++ b/Tests/SwiftLintFrameworkTests/RuleConfigurationTests.swift @@ -10,8 +10,127 @@ import SourceKittenFramework @testable import SwiftLintFramework import XCTest +// swiftlint:disable file_length +// swiftlint:disable:next type_body_length class RuleConfigurationsTests: XCTestCase { + func testLineLengthConfigurationInitializerSetsLength() { + let warning = 100 + let error = 150 + let length1 = SeverityLevelsConfiguration(warning: warning, error: error) + let configuration1 = LineLengthConfiguration(warning: warning, error: error, ignoresUrls: true) + XCTAssertEqual(configuration1.length, length1) + + let length2 = SeverityLevelsConfiguration(warning: warning, error: nil) + let configuration2 = LineLengthConfiguration(warning: warning, error: nil, ignoresUrls: true) + XCTAssertEqual(configuration2.length, length2) + } + + func testLineLengthConfigurationInitialiserSetsIgnoresUrls() { + let configuration1 = LineLengthConfiguration(warning: 100, error: 150, ignoresUrls: true) + XCTAssertTrue(configuration1.ignoresUrls) + + let configuration2 = LineLengthConfiguration(warning: 100, error: 150, ignoresUrls: false) + XCTAssertFalse(configuration2.ignoresUrls) + } + + func testLineLengthConfigurationParams() { + let warning = 13 + let error = 10 + let configuration = LineLengthConfiguration(warning: warning, error: error, ignoresUrls: true) + let params = [RuleParameter(severity: .error, value: error), RuleParameter(severity: .warning, value: warning)] + XCTAssertEqual(configuration.params, params) + } + + func testLineLengthConfigurationPartialParams() { + let warning = 13 + let configuration = LineLengthConfiguration(warning: warning, error: nil, ignoresUrls: true) + XCTAssertEqual(configuration.params, [RuleParameter(severity: .warning, value: 13)]) + } + + func testLineLengthConfigurationThrowsOnBadConfig() { + let config = "unknown" + var configuration = LineLengthConfiguration(warning: 100, error: 150, ignoresUrls: true) + + checkError(ConfigurationError.unknownConfiguration) { + try configuration.applyConfiguration(config) + } + } + + func testLineLengthConfigurationApplyConfigurationWithArray() { + var configuration = LineLengthConfiguration(warning: 0, error: 0, ignoresUrls: false) + + let warning1 = 100 + let error1 = 100 + let length1 = SeverityLevelsConfiguration(warning: warning1, error: error1) + let config1 = [warning1, error1] + + let warning2 = 150 + let length2 = SeverityLevelsConfiguration(warning: warning2, error: nil) + let config2 = [warning2] + + do { + try configuration.applyConfiguration(config1) + XCTAssertEqual(configuration.length, length1) + + try configuration.applyConfiguration(config2) + XCTAssertEqual(configuration.length, length2) + } catch { + XCTFail() + } + } + + func testLineLengthConfigurationApplyConfigurationWithDictionary() { + var configuration = LineLengthConfiguration(warning: 0, error: 0, ignoresUrls: false) + + let warning1 = 100 + let error1 = 100 + let length1 = SeverityLevelsConfiguration(warning: warning1, error: error1) + let config1: [String: Any] = ["warning": warning1, "error": error1, "ignores_urls": true] + + let warning2 = 200 + let error2 = 200 + let length2 = SeverityLevelsConfiguration(warning: warning2, error: error2) + let config2: [String: Int] = ["warning": warning2, "error": error2] + + let length3 = SeverityLevelsConfiguration(warning: warning2, error: nil) + let config3: [String: Bool] = ["ignores_urls": false] + + do { + try configuration.applyConfiguration(config1) + XCTAssertEqual(configuration.length, length1) + XCTAssertTrue(configuration.ignoresUrls) + + try configuration.applyConfiguration(config2) + XCTAssertEqual(configuration.length, length2) + XCTAssertTrue(configuration.ignoresUrls) + + try configuration.applyConfiguration(config3) + XCTAssertEqual(configuration.length, length3) + XCTAssertFalse(configuration.ignoresUrls) + } catch { + XCTFail() + } + } + + func testLineLengthConfigurationCompares() { + let configuration1 = LineLengthConfiguration(warning: 100, error: 100, ignoresUrls: true) + let configuration2 = LineLengthConfiguration(warning: 100, error: 100, ignoresUrls: false) + XCTAssertFalse(configuration1 == configuration2) + + let configuration3 = LineLengthConfiguration(warning: 100, error: 200, ignoresUrls: true) + XCTAssertFalse(configuration1 == configuration3) + + let configuration4 = LineLengthConfiguration(warning: 200, error: 100, ignoresUrls: true) + XCTAssertFalse(configuration1 == configuration4) + + let configuration5 = LineLengthConfiguration(warning: 100, error: 100, ignoresUrls: true) + XCTAssertTrue(configuration1 == configuration5) + + let configuration6 = LineLengthConfiguration(warning: 100, error: 100, ignoresUrls: false) + XCTAssertTrue(configuration2 == configuration6) + } + func testNameConfigurationSetsCorrectly() { let config = [ "min_length": ["warning": 17, "error": 7], "max_length": ["warning": 170, "error": 700], @@ -279,6 +398,22 @@ class RuleConfigurationsTests: XCTestCase { extension RuleConfigurationsTests { static var allTests: [(String, (RuleConfigurationsTests) -> () throws -> Void)] { return [ + ("testLineLengthConfigurationInitializerSetsLength", + testLineLengthConfigurationParams), + ("testLineLengthConfigurationInitialiserSetsIgnoresUrls", + testLineLengthConfigurationInitialiserSetsIgnoresUrls), + ("testLineLengthConfigurationPartialParams", + testLineLengthConfigurationPartialParams), + ("testLineLengthConfigurationParams", + testLineLengthConfigurationParams), + ("testLineLengthConfigurationThrowsOnBadConfig", + testLineLengthConfigurationThrowsOnBadConfig), + ("testLineLengthConfigurationApplyConfigurationWithArray", + testLineLengthConfigurationApplyConfigurationWithArray), + ("testLineLengthConfigurationApplyConfigurationWithDictionary", + testLineLengthConfigurationApplyConfigurationWithDictionary), + ("testLineLengthConfigurationCompares", + testLineLengthConfigurationCompares), ("testNameConfigurationSetsCorrectly", testNameConfigurationSetsCorrectly), ("testNameConfigurationThrowsOnBadConfig", diff --git a/Tests/SwiftLintFrameworkTests/RulesTests.swift b/Tests/SwiftLintFrameworkTests/RulesTests.swift index 6846bc154..3ae2487c0 100644 --- a/Tests/SwiftLintFrameworkTests/RulesTests.swift +++ b/Tests/SwiftLintFrameworkTests/RulesTests.swift @@ -135,8 +135,26 @@ class RulesTests: XCTestCase { } func testLineLength() { - verifyRule(LineLengthRule.description, commentDoesntViolate: false, - stringDoesntViolate: false) + verifyRule(LineLengthRule.description, commentDoesntViolate: false, stringDoesntViolate: false) + + // Perform additional tests with the ignores_urls settings enabled + let url = "https://github.com/realm/SwiftLint" + let triggeringLines = [String(repeating: "/", count: 121) + "\(url)\n"] + let nonTriggeringLines = ["\(url) " + String(repeating: "/", count: 118) + " \(url)\n", + "\(url)/" + String(repeating: "a", count: 120)] + + let baseDescription = LineLengthRule.description + let nonTriggeringExamples = baseDescription.nonTriggeringExamples + nonTriggeringLines + let triggeringExamples = baseDescription.triggeringExamples + triggeringLines + let description = RuleDescription(identifier: baseDescription.identifier, + name: baseDescription.name, + description: baseDescription.description, + nonTriggeringExamples: nonTriggeringExamples, + triggeringExamples: triggeringExamples, + corrections: baseDescription.corrections) + + verifyRule(description, ruleConfiguration: ["ignores_urls": true], + commentDoesntViolate: false, stringDoesntViolate: false) } func testMark() { From e87ecc684a2186df752897b89ce3ba50a1d33c7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Hern=C3=A1ndez?= Date: Thu, 22 Dec 2016 15:42:05 +0100 Subject: [PATCH 3/8] Add import to fix tests running with SPM --- Source/SwiftLintFramework/Rules/LineLengthRule.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/SwiftLintFramework/Rules/LineLengthRule.swift b/Source/SwiftLintFramework/Rules/LineLengthRule.swift index 07b6e0881..6ffa425e2 100644 --- a/Source/SwiftLintFramework/Rules/LineLengthRule.swift +++ b/Source/SwiftLintFramework/Rules/LineLengthRule.swift @@ -6,6 +6,7 @@ // Copyright © 2015 Realm. All rights reserved. // +import Foundation import SourceKittenFramework public struct LineLengthRule: ConfigurationProviderRule, SourceKitFreeRule { From 384c7a85075f9580f4662e39713486e57455127b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Hern=C3=A1ndez?= Date: Sat, 31 Dec 2016 02:25:42 +0100 Subject: [PATCH 4/8] Use NSRegularExpression to fix the rule on Linux --- .../Rules/LineLengthRule.swift | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/Source/SwiftLintFramework/Rules/LineLengthRule.swift b/Source/SwiftLintFramework/Rules/LineLengthRule.swift index 6ffa425e2..49541470d 100644 --- a/Source/SwiftLintFramework/Rules/LineLengthRule.swift +++ b/Source/SwiftLintFramework/Rules/LineLengthRule.swift @@ -92,12 +92,24 @@ public struct LineLengthRule: ConfigurationProviderRule, SourceKitFreeRule { } private func stripUrls(fromSourceString sourceString: String) -> String { - let types = NSTextCheckingResult.CheckingType.link.rawValue let range = NSRange(location: 0, length: sourceString.bridge().length) - guard let urlDetector = try? NSDataDetector(types: types) else { - return sourceString - } - return urlDetector.stringByReplacingMatches(in: sourceString, options: [], range: range, withTemplate: "") + // Workaround for Linux until NSDataDetector is available + #if os(Linux) + // Regex pattern from http://daringfireball.net/2010/07/improved_regex_for_matching_urls + let pattern = "(?i)\\b((?:[a-z][\\w-]+:(?:/{1,3}|[a-z0-9%])|www\\d{0,3}[.]|[a-z0-9.\\-]+[.][a-z]{2,4}/)" + + "(?:[^\\s()<>]+|\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*\\))+(?:\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*" + + "\\)|[^\\s`!()\\[\\]{};:'\".,<>?«»“”‘’]))" + guard let regex = try? NSRegularExpression(pattern: pattern, options: []) else { + return sourceString + } + return regex.stringByReplacingMatches(in: sourceString, options: [], range: range, withTemplate: "") + #else + let types = NSTextCheckingResult.CheckingType.link.rawValue + guard let urlDetector = try? NSDataDetector(types: types) else { + return sourceString + } + return urlDetector.stringByReplacingMatches(in: sourceString, options: [], range: range, withTemplate: "") + #endif } } From d58d26f526d6d567889583ac0b87416df2621df8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Hern=C3=A1ndez?= Date: Thu, 5 Jan 2017 22:30:54 +0100 Subject: [PATCH 5/8] Use regex to cache the regular expression --- Source/SwiftLintFramework/Rules/LineLengthRule.swift | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Source/SwiftLintFramework/Rules/LineLengthRule.swift b/Source/SwiftLintFramework/Rules/LineLengthRule.swift index 49541470d..f8d1db1c7 100644 --- a/Source/SwiftLintFramework/Rules/LineLengthRule.swift +++ b/Source/SwiftLintFramework/Rules/LineLengthRule.swift @@ -99,10 +99,8 @@ public struct LineLengthRule: ConfigurationProviderRule, SourceKitFreeRule { let pattern = "(?i)\\b((?:[a-z][\\w-]+:(?:/{1,3}|[a-z0-9%])|www\\d{0,3}[.]|[a-z0-9.\\-]+[.][a-z]{2,4}/)" + "(?:[^\\s()<>]+|\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*\\))+(?:\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*" + "\\)|[^\\s`!()\\[\\]{};:'\".,<>?«»“”‘’]))" - guard let regex = try? NSRegularExpression(pattern: pattern, options: []) else { - return sourceString - } - return regex.stringByReplacingMatches(in: sourceString, options: [], range: range, withTemplate: "") + let urlRegex = regex(pattern) + return urlRegex.stringByReplacingMatches(in: sourceString, options: [], range: range, withTemplate: "") #else let types = NSTextCheckingResult.CheckingType.link.rawValue guard let urlDetector = try? NSDataDetector(types: types) else { From cf2c7ced3944c0920fe3250926ea6c5eb66095e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Hern=C3=A1ndez?= Date: Thu, 5 Jan 2017 23:27:54 +0100 Subject: [PATCH 6/8] Move method to strip urls to String extension --- CHANGELOG.md | 10 ++--- .../Rules/LineLengthRule.swift | 20 +++++----- .../LineLengthConfiguration.swift | 12 +++--- .../RuleConfigurationTests.swift | 40 +++++++++---------- 4 files changed, 42 insertions(+), 40 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fcef10479..6782dfb97 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -98,6 +98,11 @@ [Aaron McTavish](https://github.com/aamctustwo) [#769](https://github.com/realm/SwiftLint/issues/769) +* Add check to ignore urls in `line_length` rule when `ignores_urls` + configuration is enabled. + [Javier Hernández](https://github.com/jaherhi) + [#384](https://github.com/realm/SwiftLint/issues/384) + ##### Bug Fixes * Ignore close parentheses on `vertical_parameter_alignment` rule. @@ -134,11 +139,6 @@ ##### Enhancements -* Add check to ignore urls in `line_length` rule when `ignores_urls` - configuration is enabled. - [Javier Hernández](https://github.com/jaherhi) - [#384](https://github.com/realm/SwiftLint/issues/384) - * Add `closure_end_indentation` opt-in rule that validates closure closing braces according to these rules: * If the method call has chained breaking lines on each method diff --git a/Source/SwiftLintFramework/Rules/LineLengthRule.swift b/Source/SwiftLintFramework/Rules/LineLengthRule.swift index f8d1db1c7..55efb04de 100644 --- a/Source/SwiftLintFramework/Rules/LineLengthRule.swift +++ b/Source/SwiftLintFramework/Rules/LineLengthRule.swift @@ -10,7 +10,7 @@ import Foundation import SourceKittenFramework public struct LineLengthRule: ConfigurationProviderRule, SourceKitFreeRule { - public var configuration = LineLengthConfiguration(warning: 120, error: 200, ignoresUrls: false) + public var configuration = LineLengthConfiguration(warning: 120, error: 200, ignoresURLs: false) public init() {} @@ -41,8 +41,8 @@ public struct LineLengthRule: ConfigurationProviderRule, SourceKitFreeRule { } var strippedString = line.content - if configuration.ignoresUrls { - strippedString = stripUrls(fromSourceString: strippedString) + if configuration.ignoresURLs { + strippedString = strippedString.strippingURLs } strippedString = stripLiterals(fromSourceString: strippedString, withDelimiter: "#colorLiteral") @@ -91,8 +91,11 @@ public struct LineLengthRule: ConfigurationProviderRule, SourceKitFreeRule { return modifiedString } - private func stripUrls(fromSourceString sourceString: String) -> String { - let range = NSRange(location: 0, length: sourceString.bridge().length) +} + +fileprivate extension String { + var strippingURLs: String { + let range = NSRange(location: 0, length: bridge().length) // Workaround for Linux until NSDataDetector is available #if os(Linux) // Regex pattern from http://daringfireball.net/2010/07/improved_regex_for_matching_urls @@ -100,14 +103,13 @@ public struct LineLengthRule: ConfigurationProviderRule, SourceKitFreeRule { "(?:[^\\s()<>]+|\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*\\))+(?:\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*" + "\\)|[^\\s`!()\\[\\]{};:'\".,<>?«»“”‘’]))" let urlRegex = regex(pattern) - return urlRegex.stringByReplacingMatches(in: sourceString, options: [], range: range, withTemplate: "") + return urlRegex.stringByReplacingMatches(in: self, options: [], range: range, withTemplate: "") #else let types = NSTextCheckingResult.CheckingType.link.rawValue guard let urlDetector = try? NSDataDetector(types: types) else { - return sourceString + return self } - return urlDetector.stringByReplacingMatches(in: sourceString, options: [], range: range, withTemplate: "") + return urlDetector.stringByReplacingMatches(in: self, options: [], range: range, withTemplate: "") #endif } - } diff --git a/Source/SwiftLintFramework/Rules/RuleConfigurations/LineLengthConfiguration.swift b/Source/SwiftLintFramework/Rules/RuleConfigurations/LineLengthConfiguration.swift index eaf29e22b..5c2873e19 100644 --- a/Source/SwiftLintFramework/Rules/RuleConfigurations/LineLengthConfiguration.swift +++ b/Source/SwiftLintFramework/Rules/RuleConfigurations/LineLengthConfiguration.swift @@ -10,19 +10,19 @@ import Foundation public struct LineLengthConfiguration: RuleConfiguration, Equatable { public var consoleDescription: String { - return length.consoleDescription + ", ignores urls: \(ignoresUrls)" + return length.consoleDescription + ", ignores urls: \(ignoresURLs)" } var length: SeverityLevelsConfiguration - var ignoresUrls: Bool + var ignoresURLs: Bool var params: [RuleParameter] { return length.params } - public init(warning: Int, error: Int?, ignoresUrls: Bool) { + public init(warning: Int, error: Int?, ignoresURLs: Bool) { length = SeverityLevelsConfiguration(warning: warning, error: error) - self.ignoresUrls = ignoresUrls + self.ignoresURLs = ignoresURLs } public mutating func applyConfiguration(_ configuration: Any) throws { @@ -35,7 +35,7 @@ public struct LineLengthConfiguration: RuleConfiguration, Equatable { let warning = configDict["warning"] as? Int ?? length.warning let error = configDict["error"] as? Int length = SeverityLevelsConfiguration(warning: warning, error: error) - ignoresUrls = configDict["ignores_urls"] as? Bool ?? ignoresUrls + ignoresURLs = configDict["ignores_urls"] as? Bool ?? ignoresURLs } else { throw ConfigurationError.unknownConfiguration } @@ -44,5 +44,5 @@ public struct LineLengthConfiguration: RuleConfiguration, Equatable { } public func == (lhs: LineLengthConfiguration, rhs: LineLengthConfiguration) -> Bool { - return lhs.length == rhs.length && lhs.ignoresUrls == rhs.ignoresUrls + return lhs.length == rhs.length && lhs.ignoresURLs == rhs.ignoresURLs } diff --git a/Tests/SwiftLintFrameworkTests/RuleConfigurationTests.swift b/Tests/SwiftLintFrameworkTests/RuleConfigurationTests.swift index 56d09cc4c..71c5dface 100644 --- a/Tests/SwiftLintFrameworkTests/RuleConfigurationTests.swift +++ b/Tests/SwiftLintFrameworkTests/RuleConfigurationTests.swift @@ -18,39 +18,39 @@ class RuleConfigurationsTests: XCTestCase { let warning = 100 let error = 150 let length1 = SeverityLevelsConfiguration(warning: warning, error: error) - let configuration1 = LineLengthConfiguration(warning: warning, error: error, ignoresUrls: true) + let configuration1 = LineLengthConfiguration(warning: warning, error: error, ignoresURLs: true) XCTAssertEqual(configuration1.length, length1) let length2 = SeverityLevelsConfiguration(warning: warning, error: nil) - let configuration2 = LineLengthConfiguration(warning: warning, error: nil, ignoresUrls: true) + let configuration2 = LineLengthConfiguration(warning: warning, error: nil, ignoresURLs: true) XCTAssertEqual(configuration2.length, length2) } func testLineLengthConfigurationInitialiserSetsIgnoresUrls() { - let configuration1 = LineLengthConfiguration(warning: 100, error: 150, ignoresUrls: true) - XCTAssertTrue(configuration1.ignoresUrls) + let configuration1 = LineLengthConfiguration(warning: 100, error: 150, ignoresURLs: true) + XCTAssertTrue(configuration1.ignoresURLs) - let configuration2 = LineLengthConfiguration(warning: 100, error: 150, ignoresUrls: false) - XCTAssertFalse(configuration2.ignoresUrls) + let configuration2 = LineLengthConfiguration(warning: 100, error: 150, ignoresURLs: false) + XCTAssertFalse(configuration2.ignoresURLs) } func testLineLengthConfigurationParams() { let warning = 13 let error = 10 - let configuration = LineLengthConfiguration(warning: warning, error: error, ignoresUrls: true) + let configuration = LineLengthConfiguration(warning: warning, error: error, ignoresURLs: true) let params = [RuleParameter(severity: .error, value: error), RuleParameter(severity: .warning, value: warning)] XCTAssertEqual(configuration.params, params) } func testLineLengthConfigurationPartialParams() { let warning = 13 - let configuration = LineLengthConfiguration(warning: warning, error: nil, ignoresUrls: true) + let configuration = LineLengthConfiguration(warning: warning, error: nil, ignoresURLs: true) XCTAssertEqual(configuration.params, [RuleParameter(severity: .warning, value: 13)]) } func testLineLengthConfigurationThrowsOnBadConfig() { let config = "unknown" - var configuration = LineLengthConfiguration(warning: 100, error: 150, ignoresUrls: true) + var configuration = LineLengthConfiguration(warning: 100, error: 150, ignoresURLs: true) checkError(ConfigurationError.unknownConfiguration) { try configuration.applyConfiguration(config) @@ -58,7 +58,7 @@ class RuleConfigurationsTests: XCTestCase { } func testLineLengthConfigurationApplyConfigurationWithArray() { - var configuration = LineLengthConfiguration(warning: 0, error: 0, ignoresUrls: false) + var configuration = LineLengthConfiguration(warning: 0, error: 0, ignoresURLs: false) let warning1 = 100 let error1 = 100 @@ -81,7 +81,7 @@ class RuleConfigurationsTests: XCTestCase { } func testLineLengthConfigurationApplyConfigurationWithDictionary() { - var configuration = LineLengthConfiguration(warning: 0, error: 0, ignoresUrls: false) + var configuration = LineLengthConfiguration(warning: 0, error: 0, ignoresURLs: false) let warning1 = 100 let error1 = 100 @@ -99,35 +99,35 @@ class RuleConfigurationsTests: XCTestCase { do { try configuration.applyConfiguration(config1) XCTAssertEqual(configuration.length, length1) - XCTAssertTrue(configuration.ignoresUrls) + XCTAssertTrue(configuration.ignoresURLs) try configuration.applyConfiguration(config2) XCTAssertEqual(configuration.length, length2) - XCTAssertTrue(configuration.ignoresUrls) + XCTAssertTrue(configuration.ignoresURLs) try configuration.applyConfiguration(config3) XCTAssertEqual(configuration.length, length3) - XCTAssertFalse(configuration.ignoresUrls) + XCTAssertFalse(configuration.ignoresURLs) } catch { XCTFail() } } func testLineLengthConfigurationCompares() { - let configuration1 = LineLengthConfiguration(warning: 100, error: 100, ignoresUrls: true) - let configuration2 = LineLengthConfiguration(warning: 100, error: 100, ignoresUrls: false) + let configuration1 = LineLengthConfiguration(warning: 100, error: 100, ignoresURLs: true) + let configuration2 = LineLengthConfiguration(warning: 100, error: 100, ignoresURLs: false) XCTAssertFalse(configuration1 == configuration2) - let configuration3 = LineLengthConfiguration(warning: 100, error: 200, ignoresUrls: true) + let configuration3 = LineLengthConfiguration(warning: 100, error: 200, ignoresURLs: true) XCTAssertFalse(configuration1 == configuration3) - let configuration4 = LineLengthConfiguration(warning: 200, error: 100, ignoresUrls: true) + let configuration4 = LineLengthConfiguration(warning: 200, error: 100, ignoresURLs: true) XCTAssertFalse(configuration1 == configuration4) - let configuration5 = LineLengthConfiguration(warning: 100, error: 100, ignoresUrls: true) + let configuration5 = LineLengthConfiguration(warning: 100, error: 100, ignoresURLs: true) XCTAssertTrue(configuration1 == configuration5) - let configuration6 = LineLengthConfiguration(warning: 100, error: 100, ignoresUrls: false) + let configuration6 = LineLengthConfiguration(warning: 100, error: 100, ignoresURLs: false) XCTAssertTrue(configuration2 == configuration6) } From 7b3648899d4b271dd04e21fbea5e15bf5d3aafa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Hern=C3=A1ndez?= Date: Fri, 6 Jan 2017 00:15:41 +0100 Subject: [PATCH 7/8] Extract line length tests to their own test files --- SwiftLint.xcodeproj/project.pbxproj | 8 + Tests/LinuxMain.swift | 2 + .../LineLengthConfigurationTests.swift | 154 ++++++++++++++++++ .../LineLengthRuleTests.swift | 47 ++++++ .../RuleConfigurationTests.swift | 135 --------------- .../SwiftLintFrameworkTests/RulesTests.swift | 25 --- 6 files changed, 211 insertions(+), 160 deletions(-) create mode 100644 Tests/SwiftLintFrameworkTests/LineLengthConfigurationTests.swift create mode 100644 Tests/SwiftLintFrameworkTests/LineLengthRuleTests.swift diff --git a/SwiftLint.xcodeproj/project.pbxproj b/SwiftLint.xcodeproj/project.pbxproj index b3b752757..0944dc0aa 100644 --- a/SwiftLint.xcodeproj/project.pbxproj +++ b/SwiftLint.xcodeproj/project.pbxproj @@ -34,6 +34,8 @@ 3B1DF0121C5148140011BCED /* CustomRules.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B1DF0111C5148140011BCED /* CustomRules.swift */; }; 3B30C4A11C3785B300E04027 /* YamlParserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B30C4A01C3785B300E04027 /* YamlParserTests.swift */; }; 3B5B9FE11C444DA20009AD27 /* Array+SwiftLint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B5B9FE01C444DA20009AD27 /* Array+SwiftLint.swift */; }; + 3B63D46D1E1F05160057BE35 /* LineLengthConfigurationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B63D46C1E1F05160057BE35 /* LineLengthConfigurationTests.swift */; }; + 3B63D46F1E1F09DF0057BE35 /* LineLengthRuleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B63D46E1E1F09DF0057BE35 /* LineLengthRuleTests.swift */; }; 3B828E531C546468000D180E /* RuleConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B828E521C546468000D180E /* RuleConfiguration.swift */; }; 3BA79C9B1C4767910057E705 /* NSRange+SwiftLint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BA79C9A1C4767910057E705 /* NSRange+SwiftLint.swift */; }; 3BB47D831C514E8100AE6A10 /* RegexConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BB47D821C514E8100AE6A10 /* RegexConfiguration.swift */; }; @@ -275,6 +277,8 @@ 3B1DF0111C5148140011BCED /* CustomRules.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomRules.swift; sourceTree = ""; }; 3B30C4A01C3785B300E04027 /* YamlParserTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = YamlParserTests.swift; sourceTree = ""; }; 3B5B9FE01C444DA20009AD27 /* Array+SwiftLint.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Array+SwiftLint.swift"; sourceTree = ""; }; + 3B63D46C1E1F05160057BE35 /* LineLengthConfigurationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LineLengthConfigurationTests.swift; sourceTree = ""; }; + 3B63D46E1E1F09DF0057BE35 /* LineLengthRuleTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LineLengthRuleTests.swift; sourceTree = ""; }; 3B828E521C546468000D180E /* RuleConfiguration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RuleConfiguration.swift; sourceTree = ""; }; 3BA79C9A1C4767910057E705 /* NSRange+SwiftLint.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSRange+SwiftLint.swift"; sourceTree = ""; }; 3BB47D821C514E8100AE6A10 /* RegexConfiguration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RegexConfiguration.swift; sourceTree = ""; }; @@ -694,6 +698,8 @@ E809EDA21B8A73FB00399043 /* ConfigurationTests.swift */, D4348EE91C46122C007707FB /* FunctionBodyLengthRuleTests.swift */, D4998DE81DF194F20006E05D /* FileHeaderRuleTests.swift */, + 3B63D46C1E1F05160057BE35 /* LineLengthConfigurationTests.swift */, + 3B63D46E1E1F09DF0057BE35 /* LineLengthRuleTests.swift */, C9802F2E1E0C8AEE008AB27F /* TrailingCommaRuleTests.swift */, E832F10C1B17E725003F265F /* IntegrationTests.swift */, E86396C61BADAFE6002C9E88 /* ReporterTests.swift */, @@ -1255,6 +1261,7 @@ 006204DE1E1E4E0A00FFFBE1 /* VerticalWhitespaceRuleTests.swift in Sources */, 02FD8AEF1BFC18D60014BFFB /* ExtendedNSStringTests.swift in Sources */, D4348EEA1C46122C007707FB /* FunctionBodyLengthRuleTests.swift in Sources */, + 3B63D46D1E1F05160057BE35 /* LineLengthConfigurationTests.swift in Sources */, 6C7045441C6ADA450003F15A /* SourceKitCrashTests.swift in Sources */, 3BB47D871C51DE6E00AE6A10 /* CustomRulesTests.swift in Sources */, E812249A1B04F85B001783D2 /* TestHelpers.swift in Sources */, @@ -1266,6 +1273,7 @@ E88198631BEA9A5400333A11 /* RulesTests.swift in Sources */, D46202211E16002A0027AAD1 /* Swift2RulesTests.swift in Sources */, C9802F2F1E0C8AEE008AB27F /* TrailingCommaRuleTests.swift in Sources */, + 3B63D46F1E1F09DF0057BE35 /* LineLengthRuleTests.swift in Sources */, 3BCC04D41C502BAB006073C3 /* RuleConfigurationTests.swift in Sources */, E809EDA31B8A73FB00399043 /* ConfigurationTests.swift in Sources */, ); diff --git a/Tests/LinuxMain.swift b/Tests/LinuxMain.swift index 6e95bfc13..8b27867a6 100644 --- a/Tests/LinuxMain.swift +++ b/Tests/LinuxMain.swift @@ -18,6 +18,8 @@ XCTMain([ testCase(FileHeaderRuleTests.allTests), testCase(FunctionBodyLengthRuleTests.allTests), testCase(IntegrationTests.allTests), + testCase(LineLengthConfigurationTests), + testCase(LineLengthRuleTests), testCase(ReporterTests.allTests), testCase(RuleConfigurationsTests.allTests), testCase(RuleTests.allTests), diff --git a/Tests/SwiftLintFrameworkTests/LineLengthConfigurationTests.swift b/Tests/SwiftLintFrameworkTests/LineLengthConfigurationTests.swift new file mode 100644 index 000000000..84f621f63 --- /dev/null +++ b/Tests/SwiftLintFrameworkTests/LineLengthConfigurationTests.swift @@ -0,0 +1,154 @@ +// +// LineLengthConfigurationTests.swift +// SwiftLint +// +// Created by Javier Hernández on 05/01/17. +// Copyright © 2017 Realm. All rights reserved. +// + +import SourceKittenFramework +@testable import SwiftLintFramework +import XCTest + +class LineLengthConfigurationTests: XCTestCase { + + func testLineLengthConfigurationInitializerSetsLength() { + let warning = 100 + let error = 150 + let length1 = SeverityLevelsConfiguration(warning: warning, error: error) + let configuration1 = LineLengthConfiguration(warning: warning, error: error, ignoresURLs: true) + XCTAssertEqual(configuration1.length, length1) + + let length2 = SeverityLevelsConfiguration(warning: warning, error: nil) + let configuration2 = LineLengthConfiguration(warning: warning, error: nil, ignoresURLs: true) + XCTAssertEqual(configuration2.length, length2) + } + + func testLineLengthConfigurationInitialiserSetsIgnoresUrls() { + let configuration1 = LineLengthConfiguration(warning: 100, error: 150, ignoresURLs: true) + XCTAssertTrue(configuration1.ignoresURLs) + + let configuration2 = LineLengthConfiguration(warning: 100, error: 150, ignoresURLs: false) + XCTAssertFalse(configuration2.ignoresURLs) + } + + func testLineLengthConfigurationParams() { + let warning = 13 + let error = 10 + let configuration = LineLengthConfiguration(warning: warning, error: error, ignoresURLs: true) + let params = [RuleParameter(severity: .error, value: error), RuleParameter(severity: .warning, value: warning)] + XCTAssertEqual(configuration.params, params) + } + + func testLineLengthConfigurationPartialParams() { + let warning = 13 + let configuration = LineLengthConfiguration(warning: warning, error: nil, ignoresURLs: true) + XCTAssertEqual(configuration.params, [RuleParameter(severity: .warning, value: 13)]) + } + + func testLineLengthConfigurationThrowsOnBadConfig() { + let config = "unknown" + var configuration = LineLengthConfiguration(warning: 100, error: 150, ignoresURLs: true) + + checkError(ConfigurationError.unknownConfiguration) { + try configuration.applyConfiguration(config) + } + } + + func testLineLengthConfigurationApplyConfigurationWithArray() { + var configuration = LineLengthConfiguration(warning: 0, error: 0, ignoresURLs: false) + + let warning1 = 100 + let error1 = 100 + let length1 = SeverityLevelsConfiguration(warning: warning1, error: error1) + let config1 = [warning1, error1] + + let warning2 = 150 + let length2 = SeverityLevelsConfiguration(warning: warning2, error: nil) + let config2 = [warning2] + + do { + try configuration.applyConfiguration(config1) + XCTAssertEqual(configuration.length, length1) + + try configuration.applyConfiguration(config2) + XCTAssertEqual(configuration.length, length2) + } catch { + XCTFail() + } + } + + func testLineLengthConfigurationApplyConfigurationWithDictionary() { + var configuration = LineLengthConfiguration(warning: 0, error: 0, ignoresURLs: false) + + let warning1 = 100 + let error1 = 100 + let length1 = SeverityLevelsConfiguration(warning: warning1, error: error1) + let config1: [String: Any] = ["warning": warning1, "error": error1, "ignores_urls": true] + + let warning2 = 200 + let error2 = 200 + let length2 = SeverityLevelsConfiguration(warning: warning2, error: error2) + let config2: [String: Int] = ["warning": warning2, "error": error2] + + let length3 = SeverityLevelsConfiguration(warning: warning2, error: nil) + let config3: [String: Bool] = ["ignores_urls": false] + + do { + try configuration.applyConfiguration(config1) + XCTAssertEqual(configuration.length, length1) + XCTAssertTrue(configuration.ignoresURLs) + + try configuration.applyConfiguration(config2) + XCTAssertEqual(configuration.length, length2) + XCTAssertTrue(configuration.ignoresURLs) + + try configuration.applyConfiguration(config3) + XCTAssertEqual(configuration.length, length3) + XCTAssertFalse(configuration.ignoresURLs) + } catch { + XCTFail() + } + } + + func testLineLengthConfigurationCompares() { + let configuration1 = LineLengthConfiguration(warning: 100, error: 100, ignoresURLs: true) + let configuration2 = LineLengthConfiguration(warning: 100, error: 100, ignoresURLs: false) + XCTAssertFalse(configuration1 == configuration2) + + let configuration3 = LineLengthConfiguration(warning: 100, error: 200, ignoresURLs: true) + XCTAssertFalse(configuration1 == configuration3) + + let configuration4 = LineLengthConfiguration(warning: 200, error: 100, ignoresURLs: true) + XCTAssertFalse(configuration1 == configuration4) + + let configuration5 = LineLengthConfiguration(warning: 100, error: 100, ignoresURLs: true) + XCTAssertTrue(configuration1 == configuration5) + + let configuration6 = LineLengthConfiguration(warning: 100, error: 100, ignoresURLs: false) + XCTAssertTrue(configuration2 == configuration6) + } +} + +extension LineLengthConfigurationTests { + static var allTests: [(String, (LineLengthConfigurationTests) -> () throws -> Void)] { + return [ + ("testLineLengthConfigurationInitializerSetsLength", + testLineLengthConfigurationInitializerSetsLength), + ("testLineLengthConfigurationInitialiserSetsIgnoresUrls", + testLineLengthConfigurationInitialiserSetsIgnoresUrls), + ("testLineLengthConfigurationPartialParams", + testLineLengthConfigurationPartialParams), + ("testLineLengthConfigurationParams", + testLineLengthConfigurationParams), + ("testLineLengthConfigurationThrowsOnBadConfig", + testLineLengthConfigurationThrowsOnBadConfig), + ("testLineLengthConfigurationApplyConfigurationWithArray", + testLineLengthConfigurationApplyConfigurationWithArray), + ("testLineLengthConfigurationApplyConfigurationWithDictionary", + testLineLengthConfigurationApplyConfigurationWithDictionary), + ("testLineLengthConfigurationCompares", + testLineLengthConfigurationCompares) + ] + } +} diff --git a/Tests/SwiftLintFrameworkTests/LineLengthRuleTests.swift b/Tests/SwiftLintFrameworkTests/LineLengthRuleTests.swift new file mode 100644 index 000000000..2e34efe1d --- /dev/null +++ b/Tests/SwiftLintFrameworkTests/LineLengthRuleTests.swift @@ -0,0 +1,47 @@ +// +// LineLengthRuleTests.swift +// SwiftLint +// +// Created by Javier Hernández on 06/01/17. +// Copyright © 2017 Realm. All rights reserved. +// + +import SourceKittenFramework +@testable import SwiftLintFramework +import XCTest + +class LineLengthRuleTests: XCTestCase { + + func testLineLength() { + verifyRule(LineLengthRule.description, commentDoesntViolate: false, stringDoesntViolate: false) + } + + func testLineLengthWithIgnoreURLsEnabled() { + let url = "https://github.com/realm/SwiftLint" + let triggeringLines = [String(repeating: "/", count: 121) + "\(url)\n"] + let nonTriggeringLines = ["\(url) " + String(repeating: "/", count: 118) + " \(url)\n", + "\(url)/" + String(repeating: "a", count: 120)] + + let baseDescription = LineLengthRule.description + let nonTriggeringExamples = baseDescription.nonTriggeringExamples + nonTriggeringLines + let triggeringExamples = baseDescription.triggeringExamples + triggeringLines + let description = RuleDescription(identifier: baseDescription.identifier, + name: baseDescription.name, + description: baseDescription.description, + nonTriggeringExamples: nonTriggeringExamples, + triggeringExamples: triggeringExamples, + corrections: baseDescription.corrections) + + verifyRule(description, ruleConfiguration: ["ignores_urls": true], + commentDoesntViolate: false, stringDoesntViolate: false) + } +} + +extension LineLengthRuleTests { + static var allTests: [(String, (LineLengthRuleTests) -> () throws -> Void)] { + return [ + ("testLineLength", testLineLength), + ("testLineLengthWithIgnoreURLsEnabled", testLineLengthWithIgnoreURLsEnabled) + ] + } +} diff --git a/Tests/SwiftLintFrameworkTests/RuleConfigurationTests.swift b/Tests/SwiftLintFrameworkTests/RuleConfigurationTests.swift index 71c5dface..403c5bb00 100644 --- a/Tests/SwiftLintFrameworkTests/RuleConfigurationTests.swift +++ b/Tests/SwiftLintFrameworkTests/RuleConfigurationTests.swift @@ -10,127 +10,8 @@ import SourceKittenFramework @testable import SwiftLintFramework import XCTest -// swiftlint:disable file_length -// swiftlint:disable:next type_body_length class RuleConfigurationsTests: XCTestCase { - func testLineLengthConfigurationInitializerSetsLength() { - let warning = 100 - let error = 150 - let length1 = SeverityLevelsConfiguration(warning: warning, error: error) - let configuration1 = LineLengthConfiguration(warning: warning, error: error, ignoresURLs: true) - XCTAssertEqual(configuration1.length, length1) - - let length2 = SeverityLevelsConfiguration(warning: warning, error: nil) - let configuration2 = LineLengthConfiguration(warning: warning, error: nil, ignoresURLs: true) - XCTAssertEqual(configuration2.length, length2) - } - - func testLineLengthConfigurationInitialiserSetsIgnoresUrls() { - let configuration1 = LineLengthConfiguration(warning: 100, error: 150, ignoresURLs: true) - XCTAssertTrue(configuration1.ignoresURLs) - - let configuration2 = LineLengthConfiguration(warning: 100, error: 150, ignoresURLs: false) - XCTAssertFalse(configuration2.ignoresURLs) - } - - func testLineLengthConfigurationParams() { - let warning = 13 - let error = 10 - let configuration = LineLengthConfiguration(warning: warning, error: error, ignoresURLs: true) - let params = [RuleParameter(severity: .error, value: error), RuleParameter(severity: .warning, value: warning)] - XCTAssertEqual(configuration.params, params) - } - - func testLineLengthConfigurationPartialParams() { - let warning = 13 - let configuration = LineLengthConfiguration(warning: warning, error: nil, ignoresURLs: true) - XCTAssertEqual(configuration.params, [RuleParameter(severity: .warning, value: 13)]) - } - - func testLineLengthConfigurationThrowsOnBadConfig() { - let config = "unknown" - var configuration = LineLengthConfiguration(warning: 100, error: 150, ignoresURLs: true) - - checkError(ConfigurationError.unknownConfiguration) { - try configuration.applyConfiguration(config) - } - } - - func testLineLengthConfigurationApplyConfigurationWithArray() { - var configuration = LineLengthConfiguration(warning: 0, error: 0, ignoresURLs: false) - - let warning1 = 100 - let error1 = 100 - let length1 = SeverityLevelsConfiguration(warning: warning1, error: error1) - let config1 = [warning1, error1] - - let warning2 = 150 - let length2 = SeverityLevelsConfiguration(warning: warning2, error: nil) - let config2 = [warning2] - - do { - try configuration.applyConfiguration(config1) - XCTAssertEqual(configuration.length, length1) - - try configuration.applyConfiguration(config2) - XCTAssertEqual(configuration.length, length2) - } catch { - XCTFail() - } - } - - func testLineLengthConfigurationApplyConfigurationWithDictionary() { - var configuration = LineLengthConfiguration(warning: 0, error: 0, ignoresURLs: false) - - let warning1 = 100 - let error1 = 100 - let length1 = SeverityLevelsConfiguration(warning: warning1, error: error1) - let config1: [String: Any] = ["warning": warning1, "error": error1, "ignores_urls": true] - - let warning2 = 200 - let error2 = 200 - let length2 = SeverityLevelsConfiguration(warning: warning2, error: error2) - let config2: [String: Int] = ["warning": warning2, "error": error2] - - let length3 = SeverityLevelsConfiguration(warning: warning2, error: nil) - let config3: [String: Bool] = ["ignores_urls": false] - - do { - try configuration.applyConfiguration(config1) - XCTAssertEqual(configuration.length, length1) - XCTAssertTrue(configuration.ignoresURLs) - - try configuration.applyConfiguration(config2) - XCTAssertEqual(configuration.length, length2) - XCTAssertTrue(configuration.ignoresURLs) - - try configuration.applyConfiguration(config3) - XCTAssertEqual(configuration.length, length3) - XCTAssertFalse(configuration.ignoresURLs) - } catch { - XCTFail() - } - } - - func testLineLengthConfigurationCompares() { - let configuration1 = LineLengthConfiguration(warning: 100, error: 100, ignoresURLs: true) - let configuration2 = LineLengthConfiguration(warning: 100, error: 100, ignoresURLs: false) - XCTAssertFalse(configuration1 == configuration2) - - let configuration3 = LineLengthConfiguration(warning: 100, error: 200, ignoresURLs: true) - XCTAssertFalse(configuration1 == configuration3) - - let configuration4 = LineLengthConfiguration(warning: 200, error: 100, ignoresURLs: true) - XCTAssertFalse(configuration1 == configuration4) - - let configuration5 = LineLengthConfiguration(warning: 100, error: 100, ignoresURLs: true) - XCTAssertTrue(configuration1 == configuration5) - - let configuration6 = LineLengthConfiguration(warning: 100, error: 100, ignoresURLs: false) - XCTAssertTrue(configuration2 == configuration6) - } - func testNameConfigurationSetsCorrectly() { let config = [ "min_length": ["warning": 17, "error": 7], "max_length": ["warning": 170, "error": 700], @@ -398,22 +279,6 @@ class RuleConfigurationsTests: XCTestCase { extension RuleConfigurationsTests { static var allTests: [(String, (RuleConfigurationsTests) -> () throws -> Void)] { return [ - ("testLineLengthConfigurationInitializerSetsLength", - testLineLengthConfigurationParams), - ("testLineLengthConfigurationInitialiserSetsIgnoresUrls", - testLineLengthConfigurationInitialiserSetsIgnoresUrls), - ("testLineLengthConfigurationPartialParams", - testLineLengthConfigurationPartialParams), - ("testLineLengthConfigurationParams", - testLineLengthConfigurationParams), - ("testLineLengthConfigurationThrowsOnBadConfig", - testLineLengthConfigurationThrowsOnBadConfig), - ("testLineLengthConfigurationApplyConfigurationWithArray", - testLineLengthConfigurationApplyConfigurationWithArray), - ("testLineLengthConfigurationApplyConfigurationWithDictionary", - testLineLengthConfigurationApplyConfigurationWithDictionary), - ("testLineLengthConfigurationCompares", - testLineLengthConfigurationCompares), ("testNameConfigurationSetsCorrectly", testNameConfigurationSetsCorrectly), ("testNameConfigurationThrowsOnBadConfig", diff --git a/Tests/SwiftLintFrameworkTests/RulesTests.swift b/Tests/SwiftLintFrameworkTests/RulesTests.swift index 3ae2487c0..7b8c39ce8 100644 --- a/Tests/SwiftLintFrameworkTests/RulesTests.swift +++ b/Tests/SwiftLintFrameworkTests/RulesTests.swift @@ -10,7 +10,6 @@ import SwiftLintFramework import XCTest // swiftlint:disable file_length -// swiftlint:disable:next type_body_length class RulesTests: XCTestCase { func testClassDelegateProtocol() { @@ -134,29 +133,6 @@ class RulesTests: XCTestCase { verifyRule(LegacyConstructorRule.description) } - func testLineLength() { - verifyRule(LineLengthRule.description, commentDoesntViolate: false, stringDoesntViolate: false) - - // Perform additional tests with the ignores_urls settings enabled - let url = "https://github.com/realm/SwiftLint" - let triggeringLines = [String(repeating: "/", count: 121) + "\(url)\n"] - let nonTriggeringLines = ["\(url) " + String(repeating: "/", count: 118) + " \(url)\n", - "\(url)/" + String(repeating: "a", count: 120)] - - let baseDescription = LineLengthRule.description - let nonTriggeringExamples = baseDescription.nonTriggeringExamples + nonTriggeringLines - let triggeringExamples = baseDescription.triggeringExamples + triggeringLines - let description = RuleDescription(identifier: baseDescription.identifier, - name: baseDescription.name, - description: baseDescription.description, - nonTriggeringExamples: nonTriggeringExamples, - triggeringExamples: triggeringExamples, - corrections: baseDescription.corrections) - - verifyRule(description, ruleConfiguration: ["ignores_urls": true], - commentDoesntViolate: false, stringDoesntViolate: false) - } - func testMark() { verifyRule(MarkRule.description, commentDoesntViolate: false) } @@ -389,7 +365,6 @@ extension RulesTests { ("testLegacyNSGeometryFunctions", testLegacyNSGeometryFunctions), ("testLegacyConstant", testLegacyConstant), ("testLegacyConstructor", testLegacyConstructor), - ("testLineLength", testLineLength), ("testMark", testMark), ("testNesting", testNesting), ("testNimbleOperator", testNimbleOperator), From 5a3b910be25361b02879164114c2030e4fd69ea6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Hern=C3=A1ndez?= Date: Fri, 6 Jan 2017 11:54:40 +0100 Subject: [PATCH 8/8] Fix LinuxMain.swift --- Tests/LinuxMain.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tests/LinuxMain.swift b/Tests/LinuxMain.swift index 8b27867a6..f87c95114 100644 --- a/Tests/LinuxMain.swift +++ b/Tests/LinuxMain.swift @@ -18,8 +18,8 @@ XCTMain([ testCase(FileHeaderRuleTests.allTests), testCase(FunctionBodyLengthRuleTests.allTests), testCase(IntegrationTests.allTests), - testCase(LineLengthConfigurationTests), - testCase(LineLengthRuleTests), + testCase(LineLengthConfigurationTests.allTests), + testCase(LineLengthRuleTests.allTests), testCase(ReporterTests.allTests), testCase(RuleConfigurationsTests.allTests), testCase(RuleTests.allTests),