Skip to content

Commit

Permalink
Add XCTestCase
Browse files Browse the repository at this point in the history
  • Loading branch information
ornithocoder committed Aug 16, 2017
1 parent 8d478f7 commit 457aea0
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 63 deletions.
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
[Ryan Booker](https://github.com/ryanbooker)
[#1761](https://github.com/realm/SwiftLint/issues/1761)

* Add `quick_single_spec` opt-in rule to enforce test files
to contain a single QuickSpec classes.
* Add `single_test_class` opt-in rule to enforce test files
to contain a single QuickSpec or XCTestCase class.
[Ornithologist Coder](https://github.com/ornithocoder)
[#1779](https://github.com/realm/SwiftLint/issues/1779)

Expand Down
114 changes: 69 additions & 45 deletions Rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,14 @@
* [Private Unit Test](#private-unit-test)
* [Prohibited calls to super](#prohibited-calls-to-super)
* [Protocol Property Accessors Order](#protocol-property-accessors-order)
* [Quick Single Spec](#quick-single-spec)
* [Redundant Discardable Let](#redundant-discardable-let)
* [Redundant Nil Coalescing](#redundant-nil-coalescing)
* [Redundant Optional Initialization](#redundant-optional-initialization)
* [Redundant String Enum Value](#redundant-string-enum-value)
* [Redundant Void Return](#redundant-void-return)
* [Returning Whitespace](#returning-whitespace)
* [Shorthand Operator](#shorthand-operator)
* [Single Test Class](#single-test-class)
* [Sorted Imports](#sorted-imports)
* [Statement Position](#statement-position)
* [Strict fileprivate](#strict-fileprivate)
Expand Down Expand Up @@ -7907,50 +7907,6 @@ protocol Foo {



## Quick Single Spec

Identifier | Enabled by default | Supports autocorrection | Kind
--- | --- | --- | ---
`quick_single_spec` | Disabled | No | style

Test files should contain a single QuickSpec class.

### Examples

<details>
<summary>Non Triggering Examples</summary>

```swift
class FooTests { }

```

```swift
class FooTests: QuickSpec { }

```

</details>
<details>
<summary>Triggering Examples</summary>

```swift
class FooTests: QuickSpec { }
class BarTests: QuickSpec { }

```

```swift
class FooTests: QuickSpec { }
class BarTests: QuickSpec { }
class TotoTests: QuickSpec { }

```

</details>



## Redundant Discardable Let

Identifier | Enabled by default | Supports autocorrection | Kind
Expand Down Expand Up @@ -8683,6 +8639,74 @@ n = n - i / outputLength



## Single Test Class

Identifier | Enabled by default | Supports autocorrection | Kind
--- | --- | --- | ---
`single_test_class` | Disabled | No | style

Test files should contain a single QuickSpec or XCTestCase class.

### Examples

<details>
<summary>Non Triggering Examples</summary>

```swift
class FooTests { }

```

```swift
class FooTests: QuickSpec { }

```

```swift
class FooTests: XCTestCase { }

```

</details>
<details>
<summary>Triggering Examples</summary>

```swift
class FooTests: QuickSpec { }
class BarTests: QuickSpec { }

```

```swift
class FooTests: QuickSpec { }
class BarTests: QuickSpec { }
class TotoTests: QuickSpec { }

```

```swift
class FooTests: XCTestCase { }
class BarTests: XCTestCase { }

```

```swift
class FooTests: XCTestCase { }
class BarTests: XCTestCase { }
class TotoTests: XCTestCase { }

```

```swift
class FooTests: QuickSpec { }
class BarTests: XCTestCase { }

```

</details>



## Sorted Imports

Identifier | Enabled by default | Supports autocorrection | Kind
Expand Down
2 changes: 1 addition & 1 deletion Source/SwiftLintFramework/Models/MasterRuleList.swift
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public let masterRuleList = RuleList(rules: [
PrivateUnitTestRule.self,
ProhibitedSuperRule.self,
ProtocolPropertyAccessorsOrderRule.self,
QuickSingleSpecRule.self,
SingleTestClassRule.self,
RedundantDiscardableLetRule.self,
RedundantNilCoalescingRule.self,
RedundantOptionalInitializationRule.self,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,27 @@
import Foundation
import SourceKittenFramework

public struct QuickSingleSpecRule: Rule, OptInRule, ConfigurationProviderRule {
public struct SingleTestClassRule: Rule, OptInRule, ConfigurationProviderRule {
public var configuration = SeverityConfiguration(.warning)

public init() {}

public static let description = RuleDescription(
identifier: "quick_single_spec",
name: "Quick Single Spec",
description: "Test files should contain a single QuickSpec class.",
identifier: "single_test_class",
name: "Single Test Class",
description: "Test files should contain a single QuickSpec or XCTestCase class.",
kind: .style,
nonTriggeringExamples: [
"class FooTests { }\n",
"class FooTests: QuickSpec { }\n"
"class FooTests: QuickSpec { }\n",
"class FooTests: XCTestCase { }\n"
],
triggeringExamples: [
"↓class FooTests: QuickSpec { }\n↓class BarTests: QuickSpec { }\n",
"↓class FooTests: QuickSpec { }\n↓class BarTests: QuickSpec { }\n↓class TotoTests: QuickSpec { }\n"
"↓class FooTests: QuickSpec { }\n↓class BarTests: QuickSpec { }\n↓class TotoTests: QuickSpec { }\n",
"↓class FooTests: XCTestCase { }\n↓class BarTests: XCTestCase { }\n",
"↓class FooTests: XCTestCase { }\n↓class BarTests: XCTestCase { }\n↓class TotoTests: XCTestCase { }\n",
"↓class FooTests: QuickSpec { }\n↓class BarTests: XCTestCase { }\n"
]
)

Expand All @@ -40,7 +44,9 @@ public struct QuickSingleSpecRule: Rule, OptInRule, ConfigurationProviderRule {
// MARK: - Private

private func quickSpecs(in file: File) -> [[String: SourceKitRepresentable]] {
return file.structure.dictionary.substructure.filter { $0.inheritedTypes.contains("QuickSpec") }
return file.structure.dictionary.substructure.filter {
$0.inheritedTypes.filter { !testClasses().contains($0) }.isEmpty
}
}

private func toViolation(in file: File,
Expand All @@ -51,7 +57,11 @@ public struct QuickSingleSpecRule: Rule, OptInRule, ConfigurationProviderRule {
return StyleViolation(ruleDescription: type(of: self).description,
severity: configuration.severity,
location: Location(file: file, byteOffset: offset),
reason: "\(numberOfSpecs) Quick Specs found in this file.")
reason: "\(numberOfSpecs) test classes found in this file.")
}
}

private func testClasses() -> [String] {
return ["QuickSpec", "XCTestCase"]
}
}
8 changes: 4 additions & 4 deletions SwiftLint.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
6250D32A1ED4DFEB00735129 /* MultilineParametersRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6238AE411ED4D734006C3601 /* MultilineParametersRule.swift */; };
62622F6B1F2F2E3500D5D099 /* DiscouragedDirectInitRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62622F6A1F2F2E3500D5D099 /* DiscouragedDirectInitRule.swift */; };
626D02971F31CBCC0054788D /* XCTFailMessageRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 626D02961F31CBCC0054788D /* XCTFailMessageRule.swift */; };
629C60D91F43906700B4AF92 /* QuickSingleSpecRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 629C60D81F43906700B4AF92 /* QuickSingleSpecRule.swift */; };
629C60D91F43906700B4AF92 /* SingleTestClassRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 629C60D81F43906700B4AF92 /* SingleTestClassRule.swift */; };
62A498561F306A7700D766E4 /* DiscouragedDirectInitConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62A498551F306A7700D766E4 /* DiscouragedDirectInitConfiguration.swift */; };
62A6E7931F3317E3003A0479 /* JoinedDefaultRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62A6E7911F3317E3003A0479 /* JoinedDefaultRule.swift */; };
67932E2D1E54AF4B00CB0629 /* CyclomaticComplexityConfigurationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67932E2C1E54AF4B00CB0629 /* CyclomaticComplexityConfigurationTests.swift */; };
Expand Down Expand Up @@ -378,7 +378,7 @@
6238AE411ED4D734006C3601 /* MultilineParametersRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MultilineParametersRule.swift; sourceTree = "<group>"; };
62622F6A1F2F2E3500D5D099 /* DiscouragedDirectInitRule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiscouragedDirectInitRule.swift; sourceTree = "<group>"; };
626D02961F31CBCC0054788D /* XCTFailMessageRule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCTFailMessageRule.swift; sourceTree = "<group>"; };
629C60D81F43906700B4AF92 /* QuickSingleSpecRule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickSingleSpecRule.swift; sourceTree = "<group>"; };
629C60D81F43906700B4AF92 /* SingleTestClassRule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingleTestClassRule.swift; sourceTree = "<group>"; };
62A498551F306A7700D766E4 /* DiscouragedDirectInitConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiscouragedDirectInitConfiguration.swift; sourceTree = "<group>"; };
62A6E7911F3317E3003A0479 /* JoinedDefaultRule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JoinedDefaultRule.swift; sourceTree = "<group>"; };
62AF35D71F30B183009B11EE /* DiscouragedDirectInitRuleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiscouragedDirectInitRuleTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -998,7 +998,7 @@
B2902A0B1D66815600BFCCF7 /* PrivateUnitTestRule.swift */,
009E09271DFEE4C200B588A7 /* ProhibitedSuperRule.swift */,
D47F31141EC918B600E3E1CA /* ProtocolPropertyAccessorsOrderRule.swift */,
629C60D81F43906700B4AF92 /* QuickSingleSpecRule.swift */,
629C60D81F43906700B4AF92 /* SingleTestClassRule.swift */,
D4C889701E385B7B00BAE88D /* RedundantDiscardableLetRule.swift */,
24B4DF0B1D6DFA370097803B /* RedundantNilCoalescingRule.swift */,
D4B022951E0EF80C007E5297 /* RedundantOptionalInitializationRule.swift */,
Expand Down Expand Up @@ -1438,7 +1438,7 @@
D47A510E1DB29EEB00A4CC21 /* SwitchCaseOnNewlineRule.swift in Sources */,
D462021F1E15F52D0027AAD1 /* NumberSeparatorRuleExamples.swift in Sources */,
D4DA1DF41E17511D0037413D /* CompilerProtocolInitRule.swift in Sources */,
629C60D91F43906700B4AF92 /* QuickSingleSpecRule.swift in Sources */,
629C60D91F43906700B4AF92 /* SingleTestClassRule.swift in Sources */,
621061BF1ED57E640082D51E /* MultilineParametersRuleExamples.swift in Sources */,
D48AE2CC1DFB58C5001C6A4A /* AttributesRulesExamples.swift in Sources */,
E88DEA6F1B09843F00A66CB0 /* Location.swift in Sources */,
Expand Down
2 changes: 1 addition & 1 deletion Tests/LinuxMain.swift
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ extension RulesTests {
("testPrivateUnitTest", testPrivateUnitTest),
("testProhibitedSuper", testProhibitedSuper),
("testProtocolPropertyAccessorsOrder", testProtocolPropertyAccessorsOrder),
("testQuickSingleSpec", testQuickSingleSpec),
("testSingleTestClass", testSingleTestClass),
("testRedundantDiscardableLet", testRedundantDiscardableLet),
("testRedundantNilCoalescing", testRedundantNilCoalescing),
("testRedundantOptionalInitialization", testRedundantOptionalInitialization),
Expand Down
4 changes: 2 additions & 2 deletions Tests/SwiftLintFrameworkTests/RulesTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -237,8 +237,8 @@ class RulesTests: XCTestCase {
verifyRule(ProtocolPropertyAccessorsOrderRule.description)
}

func testQuickSingleSpec() {
verifyRule(QuickSingleSpecRule.description)
func testSingleTestClass() {
verifyRule(SingleTestClassRule.description)
}

func testRedundantDiscardableLet() {
Expand Down

0 comments on commit 457aea0

Please sign in to comment.