Skip to content

Commit

Permalink
Add only_after_dot configuration option to empty_count rule
Browse files Browse the repository at this point in the history
  • Loading branch information
lordzsolt committed Feb 3, 2020
1 parent be44017 commit 7dd18b9
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 12 deletions.
17 changes: 12 additions & 5 deletions Source/SwiftLintFramework/Rules/Performance/EmptyCountRule.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import SourceKittenFramework

public struct EmptyCountRule: ConfigurationProviderRule, OptInRule, AutomaticTestableRule {
public var configuration = SeverityConfiguration(.error)
public struct EmptyCountRule: ConfigurationProviderRule, OptInRule {
public var configuration = EmptyCountConfiguration()

public init() {}

Expand Down Expand Up @@ -34,12 +34,19 @@ public struct EmptyCountRule: ConfigurationProviderRule, OptInRule, AutomaticTes
)

public func validate(file: SwiftLintFile) -> [StyleViolation] {
let pattern = "\\bcount\\s*(==|!=|<|<=|>|>=)\\s*0(\\b|([box][0_]+\\b){1})"
let defaultPattern = #"\bcount\s*(==|!=|<|<=|>|>=)\s*0(\b|([box][0_]+\b){1})"#
let prefixPattern = configuration.onlyAfterDot ? #"\."# : ""
let pattern = prefixPattern + defaultPattern

// Offset the violation location in case `only_after_dot` is turned on,
// to compensate for the pattern matching the dot
let offset = configuration.onlyAfterDot ? 1 : 0

let excludingKinds = SyntaxKind.commentAndStringKinds
return file.match(pattern: pattern, excludingSyntaxKinds: excludingKinds).map {
StyleViolation(ruleDescription: type(of: self).description,
severity: configuration.severity,
location: Location(file: file, characterOffset: $0.location))
severity: configuration.severityConfiguration.severity,
location: Location(file: file, characterOffset: $0.location + offset))
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
private enum ConfigurationKey: String {
case severity = "severity"
case onlyAfterDot = "only_after_dot"
}

public struct EmptyCountConfiguration: RuleConfiguration, Equatable {
private(set) var severityConfiguration = SeverityConfiguration(.warning)
private(set) var onlyAfterDot: Bool = false

public var consoleDescription: String {
return [severityConfiguration.consoleDescription,
"\(ConfigurationKey.onlyAfterDot.rawValue): \(onlyAfterDot)"].joined(separator: ", ")
}

public mutating func apply(configuration: Any) throws {
guard let configuration = configuration as? [String: Any] else {
throw ConfigurationError.unknownConfiguration
}

if let severityString = configuration[ConfigurationKey.severity.rawValue] as? String {
try severityConfiguration.apply(configuration: severityString)
}

onlyAfterDot = configuration[ConfigurationKey.onlyAfterDot.rawValue] as? Bool ?? false
}
}
8 changes: 8 additions & 0 deletions SwiftLint.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@
67EB4DFA1E4CC111004E9ACD /* CyclomaticComplexityConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67EB4DF81E4CC101004E9ACD /* CyclomaticComplexityConfiguration.swift */; };
67EB4DFC1E4CD7F5004E9ACD /* CyclomaticComplexityRuleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67EB4DFB1E4CD7F5004E9ACD /* CyclomaticComplexityRuleTests.swift */; };
69F88BF71BDA38A6005E7CAE /* OpeningBraceRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 692B1EB11BD7E00F00EAABFF /* OpeningBraceRule.swift */; };
6A804EF323D8F6CF00976471 /* EmptyCountConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A804EF023D8F6A200976471 /* EmptyCountConfiguration.swift */; };
6A804EF623D8FB0D00976471 /* EmptyCountRuleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A804EF423D8FA7900976471 /* EmptyCountRuleTests.swift */; };
6BE79EB12204EC0700B5A2FE /* RequiredDeinitRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BE79EB02204EC0700B5A2FE /* RequiredDeinitRule.swift */; };
6C15818D237026AC00F582A2 /* GitHubActionsLoggingReporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C15818C237026AC00F582A2 /* GitHubActionsLoggingReporter.swift */; };
6C15818F23702DCE00F582A2 /* CannedGitHubActionsLoggingReporterOutput.txt in Resources */ = {isa = PBXBuildFile; fileRef = 6C15818E23702DCE00F582A2 /* CannedGitHubActionsLoggingReporterOutput.txt */; };
Expand Down Expand Up @@ -649,6 +651,8 @@
692B1EB11BD7E00F00EAABFF /* OpeningBraceRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OpeningBraceRule.swift; sourceTree = "<group>"; };
692B60AB1BD8F2E700C7AA22 /* StatementPositionRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StatementPositionRule.swift; sourceTree = "<group>"; };
695BE9CE1BDFD92B0071E985 /* CommaRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CommaRule.swift; sourceTree = "<group>"; };
6A804EF023D8F6A200976471 /* EmptyCountConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmptyCountConfiguration.swift; sourceTree = "<group>"; };
6A804EF423D8FA7900976471 /* EmptyCountRuleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmptyCountRuleTests.swift; sourceTree = "<group>"; };
6BE79EB02204EC0700B5A2FE /* RequiredDeinitRule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RequiredDeinitRule.swift; sourceTree = "<group>"; };
6C15818C237026AC00F582A2 /* GitHubActionsLoggingReporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GitHubActionsLoggingReporter.swift; sourceTree = "<group>"; };
6C15818E23702DCE00F582A2 /* CannedGitHubActionsLoggingReporterOutput.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CannedGitHubActionsLoggingReporterOutput.txt; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1054,6 +1058,7 @@
67EB4DF81E4CC101004E9ACD /* CyclomaticComplexityConfiguration.swift */,
62A498551F306A7700D766E4 /* DiscouragedDirectInitConfiguration.swift */,
D41985EA21FAB63E003BE2B7 /* DeploymentTargetConfiguration.swift */,
6A804EF023D8F6A200976471 /* EmptyCountConfiguration.swift */,
125AAC77203AA82D0004BCE0 /* ExplicitTypeInterfaceConfiguration.swift */,
D4C4A3511DEFBBB700E0E04C /* FileHeaderConfiguration.swift */,
29FFC3781F1574FD007E4825 /* FileLengthRuleConfiguration.swift */,
Expand Down Expand Up @@ -1545,6 +1550,7 @@
125CE52E20425EFD001635E5 /* ExplicitTypeInterfaceConfigurationTests.swift */,
12E3D4DB2042729300B3E30E /* ExplicitTypeInterfaceRuleTests.swift */,
02FD8AEE1BFC18D60014BFFB /* ExtendedNSStringTests.swift */,
6A804EF423D8FA7900976471 /* EmptyCountRuleTests.swift */,
D4998DE81DF194F20006E05D /* FileHeaderRuleTests.swift */,
29FFC37B1F157BA8007E4825 /* FileLengthRuleTests.swift */,
4100D7A123BEAB5A009464E0 /* FileNameNoSpaceRuleTests.swift */,
Expand Down Expand Up @@ -2022,6 +2028,7 @@
827169B51F48D712003FB9AF /* NoGroupingExtensionRule.swift in Sources */,
D41B57781ED8CEE0007B0470 /* ExtensionAccessModifierRule.swift in Sources */,
E881985C1BEA978500333A11 /* TrailingNewlineRule.swift in Sources */,
6A804EF323D8F6CF00976471 /* EmptyCountConfiguration.swift in Sources */,
D414D6AE21D22FF500960935 /* LastWhereRule.swift in Sources */,
D4EABD0C22CE6F5B00635667 /* VerticalParameterAlignmentRuleExamples.swift in Sources */,
D44037972132730000FDA77B /* ProhibitedInterfaceBuilderRule.swift in Sources */,
Expand Down Expand Up @@ -2400,6 +2407,7 @@
E86396C71BADAFE6002C9E88 /* ReporterTests.swift in Sources */,
BCB68283216213130078E4C3 /* CompilerProtocolInitRuleTests.swift in Sources */,
D43B04661E071ED3004016AF /* ColonRuleTests.swift in Sources */,
6A804EF623D8FB0D00976471 /* EmptyCountRuleTests.swift in Sources */,
D4F5851920E99B5A0085C6D8 /* PrivateOutletRuleTests.swift in Sources */,
3B12C9C71C3361CB000B423F /* RuleTests.swift in Sources */,
125CE52F20425EFD001635E5 /* ExplicitTypeInterfaceConfigurationTests.swift in Sources */,
Expand Down
3 changes: 2 additions & 1 deletion Tests/LinuxMain.swift
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,8 @@ extension EmptyCollectionLiteralRuleTests {

extension EmptyCountRuleTests {
static var allTests: [(String, (EmptyCountRuleTests) -> () throws -> Void)] = [
("testWithDefaultConfiguration", testWithDefaultConfiguration)
("testEmptyCountWithDefaultConfiguration", testEmptyCountWithDefaultConfiguration),
("testEmptyCountWithOnlyAfterDot", testEmptyCountWithOnlyAfterDot)
]
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,12 +138,6 @@ class EmptyCollectionLiteralRuleTests: XCTestCase {
}
}

class EmptyCountRuleTests: XCTestCase {
func testWithDefaultConfiguration() {
verifyRule(EmptyCountRule.description)
}
}

class EmptyEnumArgumentsRuleTests: XCTestCase {
func testWithDefaultConfiguration() {
verifyRule(EmptyEnumArgumentsRule.description)
Expand Down
40 changes: 40 additions & 0 deletions Tests/SwiftLintFrameworkTests/EmptyCountRuleTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
@testable import SwiftLintFramework
import XCTest

class EmptyCountRuleTests: XCTestCase {
func testEmptyCountWithDefaultConfiguration() {
// Test with default parameters
verifyRule(EmptyCountRule.description)
}

func testEmptyCountWithOnlyAfterDot() {
// Test with `only_after_dot` set to true
let nonTriggeringExamples = [
"var count = 0\n",
"[Int]().isEmpty\n",
"[Int]().count > 1\n",
"[Int]().count == 1\n",
"[Int]().count == 0xff\n",
"[Int]().count == 0b01\n",
"[Int]().count == 0o07\n",
"discount == 0\n",
"order.discount == 0\n",
"count == 0\n"
]
let triggeringExamples = [
"[Int]().↓count == 0\n",
"[Int]().↓count > 0\n",
"[Int]().↓count != 0\n",
"[Int]().↓count == 0x0\n",
"[Int]().↓count == 0x00_00\n",
"[Int]().↓count == 0b00\n",
"[Int]().↓count == 0o00\n"
]

let description = EmptyCountRule.description
.with(triggeringExamples: triggeringExamples)
.with(nonTriggeringExamples: nonTriggeringExamples)

verifyRule(description, ruleConfiguration: ["only_after_dot": true])
}
}

0 comments on commit 7dd18b9

Please sign in to comment.