Skip to content

Commit

Permalink
Fix false positive in nimble_operator rule
Browse files Browse the repository at this point in the history
  • Loading branch information
marcelofabri authored and sjavora committed Mar 9, 2019
1 parent 79c1be0 commit eda9efe
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 22 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@

#### Bug Fixes

* None.
* Fix false positive in `nimble_operator` rule.
[Marcelo Fabri](https://github.com/marcelofabri)
[#2489](https://github.com/realm/SwiftLint/issues/2489)

## 0.29.0: A Laundry List of Changes

Expand Down
12 changes: 12 additions & 0 deletions Rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -11925,6 +11925,13 @@ expect(actual).to(haveCount(expected))
```
```swift
foo.method {
expect(value).to(equal(expectedValue), description: "Failed")
return Bar(value: ())
}
```
</details>
<details>
<summary>Triggering Examples</summary>
Expand All @@ -11944,6 +11951,11 @@ expect(actual).to(haveCount(expected))
```
```swift
↓expect(10, line: 1).to(equal(10))
```
```swift
↓expect(10).to(beGreaterThan(8))
Expand Down
17 changes: 17 additions & 0 deletions Source/SwiftLintFramework/Extensions/Structure+SwiftLint.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,21 @@ extension Structure {
parse(dictionary)
return results
}

internal func structures(forByteOffset byteOffset: Int) -> [[String: SourceKitRepresentable]] {
var results = [[String: SourceKitRepresentable]]()

func parse(_ dictionary: [String: SourceKitRepresentable]) {
guard let offset = dictionary.offset,
let byteRange = dictionary.length.map({ NSRange(location: offset, length: $0) }),
NSLocationInRange(byteOffset, byteRange) else {
return
}

results.append(dictionary)
dictionary.substructure.forEach(parse)
}
parse(dictionary)
return results
}
}
25 changes: 23 additions & 2 deletions Source/SwiftLintFramework/Rules/Idiomatic/NimbleOperatorRule.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,19 @@ public struct NimbleOperatorRule: ConfigurationProviderRule, OptInRule, Correcta
"expect(x) === x",
"expect(10) == 10",
"expect(object.asyncFunction()).toEventually(equal(1))\n",
"expect(actual).to(haveCount(expected))\n"
"expect(actual).to(haveCount(expected))\n",
"""
foo.method {
expect(value).to(equal(expectedValue), description: "Failed")
return Bar(value: ())
}
"""
],
triggeringExamples: [
"↓expect(seagull.squawk).toNot(equal(\"Hi\"))\n",
"↓expect(12).toNot(equal(10))\n",
"↓expect(10).to(equal(10))\n",
"↓expect(10, line: 1).to(equal(10))\n",
"↓expect(10).to(beGreaterThan(8))\n",
"↓expect(10).to(beGreaterThanOrEqualTo(10))\n",
"↓expect(10).to(beLessThan(11))\n",
Expand All @@ -53,7 +60,7 @@ public struct NimbleOperatorRule: ConfigurationProviderRule, OptInRule, Correcta
fileprivate typealias Operators = (to: String?, toNot: String?)
fileprivate typealias MatcherFunction = String

fileprivate let operatorsMapping: [MatcherFunction: Operators] = [
private let operatorsMapping: [MatcherFunction: Operators] = [
"equal": (to: "==", toNot: "!="),
"beIdenticalTo": (to: "===", toNot: "!=="),
"beGreaterThan": (to: ">", toNot: nil),
Expand Down Expand Up @@ -84,6 +91,20 @@ public struct NimbleOperatorRule: ConfigurationProviderRule, OptInRule, Correcta
.filter { _, kinds in
kinds.filter(excludingKinds.contains).isEmpty && kinds.first == .identifier
}.map { $0.0 }
.filter { range in
let contents = file.contents.bridge()
guard let byteRange = contents.NSRangeToByteRange(start: range.location, length: range.length) else {
return false
}

let containsCall = file.structure.structures(forByteOffset: byteRange.upperBound - 1)
.contains(where: { dict -> Bool in
return dict.kind.flatMap(SwiftExpressionKind.init) == .call &&
(dict.name ?? "").starts(with: "expect")
})

return containsCall
}
}

public func correct(file: File) -> [Correction] {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,22 +87,3 @@ public struct UnneededBreakInSwitchRule: ConfigurationProviderRule, AutomaticTes
return patternEnds.max()
}
}

private extension Structure {
func structures(forByteOffset byteOffset: Int) -> [[String: SourceKitRepresentable]] {
var results = [[String: SourceKitRepresentable]]()

func parse(_ dictionary: [String: SourceKitRepresentable]) {
guard let offset = dictionary.offset,
let byteRange = dictionary.length.map({ NSRange(location: offset, length: $0) }),
NSLocationInRange(byteOffset, byteRange) else {
return
}

results.append(dictionary)
dictionary.substructure.forEach(parse)
}
parse(dictionary)
return results
}
}

0 comments on commit eda9efe

Please sign in to comment.