Skip to content

Commit

Permalink
Fixes MissingDocRuleConfiguration (realm#3713)
Browse files Browse the repository at this point in the history
* add configuration for missing_docs

* fix MissingDocsRuleConfiguration

* add to changelog

* fix up Config default values and update tests

* use XCTAssertTrue and XCTAssertFalse

* fix line length violation

* finish up unit tests

* rever Package.resolved
  • Loading branch information
bdfox325 authored Sep 13, 2021
1 parent db229aa commit 00799cc
Show file tree
Hide file tree
Showing 8 changed files with 170 additions and 27 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

#### Bug Fixes

* None.
* Fixes a bug with the `missing_docs` rule where `excludes_inherited_types` would not be set.

## 0.44.0: Travel Size Lint Roller

Expand Down
2 changes: 1 addition & 1 deletion Source/SwiftLintFramework/Models/PrimaryRuleList.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Generated using Sourcery 1.2.1 — https://github.com/krzysztofzablocki/Sourcery
// Generated using Sourcery 1.5.0 — https://github.com/krzysztofzablocki/Sourcery
// DO NOT EDIT
/// The rule list containing all available rules built into SwiftLint.
public let primaryRuleList = RuleList(rules: [
Expand Down
12 changes: 4 additions & 8 deletions Source/SwiftLintFramework/Rules/Lint/MissingDocsRule.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,9 @@ private extension SwiftLintFile {
}
}

public struct MissingDocsRule: OptInRule, ConfigurationProviderRule, AutomaticTestableRule {
public struct MissingDocsRule: OptInRule, ConfigurationProviderRule {
public init() {
configuration = MissingDocsRuleConfiguration(
parameters: [RuleParameter<AccessControlLevel>(severity: .warning, value: .open),
RuleParameter<AccessControlLevel>(severity: .warning, value: .public)],
excludesExtensions: true,
excludesInheritedTypes: true)
configuration = MissingDocsRuleConfiguration()
}

public typealias ConfigurationType = MissingDocsRuleConfiguration
Expand All @@ -61,13 +57,13 @@ public struct MissingDocsRule: OptInRule, ConfigurationProviderRule, AutomaticTe
/// docs
public func b() {}
}
/// docs
// no docs
public class B: A { override public func b() {} }
"""),
// externally-defined superclass member is documented, but subclass member is not
Example("""
import Foundation
/// docs
// no docs
public class B: NSObject {
// no docs
override public var description: String { fatalError() } }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
public struct MissingDocsRuleConfiguration: RuleConfiguration, Equatable {
private(set) var parameters = [RuleParameter<AccessControlLevel>]()
private(set) var parameters = [
RuleParameter<AccessControlLevel>(severity: .warning, value: .open),
RuleParameter<AccessControlLevel>(severity: .warning, value: .public)
]
private(set) var excludesExtensions = true
private(set) var excludesInheritedTypes = true

Expand Down Expand Up @@ -34,14 +37,14 @@ public struct MissingDocsRuleConfiguration: RuleConfiguration, Equatable {
}

if let shouldExcludeInheritedTypes = dict["excludes_inherited_types"] as? Bool {
excludesExtensions = shouldExcludeInheritedTypes
excludesInheritedTypes = shouldExcludeInheritedTypes
}

var parameters: [RuleParameter<AccessControlLevel>] = []

for (key, value) in dict {
guard let severity = ViolationSeverity(rawValue: key) else {
throw ConfigurationError.unknownConfiguration
continue
}

if let array = [String].array(of: value) {
Expand All @@ -65,6 +68,8 @@ public struct MissingDocsRuleConfiguration: RuleConfiguration, Equatable {
throw ConfigurationError.unknownConfiguration
}

self.parameters = parameters
if parameters.isNotEmpty {
self.parameters = parameters
}
}
}
15 changes: 12 additions & 3 deletions Tests/LinuxMain.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Generated using Sourcery 1.2.1 — https://github.com/krzysztofzablocki/Sourcery
// Generated using Sourcery 1.5.0 — https://github.com/krzysztofzablocki/Sourcery
// DO NOT EDIT
@testable import SwiftLintFrameworkTests
import XCTest
Expand Down Expand Up @@ -979,6 +979,9 @@ extension LowerACLThanParentRuleTests {
extension MissingDocsRuleConfigurationTests {
static var allTests: [(String, (MissingDocsRuleConfigurationTests) -> () throws -> Void)] = [
("testDescriptionEmpty", testDescriptionEmpty),
("testDescriptionExcludesFalse", testDescriptionExcludesFalse),
("testDescriptionExcludesExtensionsFalseExcludesInheritedTypesTrue", testDescriptionExcludesExtensionsFalseExcludesInheritedTypesTrue),
("testDescriptionExcludesExtensionsTrueExcludesInheritedTypesFalse", testDescriptionExcludesExtensionsTrueExcludesInheritedTypesFalse),
("testDescriptionSingleServety", testDescriptionSingleServety),
("testDescriptionMultipleSeverities", testDescriptionMultipleSeverities),
("testDescriptionMultipleAcls", testDescriptionMultipleAcls),
Expand All @@ -987,13 +990,19 @@ extension MissingDocsRuleConfigurationTests {
("testParsingMultipleAcls", testParsingMultipleAcls),
("testInvalidServety", testInvalidServety),
("testInvalidAcl", testInvalidAcl),
("testInvalidDuplicateAcl", testInvalidDuplicateAcl)
("testInvalidDuplicateAcl", testInvalidDuplicateAcl),
("testExcludesFalse", testExcludesFalse),
("testExcludesExtensionsFalseExcludesInheritedTypesTrue", testExcludesExtensionsFalseExcludesInheritedTypesTrue),
("testExcludesExtensionsTrueExcludesInheritedTypesFalse", testExcludesExtensionsTrueExcludesInheritedTypesFalse),
("testExcludesExtensionsTrueExcludesInheritedTypesFalseWithParameters", testExcludesExtensionsTrueExcludesInheritedTypesFalseWithParameters)
]
}

extension MissingDocsRuleTests {
static var allTests: [(String, (MissingDocsRuleTests) -> () throws -> Void)] = [
("testWithDefaultConfiguration", testWithDefaultConfiguration)
("testWithDefaultConfiguration", testWithDefaultConfiguration),
("testWithExcludesExtensionsDisabled", testWithExcludesExtensionsDisabled),
("testWithExcludesInheritedTypesDisabled", testWithExcludesInheritedTypesDisabled)
]
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Generated using Sourcery 1.2.1 — https://github.com/krzysztofzablocki/Sourcery
// Generated using Sourcery 1.5.0 — https://github.com/krzysztofzablocki/Sourcery
// DO NOT EDIT
import SwiftLintFramework
import XCTest
Expand Down Expand Up @@ -419,12 +419,6 @@ class LowerACLThanParentRuleTests: XCTestCase {
}
}

class MissingDocsRuleTests: XCTestCase {
func testWithDefaultConfiguration() {
verifyRule(MissingDocsRule.description)
}
}

class MultilineArgumentsBracketsRuleTests: XCTestCase {
func testWithDefaultConfiguration() {
verifyRule(MultilineArgumentsBracketsRule.description)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,31 @@ class MissingDocsRuleConfigurationTests: XCTestCase {
let configuration = MissingDocsRuleConfiguration()
XCTAssertEqual(
configuration.consoleDescription,
"excludes_extensions: true, excludes_inherited_types: true"
"warning: open, public, excludes_extensions: true, excludes_inherited_types: true"
)
}

func testDescriptionExcludesFalse() {
let configuration = MissingDocsRuleConfiguration(excludesExtensions: false, excludesInheritedTypes: false)
XCTAssertEqual(
configuration.consoleDescription,
"excludes_extensions: false, excludes_inherited_types: false"
"warning: open, public, excludes_extensions: false, excludes_inherited_types: false"
)
}

func testDescriptionExcludesExtensionsFalseExcludesInheritedTypesTrue() {
let configuration = MissingDocsRuleConfiguration(excludesExtensions: false, excludesInheritedTypes: true)
XCTAssertEqual(
configuration.consoleDescription,
"warning: open, public, excludes_extensions: false, excludes_inherited_types: true"
)
}

func testDescriptionExcludesExtensionsTrueExcludesInheritedTypesFalse() {
let configuration = MissingDocsRuleConfiguration(excludesExtensions: true, excludesInheritedTypes: false)
XCTAssertEqual(
configuration.consoleDescription,
"warning: open, public, excludes_extensions: true, excludes_inherited_types: false"
)
}

Expand Down Expand Up @@ -74,6 +90,8 @@ class MissingDocsRuleConfigurationTests: XCTestCase {
[RuleParameter<AccessControlLevel>(severity: .warning, value: .public),
RuleParameter<AccessControlLevel>(severity: .warning, value: .open)]
)
XCTAssertTrue(configuration.excludesExtensions)
XCTAssertTrue(configuration.excludesInheritedTypes)
}

func testInvalidServety() {
Expand All @@ -83,11 +101,72 @@ class MissingDocsRuleConfigurationTests: XCTestCase {

func testInvalidAcl() {
var configuration = MissingDocsRuleConfiguration()
XCTAssertThrowsError(try configuration.apply(configuration: ["debug": ["public", "open"]]))
try? configuration.apply(configuration: ["debug": ["public", "open"]])
XCTAssertTrue(configuration.excludesExtensions)
XCTAssertTrue(configuration.excludesInheritedTypes)
XCTAssertEqual(
configuration.parameters.sorted { $0.value.rawValue > $1.value.rawValue },
[RuleParameter<AccessControlLevel>(severity: .warning, value: .public),
RuleParameter<AccessControlLevel>(severity: .warning, value: .open)]
)
}

func testInvalidDuplicateAcl() {
var configuration = MissingDocsRuleConfiguration()
XCTAssertThrowsError(try configuration.apply(configuration: ["warning": ["public", "open"], "error": "public"]))
}

func testExcludesFalse() {
var configuration = MissingDocsRuleConfiguration()
try? configuration.apply(configuration: ["excludes_extensions": false, "excludes_inherited_types": false])
XCTAssertFalse(configuration.excludesExtensions)
XCTAssertFalse(configuration.excludesInheritedTypes)
XCTAssertEqual(
configuration.parameters.sorted { $0.value.rawValue > $1.value.rawValue },
[RuleParameter<AccessControlLevel>(severity: .warning, value: .public),
RuleParameter<AccessControlLevel>(severity: .warning, value: .open)]
)
}

func testExcludesExtensionsFalseExcludesInheritedTypesTrue() {
var configuration = MissingDocsRuleConfiguration()
try? configuration.apply(configuration: ["excludes_extensions": false, "excludes_inherited_types": true])
XCTAssertFalse(configuration.excludesExtensions)
XCTAssertTrue(configuration.excludesInheritedTypes)
XCTAssertEqual(
configuration.parameters.sorted { $0.value.rawValue > $1.value.rawValue },
[RuleParameter<AccessControlLevel>(severity: .warning, value: .public),
RuleParameter<AccessControlLevel>(severity: .warning, value: .open)]
)
}

func testExcludesExtensionsTrueExcludesInheritedTypesFalse() {
var configuration = MissingDocsRuleConfiguration()
try? configuration.apply(configuration: ["excludes_extensions": true, "excludes_inherited_types": false])
XCTAssertTrue(configuration.excludesExtensions)
XCTAssertFalse(configuration.excludesInheritedTypes)
XCTAssertEqual(
configuration.parameters.sorted { $0.value.rawValue > $1.value.rawValue },
[RuleParameter<AccessControlLevel>(severity: .warning, value: .public),
RuleParameter<AccessControlLevel>(severity: .warning, value: .open)]
)
}

func testExcludesExtensionsTrueExcludesInheritedTypesFalseWithParameters() {
var configuration = MissingDocsRuleConfiguration()
try? configuration.apply(
configuration: [
"excludes_extensions": true,
"excludes_inherited_types": false,
"error": ["public"]
]
)

XCTAssertTrue(configuration.excludesExtensions)
XCTAssertFalse(configuration.excludesInheritedTypes)
XCTAssertEqual(
configuration.parameters.sorted { $0.value.rawValue > $1.value.rawValue },
[RuleParameter<AccessControlLevel>(severity: .error, value: .public)]
)
}
}
60 changes: 60 additions & 0 deletions Tests/SwiftLintFrameworkTests/MissingDocsRuleTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import SwiftLintFramework
import XCTest

class MissingDocsRuleTests: XCTestCase {
func testWithDefaultConfiguration() {
verifyRule(MissingDocsRule.description)
}

func testWithExcludesExtensionsDisabled() {
// Perform additional tests with the ignores_comments settings disabled.
let baseDescription = MissingDocsRule.description
let triggeringComments = [
Example("""
public extension A {}
"""
)
]
let nonTriggeringExamples = baseDescription.nonTriggeringExamples
.filter { !triggeringComments.contains($0) }
let triggeringExamples = baseDescription.triggeringExamples + triggeringComments
let description = baseDescription
.with(nonTriggeringExamples: nonTriggeringExamples)
.with(triggeringExamples: triggeringExamples)
verifyRule(description,
ruleConfiguration: ["excludes_extensions": false])
}

func testWithExcludesInheritedTypesDisabled() {
// Perform additional tests with the ignores_comments settings disabled.
let baseDescription = MissingDocsRule.description
let triggeringComments = [
// locally-defined superclass member is documented, but subclass member is not
Example("""
/// docs
public class A {
/// docs
public func b() {}
}
// no docs
public class B: A { override public func b() {} }
"""),
// externally-defined superclass member is documented, but subclass member is not
Example("""
import Foundation
// no docs
public class B: NSObject {
// no docs
override public var description: String { fatalError() } }
""")
]
let nonTriggeringExamples = baseDescription.nonTriggeringExamples
.filter { !triggeringComments.contains($0) }
let triggeringExamples = baseDescription.triggeringExamples + triggeringComments
let description = baseDescription
.with(nonTriggeringExamples: nonTriggeringExamples)
.with(triggeringExamples: triggeringExamples)
verifyRule(description,
ruleConfiguration: ["excludes_inherited_types": false])
}
}

0 comments on commit 00799cc

Please sign in to comment.