Files
SwiftLint/Tests/BuiltInRulesTests/ExpiringTodoRuleTests.swift

181 lines
7.2 KiB
Swift

@testable import SwiftLintBuiltInRules
import TestHelpers
import XCTest
final class ExpiringTodoRuleTests: SwiftLintTestCase {
func testExpiringTodo() {
verifyRule(ExpiringTodoRule.description, commentDoesntViolate: false)
}
func testExpiredTodo() {
let example = Example("fatalError() // TODO: [\(dateString(for: .expired))] Implement")
let violations = self.violations(example)
XCTAssertEqual(violations.count, 1)
XCTAssertEqual(violations.first!.reason, "TODO/FIXME has expired and must be resolved")
}
func testExpiredFixMe() {
let example = Example("fatalError() // FIXME: [\(dateString(for: .expired))] Implement")
let violations = self.violations(example)
XCTAssertEqual(violations.count, 1)
XCTAssertEqual(violations.first!.reason, "TODO/FIXME has expired and must be resolved")
}
func testApproachingExpiryTodo() {
let example = Example("fatalError() // TODO: [\(dateString(for: .approachingExpiry))] Implement")
let violations = self.violations(example)
XCTAssertEqual(violations.count, 1)
XCTAssertEqual(violations.first!.reason, "TODO/FIXME is approaching its expiry and should be resolved soon")
}
func testNonExpiredTodo() {
let example = Example("fatalError() // TODO: [\(dateString(for: .badFormatting))] Implement")
XCTAssertEqual(violations(example).count, 0)
}
func testExpiredCustomDelimiters() {
let ruleConfig = ExpiringTodoConfiguration(
dateDelimiters: .init(opening: "<", closing: ">")
)
let example = Example("fatalError() // TODO: <\(dateString(for: .expired))> Implement")
let violations = self.violations(example, ruleConfig)
XCTAssertEqual(violations.count, 1)
XCTAssertEqual(violations.first!.reason, "TODO/FIXME has expired and must be resolved")
}
func testExpiredCustomSeparator() {
let ruleConfig = ExpiringTodoConfiguration(
dateFormat: "MM-dd-yyyy",
dateSeparator: "-"
)
let example = Example(
"fatalError() // TODO: [\(dateString(for: .expired, format: ruleConfig.dateFormat))] Implement"
)
let violations = self.violations(example, ruleConfig)
XCTAssertEqual(violations.count, 1)
XCTAssertEqual(violations.first!.reason, "TODO/FIXME has expired and must be resolved")
}
func testExpiredCustomFormat() {
let ruleConfig = ExpiringTodoConfiguration(dateFormat: "yyyy/MM/dd")
let example = Example(
"fatalError() // TODO: [\(dateString(for: .expired, format: ruleConfig.dateFormat))] Implement"
)
let violations = self.violations(example, ruleConfig)
XCTAssertEqual(violations.count, 1)
XCTAssertEqual(violations.first!.reason, "TODO/FIXME has expired and must be resolved")
}
func testMultipleExpiredTodos() {
let example = Example(
"""
fatalError() // TODO: [\(dateString(for: .expired))] Implement one
fatalError() // TODO: Implement two by [\(dateString(for: .expired))]
"""
)
let violations = self.violations(example)
XCTAssertEqual(violations.count, 2)
XCTAssertEqual(violations[0].reason, "TODO/FIXME has expired and must be resolved")
XCTAssertEqual(violations[0].location.line, 1)
XCTAssertEqual(violations[1].reason, "TODO/FIXME has expired and must be resolved")
XCTAssertEqual(violations[1].location.line, 2)
}
func testTodoAndExpiredTodo() {
let example = Example(
"""
// TODO: Implement one - without deadline
fatalError()
// TODO: Implement two by [\(dateString(for: .expired))]
"""
)
let violations = self.violations(example)
XCTAssertEqual(violations.count, 1)
XCTAssertEqual(violations[0].reason, "TODO/FIXME has expired and must be resolved")
XCTAssertEqual(violations[0].location.line, 3)
}
func testMultilineExpiredTodo() {
let example = Example(
"""
// TODO: Multi-line task
// for: @MATODOLU
// deadline: [\(dateString(for: .expired))]
// severity: fatal
"""
)
let violations = self.violations(example)
XCTAssertEqual(violations.count, 1)
XCTAssertEqual(violations[0].reason, "TODO/FIXME has expired and must be resolved")
XCTAssertEqual(violations[0].location.line, 3)
}
func testTodoFunctionAndExpiredTodo() {
let example = Example(
"""
TODO()
// TODO: Implement two by [\(dateString(for: .expired))]
"""
)
let violations = self.violations(example)
XCTAssertEqual(violations.count, 1)
XCTAssertEqual(violations[0].reason, "TODO/FIXME has expired and must be resolved")
XCTAssertEqual(violations[0].location.line, 2)
}
func testBadExpiryTodoFormat() throws {
let ruleConfig = ExpiringTodoConfiguration(
dateFormat: "dd/yyyy/MM"
)
let example = Example("fatalError() // TODO: [31/01/2020] Implement")
let violations = self.violations(example, ruleConfig)
XCTAssertEqual(violations.count, 1)
XCTAssertEqual(violations.first?.reason, "Expiring TODO/FIXME is incorrectly formatted")
}
private func violations(_ example: Example, _ config: ExpiringTodoConfiguration? = nil) -> [StyleViolation] {
let config = config ?? ExpiringTodoConfiguration()
let serializedConfig = [
"expired_severity": config.expiredSeverity.severity.rawValue,
"approaching_expiry_severity": config.approachingExpirySeverity.severity.rawValue,
"bad_formatting_severity": config.badFormattingSeverity.severity.rawValue,
"approaching_expiry_threshold": config.approachingExpiryThreshold,
"date_format": config.dateFormat,
"date_delimiters": [
"opening": config.dateDelimiters.opening,
"closing": config.dateDelimiters.closing,
],
"date_separator": config.dateSeparator,
] as [String: Any]
return TestHelpers.violations(example, config: makeConfig(serializedConfig, ExpiringTodoRule.identifier)!)
}
private func dateString(for status: ExpiringTodoRule.ExpiryViolationLevel, format: String? = nil) -> String {
let formatter = DateFormatter()
formatter.dateFormat = format ?? ExpiringTodoConfiguration().dateFormat
return formatter.string(from: date(for: status))
}
private func date(for status: ExpiringTodoRule.ExpiryViolationLevel) -> Date {
let ruleConfiguration = ExpiringTodoRule().configuration
let daysToAdvance: Int
switch status {
case .approachingExpiry:
daysToAdvance = ruleConfiguration.approachingExpiryThreshold
case .expired:
daysToAdvance = 0
case .badFormatting:
daysToAdvance = ruleConfiguration.approachingExpiryThreshold + 1
}
return Calendar.current
.date(
byAdding: .day,
value: daysToAdvance,
to: .init()
)!
}
}