Add ability to run only one(focused) example (#3911)
* Add ability to focus on a specific test example * Update CHANGELOG.md Co-authored-by: JP Simard <jp@jpsim.com> * Update CONTRIBUTING.md Co-authored-by: JP Simard <jp@jpsim.com> Co-authored-by: JP Simard <jp@jpsim.com>
This commit is contained in:
parent
702b36a781
commit
1616023b63
|
@ -48,6 +48,10 @@
|
|||
environments, such as in Swift Package Manager plugins.
|
||||
[Juozas Valancius](https://github.com/juozasvalancius)
|
||||
|
||||
* Add ability to run only one (focused) example.
|
||||
[PaulTaykalo](https://github.com/PaulTaykalo)
|
||||
[#3911](https://github.com/realm/SwiftLint/issues/3911)
|
||||
|
||||
#### Bug Fixes
|
||||
|
||||
* Extend `class_delegate_protocol` to correctly identify cases with the protocol
|
||||
|
|
|
@ -72,6 +72,19 @@ over time. This way adding a unit test for your new Rule is just a matter of
|
|||
adding a test case in `RulesTests.swift` which simply calls
|
||||
`verifyRule(YourNewRule.description)`.
|
||||
|
||||
For debugging purposes examples can be marked as `focused`. If there are any
|
||||
focused examples found, then only those will be run when running tests for that rule.
|
||||
```
|
||||
nonTriggeringExamples: [
|
||||
Example("let x: [Int]"),
|
||||
Example("let x: [Int: String]").focused() // only this one will be run in tests
|
||||
],
|
||||
triggeringExamples: [
|
||||
Example("let x: ↓Array<String>"),
|
||||
Example("let x: ↓Dictionary<Int, String>")
|
||||
]
|
||||
```
|
||||
|
||||
### `ConfigurationProviderRule`
|
||||
|
||||
If your rule supports user-configurable options via `.swiftlint.yml`, you can
|
||||
|
|
|
@ -32,6 +32,9 @@ public struct Example {
|
|||
/// pathological use cases which are indeed important to test but not helpful for understanding can be
|
||||
/// hidden from the documentation with this option.
|
||||
let excludeFromDocumentation: Bool
|
||||
|
||||
/// Specifies whether the test example should be the only example run during the current test case execution.
|
||||
var isFocused: Bool
|
||||
}
|
||||
|
||||
public extension Example {
|
||||
|
@ -55,6 +58,7 @@ public extension Example {
|
|||
self.file = file
|
||||
self.line = line
|
||||
self.excludeFromDocumentation = excludeFromDocumentation
|
||||
self.isFocused = false
|
||||
}
|
||||
|
||||
/// Returns the same example, but with the `code` that is passed in
|
||||
|
@ -69,6 +73,13 @@ public extension Example {
|
|||
func removingViolationMarkers() -> Example {
|
||||
return with(code: code.replacingOccurrences(of: "↓", with: ""))
|
||||
}
|
||||
|
||||
/// Makes the current example focused.
|
||||
func focused() -> Example {
|
||||
var new = self
|
||||
new.isFocused = true
|
||||
return new
|
||||
}
|
||||
}
|
||||
|
||||
extension Example: Hashable {
|
||||
|
|
|
@ -356,7 +356,11 @@ extension XCTestCase {
|
|||
requiresFileOnDisk: ruleDescription.requiresFileOnDisk,
|
||||
file: file, line: line)
|
||||
}
|
||||
func makeViolations(_ example: Example) -> [StyleViolation] {
|
||||
return violations(example, config: config, requiresFileOnDisk: ruleDescription.requiresFileOnDisk)
|
||||
}
|
||||
|
||||
let ruleDescription = ruleDescription.focused()
|
||||
let triggers = ruleDescription.triggeringExamples
|
||||
let nonTriggers = ruleDescription.nonTriggeringExamples
|
||||
verify(triggers: triggers, nonTriggers: nonTriggers)
|
||||
|
@ -369,10 +373,6 @@ extension XCTestCase {
|
|||
verify(triggers: triggers.map(addShebang), nonTriggers: nonTriggers.map(addShebang))
|
||||
}
|
||||
|
||||
func makeViolations(_ example: Example) -> [StyleViolation] {
|
||||
return violations(example, config: config, requiresFileOnDisk: ruleDescription.requiresFileOnDisk)
|
||||
}
|
||||
|
||||
// Comment doesn't violate
|
||||
if !skipCommentTests {
|
||||
XCTAssertEqual(
|
||||
|
@ -401,6 +401,8 @@ extension XCTestCase {
|
|||
|
||||
func verifyCorrections(_ ruleDescription: RuleDescription, config: Configuration,
|
||||
disableCommands: [String], testMultiByteOffsets: Bool) {
|
||||
let ruleDescription = ruleDescription.focused()
|
||||
|
||||
parserDiagnosticsDisabledForTests = true
|
||||
|
||||
// corrections
|
||||
|
@ -509,3 +511,37 @@ extension XCTestCase {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private struct FocusedRuleDescription {
|
||||
let nonTriggeringExamples: [Example]
|
||||
let triggeringExamples: [Example]
|
||||
let corrections: [Example: Example]
|
||||
|
||||
init(rule: RuleDescription) {
|
||||
let nonTriggering = rule.nonTriggeringExamples.filter(\.isFocused)
|
||||
let triggering = rule.triggeringExamples.filter(\.isFocused)
|
||||
let corrections = rule.corrections.filter { _, value in value.isFocused }
|
||||
let anyFocused = nonTriggering.isNotEmpty || triggering.isNotEmpty || corrections.isNotEmpty
|
||||
|
||||
if anyFocused {
|
||||
self.nonTriggeringExamples = nonTriggering
|
||||
self.triggeringExamples = triggering
|
||||
self.corrections = corrections
|
||||
#if DISABLE_FOCUSED_EXAMPLES
|
||||
(nonTriggering + triggering + corrections.values).forEach { example in
|
||||
XCTFail("Focused examples are disabled", file: example.file, line: example.line)
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
self.nonTriggeringExamples = rule.nonTriggeringExamples
|
||||
self.triggeringExamples = rule.triggeringExamples
|
||||
self.corrections = rule.corrections
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private extension RuleDescription {
|
||||
func focused() -> FocusedRuleDescription {
|
||||
return FocusedRuleDescription(rule: self)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ jobs:
|
|||
containerImage: swift:5.6
|
||||
container: $[ variables['containerImage'] ]
|
||||
steps:
|
||||
- script: swift test --parallel
|
||||
- script: swift test --parallel -Xswiftc -DDISABLE_FOCUSED_EXAMPLES
|
||||
displayName: swift test
|
||||
|
||||
- job: Xcode
|
||||
|
@ -32,7 +32,7 @@ jobs:
|
|||
sw_vers
|
||||
xcodebuild -version
|
||||
displayName: Version Informations
|
||||
- script: xcodebuild -scheme swiftlint test -destination "platform=macOS"
|
||||
- script: xcodebuild -scheme swiftlint test -destination "platform=macOS" OTHER_SWIFT_FLAGS="-D DISABLE_FOCUSED_EXAMPLES"
|
||||
displayName: xcodebuild test
|
||||
|
||||
- job: SwiftPM
|
||||
|
@ -50,7 +50,7 @@ jobs:
|
|||
sw_vers
|
||||
xcodebuild -version
|
||||
displayName: Version Informations
|
||||
- script: swift test --parallel --enable-code-coverage
|
||||
- script: swift test --parallel --enable-code-coverage -Xswiftc -DDISABLE_FOCUSED_EXAMPLES
|
||||
displayName: swift test
|
||||
- script: |
|
||||
xcrun llvm-cov export -format="lcov" .build/debug/SwiftLintPackageTests.xctest/Contents/MacOS/SwiftLintPackageTests -instr-profile .build/debug/codecov/default.profdata > coverage.lcov
|
||||
|
|
Loading…
Reference in New Issue