Skip to content

Commit

Permalink
Add ability to focus on a specific test example
Browse files Browse the repository at this point in the history
  • Loading branch information
PaulTaykalo committed Mar 20, 2022
1 parent 702b36a commit 937f31f
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 7 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
13 changes: 13 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
```
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
Expand Down
11 changes: 11 additions & 0 deletions Source/SwiftLintFramework/Models/Example.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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
Expand All @@ -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 {
Expand Down
44 changes: 40 additions & 4 deletions Tests/SwiftLintFrameworkTests/TestHelpers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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(
Expand Down Expand Up @@ -401,6 +401,8 @@ extension XCTestCase {

func verifyCorrections(_ ruleDescription: RuleDescription, config: Configuration,
disableCommands: [String], testMultiByteOffsets: Bool) {
let ruleDescription = ruleDescription.focused()

parserDiagnosticsDisabledForTests = true

// corrections
Expand Down Expand Up @@ -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)
}
}
6 changes: 3 additions & 3 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down

0 comments on commit 937f31f

Please sign in to comment.