Skip to content

Commit

Permalink
Merge pull request #10 from s2mr/prioritizeTodoOverMixedChinese
Browse files Browse the repository at this point in the history
Add `prioritizeTodoOverMixedChinese` option
  • Loading branch information
s2mr authored Apr 4, 2023
2 parents a7c9e0b + 2a5eee4 commit 436f77a
Show file tree
Hide file tree
Showing 11 changed files with 118 additions and 7 deletions.
7 changes: 6 additions & 1 deletion Sources/L10nLintFramework/Models/Configuration.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Foundation
import Yams

public struct Configuration {
public struct Configuration: Equatable {
public static func load(customPath path: String?) throws -> Configuration {
let configPath = path ?? Self.defaultFileName
let configURL = URL(fileURLWithPath: configPath)
Expand All @@ -25,6 +25,9 @@ public struct Configuration {

public var enabledRules: [String]? = []

/// When `todo` and `mixed_chinese` violations occur at the same time, priority is given to `todo`.
public var prioritizeTodoOverMixedChinese: Bool = false

public var ruleConfigurations: RuleConfigurations = .init()
}

Expand All @@ -34,6 +37,7 @@ extension Configuration: Decodable {
case basePath = "base_path"
case disabledRules = "disabled_rules"
case enabledRules = "enabled_rules"
case prioritizeTodoOverMixedChinese = "prioritize_todo_over_mixed_chinese"
}

public init(from decoder: Decoder) throws {
Expand All @@ -42,6 +46,7 @@ extension Configuration: Decodable {
self.basePath = try container.decode(String.self, forKey: .basePath)
self.disabledRules = try container.decodeIfPresent([String].self, forKey: .disabledRules)
self.enabledRules = try container.decodeIfPresent([String].self, forKey: .enabledRules)
self.prioritizeTodoOverMixedChinese = try container.decodeIfPresent(Bool.self, forKey: .prioritizeTodoOverMixedChinese) ?? false

self.ruleConfigurations = try RuleConfigurations(from: decoder)
}
Expand Down
13 changes: 12 additions & 1 deletion Sources/L10nLintFramework/Models/LintRunner.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,19 @@ public final class LintRunner {
return Linter(baseProject: baseProject, project: project, rules: rules)
}

return try linters.flatMap {
let violations = try linters.flatMap {
try $0.lint()
}

guard configuration.prioritizeTodoOverMixedChinese else { return violations }
let todoViolations = violations.filter { $0.ruleIdentifier == TodoRule.description.identifier }

return violations.filter { violation in
guard violation.ruleIdentifier == MixedChineseRule.description.identifier else { return true }

return !todoViolations.contains(where: { todoViolation in
violation.location.file == todoViolation.location.file && violation.location.line == todoViolation.location.line
})
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Yams

public struct RuleConfigurations {
public struct RuleConfigurations: Equatable {
public var todo: TodoRuleConfiguration?
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
public struct TodoRuleConfiguration: Codable, RuleConfigurationProtocol {
public struct TodoRuleConfiguration: Equatable, Codable, RuleConfigurationProtocol {
public enum DefaultValue {
public static let isSummaryEnabled: Bool = false
public static let summaryViolationLimit: Int = 10
Expand Down
20 changes: 20 additions & 0 deletions Tests/L10nLintFrameworkTests/ConfigurationTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import XCTest
@testable import L10nLintFramework

final class ConfigurationTests: XCTestCase {
func testLoad1() throws {
XCTAssertEqual(
try Configuration.load(at: TestHelper.fixtureURL(fixtureName: "config1.yml")),
Configuration(
basePath: "Tests/L10nLintFrameworkTests/Resources/Fixtures/Localizables4",
reporter: nil,
disabledRules: Optional(["empty_value"]),
enabledRules: nil,
prioritizeTodoOverMixedChinese: true,
ruleConfigurations: RuleConfigurations(
todo: .init(isSummaryEnabled: true, summaryViolationLimit: 20)
)
)
)
}
}
52 changes: 52 additions & 0 deletions Tests/L10nLintFrameworkTests/LintRunnerTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import XCTest
@testable import L10nLintFramework

final class LintRunnerTests: XCTestCase {
func testPreferFixMeThanMixedChineseFalse() throws {
let violations = try LintRunner.run(configuration: Configuration(
basePath: TestHelper.fixtureURL(fixtureName: "Localizables7").path,
prioritizeTodoOverMixedChinese: false
))
XCTAssertEqual(violations.map(\.ruleWithLocationPoint), [
RuleWithLocationPoint(ruleIdentifier: "todo", file: "zh-Hans.lproj", line: 2, character: 1),
RuleWithLocationPoint(ruleIdentifier: "mixed_chinese", file: "zh-Hans.lproj", line: 2, character: 19),
RuleWithLocationPoint(ruleIdentifier: "mixed_chinese", file: "zh-Hans.lproj", line: 3, character: 12),
RuleWithLocationPoint(ruleIdentifier: "todo", file: "zh-Hant.lproj", line: 2, character: 1)
])
}

func testPreferFixMeThanMixedChineseTrue() throws {
let violations = try LintRunner.run(configuration: Configuration(
basePath: TestHelper.fixtureURL(fixtureName: "Localizables7").path,
prioritizeTodoOverMixedChinese: true
))
XCTAssertEqual(violations.map(\.ruleWithLocationPoint), [
RuleWithLocationPoint(ruleIdentifier: "todo", file: "zh-Hans.lproj", line: 2, character: 1),
RuleWithLocationPoint(ruleIdentifier: "mixed_chinese", file: "zh-Hans.lproj", line: 3, character: 12),
RuleWithLocationPoint(ruleIdentifier: "todo", file: "zh-Hant.lproj", line: 2, character: 1)
])
}
}

private struct RuleWithLocationPoint: Equatable, CustomStringConvertible {
var ruleIdentifier: String
var file: String?
var line: Int?
var character: Int?

var description: String {
"RuleWithLocationPoint(ruleIdentifier: \"\(ruleIdentifier)\", file: \"\(file ?? "nil")\", line: \(line ?? -1), character: \(character ?? -1))"
}
}

private extension StyleViolation {
var ruleWithLocationPoint: RuleWithLocationPoint {
let components = location.file!.components(separatedBy: "/")
return RuleWithLocationPoint(
ruleIdentifier: ruleIdentifier,
file: components[components.count - 2],
line: location.line,
character: location.character
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// MARK: LintRunner
"Key1" = "Value1";
"Key2" = "Value2";
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// MARK: LintRunner
"Key1" = "FIXME: 時間";
"Key2" = "時間";
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// MARK: LintRunner
"Key1" = "FIXME: 時間";
"Key2" = "時間";
9 changes: 9 additions & 0 deletions Tests/L10nLintFrameworkTests/Resources/Fixtures/config1.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
base_path: Tests/L10nLintFrameworkTests/Resources/Fixtures/Localizables4
prioritize_todo_over_mixed_chinese: true

disabled_rules:
- empty_value

todo:
is_summary_enabled: true
summary_violation_limit: 20
11 changes: 8 additions & 3 deletions Tests/L10nLintFrameworkTests/TestHelper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@ import Foundation
import L10nLintFramework

final class TestHelper {
static func localizedProjects(fixtureName: String) throws -> [LocalizedProject] {
static func fixtureURL(fixtureName: String) -> URL {
let currentDirectory = URL(string: #file)!.deletingLastPathComponent()
let url = URL(string: "\(currentDirectory.path)/Resources/Fixtures/\(fixtureName)")!
return try LocalizedProjectFactory.localizedProjects(baseDirectory: url)
return URL(string: "file://\(currentDirectory.path)/Resources/Fixtures/\(fixtureName)")!
}

static func localizedProjects(fixtureName: String) throws -> [LocalizedProject] {
return try LocalizedProjectFactory.localizedProjects(
baseDirectory: fixtureURL(fixtureName: fixtureName)
)
}

static func baseProject(fixtureName: String) throws -> LocalizedProject {
Expand Down

0 comments on commit 436f77a

Please sign in to comment.