Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add prioritizeTodoOverMixedChinese option #10

Merged
merged 1 commit into from
Apr 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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